aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475>2020-06-12 20:41:49 +0000
committercutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475>2020-06-12 20:41:49 +0000
commit20b3d56987ca7b7a9d7f27b0a32a93f12e8dc530 (patch)
tree5fd7cc45a44c46b1134788ed90ffb70398179f4d
parent084e0e669a8d9c6a373ff3bcb410febca4d4a48a (diff)
downloadirrlicht-20b3d56987ca7b7a9d7f27b0a32a93f12e8dc530.tar.xz
Merging r6075 through r6106 from trunk to ogl-es branch.
Burnings renderer changes. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6116 dfc29bdd-3216-0410-991c-e03cc46cb475
-rw-r--r--changes.txt12
-rw-r--r--examples/05.UserInterface/main.cpp2
-rw-r--r--examples/09.Meshviewer/main.cpp2
-rw-r--r--examples/10.Shaders/main.cpp2
-rw-r--r--examples/11.PerPixelLighting/main.cpp10
-rw-r--r--examples/12.TerrainRendering/main.cpp3
-rw-r--r--examples/16.Quake3MapShader/main.cpp8
-rwxr-xr-xexamples/22.MaterialViewer/main.cpp2
-rw-r--r--examples/23.SMeshHandling/main.cpp4
-rw-r--r--examples/25.XmlHandling/main.cpp4
-rw-r--r--examples/Demo/CDemo.cpp7
-rw-r--r--examples/Demo/CMainMenu.cpp8
-rwxr-xr-xsource/Irrlicht/Android/jni/Android.mk3
-rw-r--r--source/Irrlicht/CAnimatedMeshSceneNode.cpp4
-rw-r--r--source/Irrlicht/CBlit.h455
-rw-r--r--source/Irrlicht/CBurningShader_Raster_Reference.cpp72
-rw-r--r--source/Irrlicht/CDepthBuffer.cpp62
-rw-r--r--source/Irrlicht/CDepthBuffer.h8
-rw-r--r--source/Irrlicht/CGUIContextMenu.cpp1
-rw-r--r--source/Irrlicht/CImage.cpp23
-rw-r--r--source/Irrlicht/CImageLoaderRGB.cpp2
-rw-r--r--source/Irrlicht/CMY3DMeshFileLoader.h4
-rw-r--r--source/Irrlicht/COBJMeshFileLoader.cpp2
-rw-r--r--source/Irrlicht/COSOperator.cpp3
-rw-r--r--source/Irrlicht/CSoftware2MaterialRenderer.h42
-rw-r--r--source/Irrlicht/CSoftwareDriver2.cpp3866
-rw-r--r--source/Irrlicht/CSoftwareDriver2.h198
-rw-r--r--source/Irrlicht/CSoftwareTexture2.cpp610
-rw-r--r--source/Irrlicht/CSoftwareTexture2.h67
-rw-r--r--source/Irrlicht/CTRGouraud2.cpp61
-rw-r--r--source/Irrlicht/CTRGouraudAlpha2.cpp47
-rw-r--r--source/Irrlicht/CTRGouraudAlphaNoZ2.cpp49
-rw-r--r--source/Irrlicht/CTRGouraudNoZ2.cpp641
-rw-r--r--source/Irrlicht/CTRNormalMap.cpp271
-rw-r--r--source/Irrlicht/CTRStencilShadow.cpp316
-rw-r--r--source/Irrlicht/CTRTextureBlend.cpp635
-rw-r--r--source/Irrlicht/CTRTextureDetailMap2.cpp50
-rw-r--r--source/Irrlicht/CTRTextureGouraud2.cpp337
-rw-r--r--source/Irrlicht/CTRTextureGouraudAdd2.cpp60
-rw-r--r--source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp167
-rw-r--r--source/Irrlicht/CTRTextureGouraudAlpha.cpp107
-rw-r--r--source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp648
-rw-r--r--source/Irrlicht/CTRTextureGouraudNoZ2.cpp42
-rw-r--r--source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp199
-rw-r--r--source/Irrlicht/CTRTextureLightMap2_Add.cpp45
-rw-r--r--source/Irrlicht/CTRTextureLightMap2_M1.cpp33
-rw-r--r--source/Irrlicht/CTRTextureLightMap2_M2.cpp33
-rw-r--r--source/Irrlicht/CTRTextureLightMap2_M4.cpp113
-rw-r--r--source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp58
-rw-r--r--source/Irrlicht/CTRTextureWire2.cpp145
-rw-r--r--source/Irrlicht/CTR_transparent_reflection_2_layer.cpp729
-rw-r--r--source/Irrlicht/CXMeshFileLoader.cpp6
-rw-r--r--source/Irrlicht/IBurningShader.cpp410
-rw-r--r--source/Irrlicht/IBurningShader.h288
-rw-r--r--source/Irrlicht/IDepthBuffer.h16
-rw-r--r--source/Irrlicht/Irrlicht-gcc.cbp10
-rw-r--r--source/Irrlicht/Irrlicht10.0.vcxproj10
-rw-r--r--source/Irrlicht/Irrlicht10.0.vcxproj.filters30
-rw-r--r--source/Irrlicht/Irrlicht11.0.vcxproj10
-rw-r--r--source/Irrlicht/Irrlicht11.0.vcxproj.filters30
-rw-r--r--source/Irrlicht/Irrlicht12.0.vcxproj2
-rw-r--r--source/Irrlicht/Irrlicht12.0.vcxproj.filters6
-rw-r--r--source/Irrlicht/Irrlicht14.0.vcxproj11
-rw-r--r--source/Irrlicht/Irrlicht14.0.vcxproj.filters33
-rw-r--r--source/Irrlicht/Irrlicht15.0.vcxproj10
-rw-r--r--source/Irrlicht/Irrlicht15.0.vcxproj.filters30
-rw-r--r--source/Irrlicht/Makefile8
-rw-r--r--source/Irrlicht/S4DVertex.h741
-rw-r--r--source/Irrlicht/SoftwareDriver2_compile_config.h219
-rw-r--r--source/Irrlicht/SoftwareDriver2_helper.h820
-rw-r--r--source/Irrlicht/burning_shader_color.cpp95
-rw-r--r--source/Irrlicht/burning_shader_color_fraq.h24
-rw-r--r--source/Irrlicht/burning_shader_compile_fragment_default.h164
-rw-r--r--source/Irrlicht/burning_shader_compile_fragment_end.h20
-rw-r--r--source/Irrlicht/burning_shader_compile_fragment_start.h119
-rw-r--r--source/Irrlicht/burning_shader_compile_start.h24
-rw-r--r--source/Irrlicht/burning_shader_compile_triangle.h368
-rw-r--r--source/Irrlicht/burning_shader_compile_verify.h43
-rw-r--r--tests/media/Burning's Video-2dmatFilter.pngbin8500 -> 25513 bytes
-rw-r--r--tests/media/Burning's Video-b3dAnimation.pngbin6245 -> 5879 bytes
-rw-r--r--tests/media/Burning's Video-b3dJointPosition.pngbin2964 -> 2982 bytes
-rw-r--r--tests/media/Burning's Video-billboard.pngbin3998 -> 4577 bytes
-rw-r--r--tests/media/Burning's Video-billboardOrientation.pngbin10704 -> 10488 bytes
-rw-r--r--tests/media/Burning's Video-draw2DImage4cFilter.pngbin20835 -> 37162 bytes
-rw-r--r--tests/media/Burning's Video-drawPixel.pngbin27977 -> 27905 bytes
-rw-r--r--tests/media/Burning's Video-drawVPL_e.pngbin16353 -> 16056 bytes
-rw-r--r--tests/media/Burning's Video-drawVPL_g.pngbin13937 -> 14337 bytes
-rw-r--r--tests/media/Burning's Video-drawVPL_h.pngbin13644 -> 13300 bytes
-rw-r--r--tests/media/Burning's Video-drawVPL_i.pngbin12838 -> 13181 bytes
-rw-r--r--tests/media/Burning's Video-flyCircleAnimator.pngbin2137 -> 2567 bytes
-rw-r--r--tests/media/Burning's Video-lightType.pngbin1573 -> 5471 bytes
-rw-r--r--tests/media/Burning's Video-loadScene.pngbin29530 -> 24949 bytes
-rw-r--r--tests/media/Burning's Video-md2Normals.pngbin6405 -> 6457 bytes
-rw-r--r--tests/media/Burning's Video-multiTexture.pngbin359 -> 8117 bytes
-rw-r--r--tests/media/Burning's Video-orthoCam.pngbin3045 -> 4468 bytes
-rw-r--r--tests/media/Burning's Video-planeMatrix-scaledClip.pngbin37744 -> 37083 bytes
-rw-r--r--tests/media/Burning's Video-renderMipmap.pngbin812 -> 740 bytes
-rw-r--r--tests/media/Burning's Video-stencilSelfShadow.pngbin16396 -> 14841 bytes
-rw-r--r--tests/media/Burning's Video-stencilShadow.pngbin3275 -> 3508 bytes
-rw-r--r--tests/media/Burning's Video-terrainGap.pngbin2971 -> 4337 bytes
-rw-r--r--tests/media/Burning's Video-terrainSceneNode-1.pngbin31249 -> 34251 bytes
-rw-r--r--tests/media/Burning's Video-terrainSceneNode-2.pngbin33309 -> 36646 bytes
-rw-r--r--tests/media/Burning's Video-testGeometryCreator.pngbin7580 -> 7406 bytes
-rw-r--r--tests/media/Burning's Video-testTerrainMesh.pngbin30612 -> 29522 bytes
-rw-r--r--tests/media/Burning's Video-textureMatrix.pngbin0 -> 15212 bytes
-rw-r--r--tests/media/Burning's Video-textureMatrix2.pngbin0 -> 15212 bytes
-rw-r--r--tests/media/Burning's Video-textureMatrixInMixedScenes.pngbin0 -> 1187 bytes
-rw-r--r--tests/media/Burning's Video-textureRenderStates.pngbin30383 -> 27349 bytes
-rw-r--r--tests/media/Burning's Video-transparentAddColor.pngbin30309 -> 29747 bytes
-rw-r--r--tests/media/Burning's Video-transparentAlphaChannel.pngbin29521 -> 29346 bytes
-rw-r--r--tests/media/Burning's Video-transparentAlphaChannelRef.pngbin30112 -> 30009 bytes
-rw-r--r--tests/media/Burning's Video-transparentReflection2Layer.pngbin21621 -> 32288 bytes
-rw-r--r--tests/media/Burning's Video-transparentVertexAlpha.pngbin24479 -> 29855 bytes
-rw-r--r--tests/media/Burning's Video-transparentVertexAlphaChannelMore.pngbin3539 -> 4719 bytes
-rw-r--r--tests/media/Burning's Video-viewPortText.pngbin6477 -> 8955 bytes
-rw-r--r--tests/media/Burning's Video-writeImageToFile.pngbin0 -> 27905 bytes
-rw-r--r--tests/tests-last-passed-at.txt4
117 files changed, 10195 insertions, 3628 deletions
diff --git a/changes.txt b/changes.txt
index fd1732b..c213dfc 100644
--- a/changes.txt
+++ b/changes.txt
@@ -9,6 +9,18 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
--------------------------
Changes in 1.9 (not yet released)
+- BurningVideo: 0.51
+ - 10 year anniversary update
+ - Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map]
+ - increased internal s4DVertex to support 4 Textures and 4 Colors [switchable]
+ - Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption
+ - 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D
+ - Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE]
+ - NormalMap for 1 Light accurate. still all lights are accumulated
+ - SuperTuxKart 8.0.1 playable
+ - Known Problems
+ - Depthbuffer range not equal to Hardware Drivers. Problems with Orthographic Stencil Shadows
+ - Triangle MipMap Selection. Wrong for TextureAtlas and Billboards
- Fix CPLYMeshFileLoader checking for wrong vertex count when switching between 16/32 bit. Thanks @randomMesh for reporting.
- Fix bug that AnimatedMeshSceneNode ignored ReadOnlyMaterials flag when checking materials for transparent render passes.
- Unify checks if materials should use transparent render pass with new IVideoDriver::needsTransparentRenderPass function.
diff --git a/examples/05.UserInterface/main.cpp b/examples/05.UserInterface/main.cpp
index 501eed3..deaba6f 100644
--- a/examples/05.UserInterface/main.cpp
+++ b/examples/05.UserInterface/main.cpp
@@ -266,7 +266,7 @@ int main()
/*
And at last, we create a nice Irrlicht Engine logo in the top left corner.
*/
- env->addImage(driver->getTexture(mediaPath + "irrlichtlogo2.png"),
+ env->addImage(driver->getTexture(mediaPath + "irrlichtlogo3.png"),
position2d<int>(10,10));
diff --git a/examples/09.Meshviewer/main.cpp b/examples/09.Meshviewer/main.cpp
index 010ad6e..1a5f51a 100644
--- a/examples/09.Meshviewer/main.cpp
+++ b/examples/09.Meshviewer/main.cpp
@@ -978,7 +978,7 @@ int main(int argc, char* argv[])
// load the irrlicht engine logo
IGUIImage *img =
- env->addImage(driver->getTexture("irrlichtlogo2.png"),
+ env->addImage(driver->getTexture("irrlichtlogo3.png"),
core::position2d<s32>(10, driver->getScreenSize().Height - 128));
// lock the logo's edges to the bottom left corner of the screen
diff --git a/examples/10.Shaders/main.cpp b/examples/10.Shaders/main.cpp
index 1beb3de..ff80bd5 100644
--- a/examples/10.Shaders/main.cpp
+++ b/examples/10.Shaders/main.cpp
@@ -236,6 +236,8 @@ int main()
vsFileName = mediaPath + "opengl.vsh";
}
break;
+ default:
+ break;
}
/*
diff --git a/examples/11.PerPixelLighting/main.cpp b/examples/11.PerPixelLighting/main.cpp
index c2e03af..afa59cb 100644
--- a/examples/11.PerPixelLighting/main.cpp
+++ b/examples/11.PerPixelLighting/main.cpp
@@ -285,9 +285,9 @@ int main()
driver->getTexture(mediaPath + "rockwall.jpg"));
room->setMaterialTexture(1, normalMap);
- // Stones don't glitter..
- room->getMaterial(0).SpecularColor.set(0,0,0,0);
- room->getMaterial(0).Shininess = 0.f;
+ // Stones don't glitter.. (but specular highlight for EMT_SOLID)
+ //room->getMaterial(0).SpecularColor.set(0,0,0,0);
+ //room->getMaterial(0).Shininess = 0.f;
room->setMaterialFlag(video::EMF_FOG_ENABLE, true);
room->setMaterialType(video::EMT_PARALLAX_MAP_SOLID);
@@ -365,7 +365,7 @@ int main()
// add light 1 (more green)
scene::ILightSceneNode* light1 =
smgr->addLightSceneNode(0, core::vector3df(0,0,0),
- video::SColorf(0.5f, 1.0f, 0.5f, 0.0f), 800.0f);
+ video::SColorf(0.5f, 1.0f, 0.5f, 0.0f), 400.0f);
// add fly circle animator to light 1
scene::ISceneNodeAnimator* anim =
@@ -398,7 +398,7 @@ int main()
// add light 2 (red)
scene::ISceneNode* light2 =
smgr->addLightSceneNode(0, core::vector3df(0,0,0),
- video::SColorf(1.0f, 0.2f, 0.2f, 0.0f), 800.0f);
+ video::SColorf(1.0f, 0.2f, 0.2f, 0.0f), 400.0f);
// add fly circle animator to light 2
anim = smgr->createFlyCircleAnimator(core::vector3df(0,150,0), 200.0f,
diff --git a/examples/12.TerrainRendering/main.cpp b/examples/12.TerrainRendering/main.cpp
index 7c38598..f9bc97e 100644
--- a/examples/12.TerrainRendering/main.cpp
+++ b/examples/12.TerrainRendering/main.cpp
@@ -120,7 +120,7 @@ int main()
const io::path mediaPath = getExampleMediaPath();
// add irrlicht logo
- env->addImage(driver->getTexture(mediaPath + "irrlichtlogo2.png"),
+ env->addImage(driver->getTexture(mediaPath + "irrlichtlogo3.png"),
core::position2d<s32>(10,10));
//set other font
@@ -213,6 +213,7 @@ int main()
terrain->getMeshBufferForLOD(*buffer, 0);
video::S3DVertex2TCoords* data = (video::S3DVertex2TCoords*)buffer->getVertexBuffer().getData();
// Work on data or get the IndexBuffer with a similar call.
+ (void)data; // disable unused variable warnings
buffer->drop(); // When done drop the buffer again.
/*
diff --git a/examples/16.Quake3MapShader/main.cpp b/examples/16.Quake3MapShader/main.cpp
index e8a318d..38062c5 100644
--- a/examples/16.Quake3MapShader/main.cpp
+++ b/examples/16.Quake3MapShader/main.cpp
@@ -318,7 +318,7 @@ int IRRCALLCONV main(int argc, char* argv[])
device->getCursorControl()->setVisible(false);
// load the engine logo
- gui->addImage(driver->getTexture("irrlichtlogo2.png"),
+ gui->addImage(driver->getTexture("irrlichtlogo3.png"),
core::position2d<s32>(10, 10));
// show the driver logo
@@ -335,6 +335,8 @@ int IRRCALLCONV main(int argc, char* argv[])
case video::EDT_DIRECT3D9:
gui->addImage(driver->getTexture("directxlogo.png"), pos);
break;
+ default:
+ break;
}
/*
@@ -355,14 +357,14 @@ int IRRCALLCONV main(int argc, char* argv[])
driver->endScene();
int fps = driver->getFPS();
- //if (lastFPS != fps)
+ if (1 || lastFPS != fps)
{
- io::IAttributes * const attr = smgr->getParameters();
core::stringw str = L"Q3 [";
str += driver->getName();
str += "] FPS:";
str += fps;
#ifdef _IRR_SCENEMANAGER_DEBUG
+ io::IAttributes * const attr = smgr->getParameters();
str += " Cull:";
str += attr->getAttributeAsInt("calls");
str += "/";
diff --git a/examples/22.MaterialViewer/main.cpp b/examples/22.MaterialViewer/main.cpp
index 8330926..358ce02 100755
--- a/examples/22.MaterialViewer/main.cpp
+++ b/examples/22.MaterialViewer/main.cpp
@@ -429,7 +429,7 @@ void CMaterialControl::init(scene::IMeshSceneNode* node, IrrlichtDevice * device
Driver = device->getVideoDriver ();
gui::IGUIEnvironment* guiEnv = device->getGUIEnvironment();
- scene::ISceneManager* smgr = device->getSceneManager();
+ //scene::ISceneManager* smgr = device->getSceneManager();
const video::SMaterial & material = node->getMaterial(0);
s32 top = pos.Y;
diff --git a/examples/23.SMeshHandling/main.cpp b/examples/23.SMeshHandling/main.cpp
index 2d41309..a4ef9eb 100644
--- a/examples/23.SMeshHandling/main.cpp
+++ b/examples/23.SMeshHandling/main.cpp
@@ -57,7 +57,7 @@ typedef f32 generate_func(s16 x, s16 y, f32 s);
f32 eggbox(s16 x, s16 y, f32 s)
{
const f32 r = 4.f*sqrtf((f32)(x*x + y*y))/s;
- const f32 z = expf(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));
+ const f32 z = (f32)exp(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));
return 0.25f+0.25f*z;
}
@@ -180,7 +180,7 @@ private:
public:
SMesh* Mesh;
- TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f)
+ TMesh() : Width(0), Height(0), Scale(1.f), Mesh(0)
{
Mesh = new SMesh();
}
diff --git a/examples/25.XmlHandling/main.cpp b/examples/25.XmlHandling/main.cpp
index 657ad8d..d022e5c 100644
--- a/examples/25.XmlHandling/main.cpp
+++ b/examples/25.XmlHandling/main.cpp
@@ -142,6 +142,8 @@ public:
//we were at the end of the video section so we reset our tag
currentSection=L"";
break;
+ default:
+ break;
}
}
@@ -344,6 +346,8 @@ public:
}
}
break;
+ default:
+ break;
}
}
diff --git a/examples/Demo/CDemo.cpp b/examples/Demo/CDemo.cpp
index 49dd7b6..6c073ab 100644
--- a/examples/Demo/CDemo.cpp
+++ b/examples/Demo/CDemo.cpp
@@ -497,6 +497,7 @@ void CDemo::loadSceneData()
bill = sm->addBillboardSceneNode(0, core::dimension2d<f32>(100,100),
waypoint[r]+ core::vector3df(0,20,0));
bill->setMaterialFlag(video::EMF_LIGHTING, false);
+ bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
bill->setMaterialTexture(0, driver->getTexture(mediaPath + "portal1.bmp"));
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
bill->addAnimator(anim);
@@ -583,7 +584,7 @@ void CDemo::createLoadingScreen()
const io::path mediaPath = getExampleMediaPath();
// irrlicht logo
- device->getGUIEnvironment()->addImage(device->getVideoDriver()->getTexture(mediaPath + "irrlichtlogo2.png"),
+ device->getGUIEnvironment()->addImage(device->getVideoDriver()->getTexture(mediaPath + "irrlichtlogo3.png"),
core::position2d<s32>(5,5));
// loading text
@@ -648,8 +649,8 @@ void CDemo::shoot()
else
{
// doesnt collide with wall
- core::vector3df start = camera->getPosition();
- core::vector3df end = (camera->getTarget() - start);
+ start = camera->getPosition();
+ end = (camera->getTarget() - start);
end.normalize();
start += end*8.0f;
end = start + (end * camera->getFarValue());
diff --git a/examples/Demo/CMainMenu.cpp b/examples/Demo/CMainMenu.cpp
index ebc9469..432c872 100644
--- a/examples/Demo/CMainMenu.cpp
+++ b/examples/Demo/CMainMenu.cpp
@@ -27,9 +27,9 @@ CMainMenu::CMainMenu()
bool CMainMenu::run()
{
- video::E_DRIVER_TYPE driverType = EDT_OPENGL;
+ video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
if (!IrrlichtDevice::isDriverSupported(video::EDT_OPENGL))
- driverType = video::video::EDT_BURNINGSVIDEO;
+ driverType = video::EDT_BURNINGSVIDEO;
MenuDevice = createDevice(driverType,
core::dimension2d<u32>(512, 384), 16, false, false, false, this);
@@ -195,6 +195,7 @@ bool CMainMenu::run()
{
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
+ bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
bill->setMaterialTexture(0, driver->getTexture(mediaPath + "particlered.bmp"));
}
// add fly circle animator to the light
@@ -213,6 +214,7 @@ bool CMainMenu::run()
{
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
+ bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
bill->setMaterialTexture(0, driver->getTexture(mediaPath + "portal1.bmp"));
}
// add fly circle animator to the light
@@ -275,7 +277,7 @@ bool CMainMenu::run()
{
if (!selected)
{
- outDriver=video::E_DRIVER_TYPE(i);
+ driverType=video::E_DRIVER_TYPE(i);
break;
}
--selected;
diff --git a/source/Irrlicht/Android/jni/Android.mk b/source/Irrlicht/Android/jni/Android.mk
index 54fb245..05a2d28 100755
--- a/source/Irrlicht/Android/jni/Android.mk
+++ b/source/Irrlicht/Android/jni/Android.mk
@@ -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 \
diff --git a/source/Irrlicht/CAnimatedMeshSceneNode.cpp b/source/Irrlicht/CAnimatedMeshSceneNode.cpp
index 593496a..de96749 100644
--- a/source/Irrlicht/CAnimatedMeshSceneNode.cpp
+++ b/source/Irrlicht/CAnimatedMeshSceneNode.cpp
@@ -112,12 +112,12 @@ void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
if (FramesPerSecond > 0.f) //forwards...
{
if (CurrentFrameNr > EndFrame)
- CurrentFrameNr = StartFrame + fmod(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame));
+ CurrentFrameNr = StartFrame + fmodf(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame));
}
else //backwards...
{
if (CurrentFrameNr < StartFrame)
- CurrentFrameNr = EndFrame - fmod(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame));
+ CurrentFrameNr = EndFrame - fmodf(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame));
}
}
else
diff --git a/source/Irrlicht/CBlit.h b/source/Irrlicht/CBlit.h
index d67a76b..b778828 100644
--- a/source/Irrlicht/CBlit.h
+++ b/source/Irrlicht/CBlit.h
@@ -10,6 +10,28 @@
namespace irr
{
+//! f18 - fixpoint 14.18 limit to 16k Textures
+#define CBLIT_USE_FIXPOINT18
+
+#if defined(CBLIT_USE_FIXPOINT18)
+ typedef int f18;
+ #define f18_one 262144
+ #define f18_zero 0
+ #define f32_to_f18(x)((f18)floorf(((x) * 262144.f) + 0.f))
+ #define f32_to_f32(x)(x)
+ #define f18_floor(x) ((x)>>18)
+ #define f18_round(x) ((x+131.072)>>18)
+#else
+ typedef float f18;
+ #define f18_one 1.f
+ #define f18_zero_dot_five 0.5f
+ #define f18_zero 0.f
+ #define f32_to_f18(x)(x)
+ #define f32_to_f32(x)(x)
+ #define f18_floor(x) ((int)(x))
+ #define f18_round(x) ((int)(x+0.5f))
+#endif
+
struct SBlitJob
{
AbsRectangle Dest;
@@ -17,23 +39,21 @@ namespace irr
u32 argb;
- void * src;
- void * dst;
+ const void* src;
+ void* dst;
- s32 width;
- s32 height;
+ u32 width; //draw size
+ u32 height;
- u32 srcPitch;
- u32 dstPitch;
-
- u32 srcPixelMul;
+ u32 srcPixelMul; //pixel byte size
u32 dstPixelMul;
- bool stretch;
- float x_stretch;
- float y_stretch;
+ int srcPitch; //scanline byte size. allow negative for mirror
+ u32 dstPitch;
- SBlitJob() : stretch(false) {}
+ bool stretch;
+ f32 x_stretch;
+ f32 y_stretch;
};
// Bitfields Cohen Sutherland
@@ -237,7 +257,7 @@ static void RenderLine32_Decal(video::IImage *t,
}
u32 *dst;
- dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) );
+ dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 4 ) );
if ( dy > dx )
{
@@ -301,7 +321,7 @@ static void RenderLine32_Blend(video::IImage *t,
}
u32 *dst;
- dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) );
+ dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 4 ) );
if ( dy > dx )
{
@@ -365,7 +385,7 @@ static void RenderLine16_Decal(video::IImage *t,
}
u16 *dst;
- dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) );
+ dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 2 ) );
if ( dy > dx )
{
@@ -429,7 +449,7 @@ static void RenderLine16_Blend(video::IImage *t,
}
u16 *dst;
- dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) );
+ dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 2 ) );
if ( dy > dx )
{
@@ -467,37 +487,57 @@ static void RenderLine16_Blend(video::IImage *t,
*/
static void executeBlit_TextureCopy_x_to_x( const SBlitJob * job )
{
- const u32 w = job->width;
- const u32 h = job->height;
if (job->stretch)
{
- const u32 *src = static_cast<const u32*>(job->src);
- u32 *dst = static_cast<u32*>(job->dst);
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const f18 wscale = f32_to_f18(job->x_stretch);
+ const f18 hscale = f32_to_f18(job->y_stretch);
- for ( u32 dy = 0; dy < h; ++dy )
+ f18 src_y = f18_zero;
+
+ if (job->srcPixelMul == 4)
{
- const u32 src_y = (u32)(dy*hscale);
- src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
+ const u32 *src = (u32*)(job->src);
+ u32 *dst = (u32*)(job->dst);
- for ( u32 dx = 0; dx < w; ++dx )
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
- const u32 src_x = (u32)(dx*wscale);
- dst[dx] = src[src_x];
+ src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
+
+ f18 src_x = f18_zero;
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
+ {
+ dst[dx] = src[f18_floor(src_x)];
+ }
+ dst = (u32*)((u8*)(dst)+job->dstPitch);
+ }
+ }
+ else if (job->srcPixelMul == 2)
+ {
+ const u16 *src = (u16*)(job->src);
+ u16* dst = (u16*)(job->dst);
+
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
+ {
+ src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
+
+ f18 src_x = f18_zero;
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
+ {
+ dst[dx] = src[f18_floor(src_x)];
+ }
+ dst = (u16*)((u8*)(dst)+job->dstPitch);
}
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
- const u32 widthPitch = job->width * job->dstPixelMul;
+ const size_t widthPitch = job->width * job->dstPixelMul;
const void *src = (void*) job->src;
void *dst = (void*) job->dst;
- for ( u32 dy = 0; dy != h; ++dy )
+ for ( u32 dy = 0; dy < job->height; ++dy )
{
- memcpy( dst, src, widthPitch );
+ memcpy( dst, src, widthPitch);
src = (void*) ( (u8*) (src) + job->srcPitch );
dst = (void*) ( (u8*) (dst) + job->dstPitch );
@@ -516,8 +556,8 @@ static void executeBlit_TextureCopy_32_to_16( const SBlitJob * job )
if (job->stretch)
{
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const float wscale = job->x_stretch;
+ const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@@ -562,8 +602,8 @@ static void executeBlit_TextureCopy_24_to_16( const SBlitJob * job )
if (job->stretch)
{
- const float wscale = 3.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const float wscale = job->x_stretch * 3.f;
+ const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@@ -607,8 +647,8 @@ static void executeBlit_TextureCopy_16_to_32( const SBlitJob * job )
if (job->stretch)
{
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const float wscale = job->x_stretch;
+ const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@@ -647,8 +687,8 @@ static void executeBlit_TextureCopy_16_to_24( const SBlitJob * job )
if (job->stretch)
{
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const float wscale = job->x_stretch;
+ const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@@ -697,8 +737,8 @@ static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job )
if (job->stretch)
{
- const float wscale = 3.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const float wscale = job->x_stretch * 3.f;
+ const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@@ -715,11 +755,11 @@ static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job )
}
else
{
- for ( s32 dy = 0; dy != job->height; ++dy )
+ for ( u32 dy = 0; dy < job->height; ++dy )
{
const u8* s = src;
- for ( s32 dx = 0; dx != job->width; ++dx )
+ for ( u32 dx = 0; dx < job->width; ++dx )
{
dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2];
s += 3;
@@ -740,8 +780,8 @@ static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job )
if (job->stretch)
{
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const float wscale = job->x_stretch;
+ const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@@ -781,54 +821,21 @@ static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job )
*/
static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )
{
- const u32 w = job->width;
- const u32 h = job->height;
- const u32 rdx = w>>1;
+ const f18 wscale = f32_to_f18(job->x_stretch);
+ const f18 hscale = f32_to_f18(job->y_stretch);
- const u32 *src = (u32*) job->src;
- u32 *dst = (u32*) job->dst;
+ f18 src_y = f18_zero;
+ u16 *dst = (u16*)job->dst;
- if (job->stretch)
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
- const u32 off = core::if_c_a_else_b(w&1, (u32)((w-1)*wscale), 0);
- for ( u32 dy = 0; dy < h; ++dy )
+ const u16* src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
+ f18 src_x = f18_zero;
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
- const u32 src_y = (u32)(dy*hscale);
- src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
-
- for ( u32 dx = 0; dx < rdx; ++dx )
- {
- const u32 src_x = (u32)(dx*wscale);
- dst[dx] = PixelBlend16_simd( dst[dx], src[src_x] );
- }
- if ( off )
- {
- ((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );
- }
-
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );
- }
- }
- else
- {
- const u32 off = core::if_c_a_else_b(w&1, w-1, 0);
- for (u32 dy = 0; dy != h; ++dy )
- {
- for (u32 dx = 0; dx != rdx; ++dx )
- {
- dst[dx] = PixelBlend16_simd( dst[dx], src[dx] );
- }
-
- if ( off )
- {
- ((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );
- }
-
- src = (u32*) ( (u8*) (src) + job->srcPitch );
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );
+ dst[dx] = PixelBlend16(dst[dx], src[f18_floor(src_x)]);
}
+ dst = (u16*)((u8*)(dst)+job->dstPitch);
}
}
@@ -836,40 +843,21 @@ static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )
*/
static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job )
{
- const u32 w = job->width;
- const u32 h = job->height;
- const u32 *src = (u32*) job->src;
- u32 *dst = (u32*) job->dst;
+ const f18 wscale = f32_to_f18(job->x_stretch);
+ const f18 hscale = f32_to_f18(job->y_stretch);
- if (job->stretch)
+ f18 src_y = f18_zero;
+ u32 *dst = (u32*)job->dst;
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
- for ( u32 dy = 0; dy < h; ++dy )
- {
- const u32 src_y = (u32)(dy*hscale);
- src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
-
- for ( u32 dx = 0; dx < w; ++dx )
- {
- const u32 src_x = (u32)(dx*wscale);
- dst[dx] = PixelBlend32( dst[dx], src[src_x] );
- }
+ const u32* src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );
- }
- }
- else
- {
- for ( u32 dy = 0; dy != h; ++dy )
+ f18 src_x = f18_zero;
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
- for ( u32 dx = 0; dx != w; ++dx )
- {
- dst[dx] = PixelBlend32( dst[dx], src[dx] );
- }
- src = (u32*) ( (u8*) (src) + job->srcPitch );
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );
+ dst[dx] = PixelBlend32(dst[dx], src[f18_floor(src_x)]);
}
+ dst = (u32*)((u8*)(dst)+job->dstPitch);
}
}
@@ -877,21 +865,26 @@ static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job )
*/
static void executeBlit_TextureBlendColor_16_to_16( const SBlitJob * job )
{
- u16 *src = (u16*) job->src;
- u16 *dst = (u16*) job->dst;
+ const u16 blend = video::A8R8G8B8toA1R5G5B5(job->argb);
+
+ const f18 wscale = f32_to_f18(job->x_stretch);
+ const f18 hscale = f32_to_f18(job->y_stretch);
- u16 blend = video::A8R8G8B8toA1R5G5B5 ( job->argb );
- for ( s32 dy = 0; dy != job->height; ++dy )
+ f18 src_y = f18_zero;
+ u16 *dst = (u16*)job->dst;
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
- for ( s32 dx = 0; dx != job->width; ++dx )
+ const u16* src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
+ f18 src_x = f18_zero;
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
- if ( 0 == (src[dx] & 0x8000) )
+ register u16 c0 = src[f18_floor(src_x)];
+ if (0 == (c0 & 0x8000))
continue;
- dst[dx] = PixelMul16_2( src[dx], blend );
+ dst[dx] = PixelMul16_2(c0, blend);
}
- src = (u16*) ( (u8*) (src) + job->srcPitch );
- dst = (u16*) ( (u8*) (dst) + job->dstPitch );
+ dst = (u16*)((u8*)(dst)+job->dstPitch);
}
}
@@ -900,17 +893,21 @@ static void executeBlit_TextureBlendColor_16_to_16( const SBlitJob * job )
*/
static void executeBlit_TextureBlendColor_32_to_32( const SBlitJob * job )
{
- u32 *src = (u32*) job->src;
- u32 *dst = (u32*) job->dst;
+ const f18 wscale = f32_to_f18(job->x_stretch);
+ const f18 hscale = f32_to_f18(job->y_stretch);
- for ( s32 dy = 0; dy != job->height; ++dy )
+ u32* dst = (u32*)job->dst;
+ f18 src_y = f18_zero;
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
- for ( s32 dx = 0; dx != job->width; ++dx )
+ const u32* src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
+
+ f18 src_x = f18_zero;
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
- dst[dx] = PixelBlend32( dst[dx], PixelMul32_2( src[dx], job->argb ) );
+ dst[dx] = PixelBlend32(dst[dx], PixelMul32_2(src[f18_floor(src_x)], job->argb));
}
- src = (u32*) ( (u8*) (src) + job->srcPitch );
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );
+ dst = (u32*)((u8*)(dst)+job->dstPitch);
}
}
@@ -921,7 +918,7 @@ static void executeBlit_Color_16_to_16( const SBlitJob * job )
const u16 c = video::A8R8G8B8toA1R5G5B5(job->argb);
u16 *dst = (u16*) job->dst;
- for ( s32 dy = 0; dy != job->height; ++dy )
+ for ( u32 dy = 0; dy < job->height; ++dy )
{
memset16(dst, c, job->srcPitch);
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
@@ -934,7 +931,7 @@ static void executeBlit_Color_32_to_32( const SBlitJob * job )
{
u32 *dst = (u32*) job->dst;
- for ( s32 dy = 0; dy != job->height; ++dy )
+ for ( u32 dy = 0; dy < job->height; ++dy )
{
memset32( dst, job->argb, job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
@@ -952,11 +949,11 @@ static void executeBlit_ColorAlpha_16_to_16( const SBlitJob * job )
return;
const u32 src = video::A8R8G8B8toA1R5G5B5( job->argb );
- for ( s32 dy = 0; dy != job->height; ++dy )
+ for ( u32 dy = 0; dy != job->height; ++dy )
{
- for ( s32 dx = 0; dx != job->width; ++dx )
+ for ( u32 dx = 0; dx != job->width; ++dx )
{
- dst[dx] = 0x8000 | PixelBlend16( dst[dx], src, alpha );
+ dst[dx] = PixelBlend16( dst[dx], src, alpha );
}
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
}
@@ -966,19 +963,33 @@ static void executeBlit_ColorAlpha_16_to_16( const SBlitJob * job )
*/
static void executeBlit_ColorAlpha_32_to_32( const SBlitJob * job )
{
- u32 *dst = (u32*) job->dst;
-
const u32 alpha = extractAlpha( job->argb );
- const u32 src = job->argb;
+ if (0 == alpha)
+ return;
- for ( s32 dy = 0; dy != job->height; ++dy )
+ u32 *dst = (u32*)job->dst;
+ for ( u32 dy = 0; dy < job->height; ++dy )
{
- for ( s32 dx = 0; dx != job->width; ++dx )
+ for ( u32 dx = 0; dx < job->width; ++dx )
{
- dst[dx] = (job->argb & 0xFF000000 ) | PixelBlend32( dst[dx], src, alpha );
+ dst[dx] = PixelBlend32( dst[dx], job->argb, alpha );
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
+
+}
+
+/*!
+ Pixel =>
+ color = sourceAlpha > 0 ? source, else dest
+ alpha = max(destAlpha, sourceAlpha)
+*/
+inline u16 PixelCombine16(const u16 c2, const u16 c1)
+{
+ if (video::getAlpha(c1) > 0)
+ return c1;
+ else
+ return c2;
}
/*!
@@ -1023,8 +1034,8 @@ static void executeBlit_TextureCombineColor_16_to_24( const SBlitJob * job )
if (job->stretch)
{
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const float wscale = job->x_stretch;
+ const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@@ -1069,6 +1080,58 @@ static void executeBlit_TextureCombineColor_16_to_24( const SBlitJob * job )
}
/*!
+ Pixel =>
+ color = dest * ( 1 - SourceAlpha ) + source * SourceAlpha,
+ alpha = destAlpha * ( 1 - SourceAlpha ) + sourceAlpha
+
+ where "1" means "full scale" (255)
+*/
+inline u32 PixelCombine32(const u32 c2, const u32 c1)
+{
+ // alpha test
+ u32 alpha = c1 & 0xFF000000;
+
+ if (0 == alpha)
+ return c2;
+ if (0xFF000000 == alpha)
+ {
+ return c1;
+ }
+
+ alpha >>= 24;
+
+ // add highbit alpha, if ( alpha > 127 ) alpha += 1;
+ // stretches [0;255] to [0;256] to avoid division by 255. use division 256 == shr 8
+ alpha += (alpha >> 7);
+
+ u32 srcRB = c1 & 0x00FF00FF;
+ u32 srcXG = c1 & 0x0000FF00;
+
+ u32 dstRB = c2 & 0x00FF00FF;
+ u32 dstXG = c2 & 0x0000FF00;
+
+
+ u32 rb = srcRB - dstRB;
+ u32 xg = srcXG - dstXG;
+
+ rb *= alpha;
+ xg *= alpha;
+ rb >>= 8;
+ xg >>= 8;
+
+ rb += dstRB;
+ xg += dstXG;
+
+ rb &= 0x00FF00FF;
+ xg &= 0x0000FF00;
+
+ u32 sa = c1 >> 24;
+ u32 da = c2 >> 24;
+ u32 blendAlpha_fix8 = (sa * 256 + da * (256 - alpha)) >> 8;
+ return blendAlpha_fix8 << 24 | rb | xg;
+}
+
+/*!
Combine alpha channels (increases alpha / reduces transparency)
Destination alpha is treated as full 255
*/
@@ -1081,8 +1144,8 @@ static void executeBlit_TextureCombineColor_32_to_24( const SBlitJob * job )
if (job->stretch)
{
- const float wscale = 1.f/job->x_stretch;
- const float hscale = 1.f/job->y_stretch;
+ const float wscale = job->x_stretch;
+ const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@@ -1130,9 +1193,9 @@ static void executeBlit_TextureCombineColor_32_to_32( const SBlitJob * job )
u32 *src = (u32*) job->src;
u32 *dst = (u32*) job->dst;
- for ( s32 dy = 0; dy != job->height; ++dy )
+ for ( u32 dy = 0; dy != job->height; ++dy )
{
- for ( s32 dx = 0; dx != job->width; ++dx )
+ for (u32 dx = 0; dx != job->width; ++dx )
{
dst[dx] = PixelCombine32( dst[dx], PixelMul32_2( src[dx], job->argb ) );
}
@@ -1220,26 +1283,46 @@ static inline tExecuteBlit getBlitter2( eBlitter operation,const video::IImage *
// bounce clipping to texture
-inline void setClip ( AbsRectangle &out, const core::rect<s32> *clip,
- const video::IImage * tex, s32 passnative )
+inline void setClip(AbsRectangle &out, const core::rect<s32> *clip,
+ const video::IImage* tex, s32 passnative, const core::dimension2d<u32>* tex_org)
{
- if ( clip && 0 == tex && passnative )
+ if (0 == tex)
{
- out.x0 = clip->UpperLeftCorner.X;
- out.x1 = clip->LowerRightCorner.X;
- out.y0 = clip->UpperLeftCorner.Y;
- out.y1 = clip->LowerRightCorner.Y;
+ if (clip && passnative)
+ {
+ out.x0 = clip->UpperLeftCorner.X;
+ out.x1 = clip->LowerRightCorner.X;
+ out.y0 = clip->UpperLeftCorner.Y;
+ out.y1 = clip->LowerRightCorner.Y;
+ }
+ else
+ {
+ out.x0 = 0;
+ out.x1 = 0;
+ out.y0 = 0;
+ out.y1 = 0;
+ }
return;
}
- const s32 w = tex ? tex->getDimension().Width : 0;
- const s32 h = tex ? tex->getDimension().Height : 0;
- if ( clip )
+ const s32 w = tex->getDimension().Width;
+ const s32 h = tex->getDimension().Height;
+
+ //driver could have changed texture size.
+ if (clip && tex_org && ((u32)w != tex_org->Width || (u32)h != tex_org->Height))
{
- out.x0 = core::s32_clamp ( clip->UpperLeftCorner.X, 0, w );
- out.x1 = core::s32_clamp ( clip->LowerRightCorner.X, out.x0, w );
- out.y0 = core::s32_clamp ( clip->UpperLeftCorner.Y, 0, h );
- out.y1 = core::s32_clamp ( clip->LowerRightCorner.Y, out.y0, h );
+ out.x0 = core::s32_clamp((clip->UpperLeftCorner.X*w) / tex_org->Width, 0, w - 1);
+ out.x1 = core::s32_clamp((clip->LowerRightCorner.X*w) / tex_org->Width, out.x0, w);
+ out.y0 = core::s32_clamp((clip->UpperLeftCorner.Y*h) / tex_org->Height, 0, h - 1);
+ out.y1 = core::s32_clamp((clip->LowerRightCorner.Y*h) / tex_org->Height, out.y0, h);
+ }
+ else if (clip)
+ {
+ //y-1 to prevent starting on illegal memory (not ideal!).
+ out.x0 = core::s32_clamp(clip->UpperLeftCorner.X, 0, w - 1);
+ out.x1 = core::s32_clamp(clip->LowerRightCorner.X, passnative ? 0 : out.x0, w);
+ out.y0 = core::s32_clamp(clip->UpperLeftCorner.Y, 0, h - 1);
+ out.y1 = core::s32_clamp(clip->LowerRightCorner.Y, passnative ? 0 : out.y0, h);
}
else
{
@@ -1275,8 +1358,8 @@ static s32 Blit(eBlitter operation,
SBlitJob job;
- setClip ( sourceClip, sourceClipping, source, 1 );
- setClip ( destClip, destClipping, dest, 0 );
+ setClip ( sourceClip, sourceClipping, source, 1,0 );
+ setClip ( destClip, destClipping, dest, 0,0 );
v.x0 = destPos ? destPos->X : 0;
v.y0 = destPos ? destPos->Y : 0;
@@ -1296,6 +1379,10 @@ static s32 Blit(eBlitter operation,
job.argb = argb;
+ job.stretch = false;
+ job.x_stretch = 1.f;
+ job.y_stretch = 1.f;
+
if ( source )
{
job.srcPitch = source->getPitch();
@@ -1317,9 +1404,10 @@ static s32 Blit(eBlitter operation,
return 1;
}
+#if defined(SOFTWARE_DRIVER_2_2D_AS_2D)
static s32 StretchBlit(eBlitter operation,
- video::IImage* dest, const core::rect<s32> *destRect,
- const core::rect<s32> *srcRect, video::IImage* const source,
+ video::IImage* dest, const core::rect<s32>* destClipping,const core::rect<s32> *destRect,
+ video::IImage* const source,const core::rect<s32> *srcRect, const core::dimension2d<u32>* source_org,
u32 argb)
{
tExecuteBlit blitter = getBlitter2( operation, dest, source );
@@ -1330,9 +1418,15 @@ static s32 StretchBlit(eBlitter operation,
SBlitJob job;
+ AbsRectangle destClip;
+ AbsRectangle v;
+ setClip(destClip, destClipping, dest, 0, 0);
+ setClip(v, destRect, 0, 1, 0);
+ if (!intersect(job.Dest, destClip, v))
+ return 0;
+
// Clipping
- setClip ( job.Source, srcRect, source, 1 );
- setClip ( job.Dest, destRect, dest, 0 );
+ setClip ( job.Source, srcRect, source, 1, source_org);
job.width = job.Dest.x1-job.Dest.x0;
job.height = job.Dest.y1-job.Dest.y0;
@@ -1340,14 +1434,25 @@ static s32 StretchBlit(eBlitter operation,
job.argb = argb;
// use original dest size, despite any clipping
- job.x_stretch = (float)destRect->getWidth() / (float)(job.Source.x1-job.Source.x0);
- job.y_stretch = (float)destRect->getHeight() / (float)(job.Source.y1-job.Source.y0);
- job.stretch = (job.x_stretch != 1.f) || (job.y_stretch != 1.f);
+ const int dst_w = v.x1 - v.x0; // destRect->getWidth();
+ const int dst_h = v.y1 - v.y0; // destRect->getHeight();
+ const int src_w = job.Source.x1 - job.Source.x0;
+ const int src_h = job.Source.y1 - job.Source.y0;
+
+ job.stretch = dst_w != src_w || dst_h != src_h;
+ job.x_stretch = dst_w ? (float)src_w / (float)dst_w : 1.f;
+ job.y_stretch = dst_h ? (float)src_h / (float)dst_h : 1.f;
+
if ( source )
{
job.srcPitch = source->getPitch();
job.srcPixelMul = source->getBytesPerPixel();
+
+ //dest-clippling. advance source. loosing subpixel precision
+ job.Source.x0 += (s32)floorf(job.x_stretch * (job.Dest.x0 - v.x0));
+ job.Source.y0 += (s32)floorf(job.y_stretch * (job.Dest.y0 - v.y0));
+
job.src = (void*) ( (u8*) source->getData() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) );
}
else
@@ -1364,7 +1469,7 @@ static s32 StretchBlit(eBlitter operation,
return 1;
}
-
+#endif
// Methods for Software drivers
//! draws a rectangle
diff --git a/source/Irrlicht/CBurningShader_Raster_Reference.cpp b/source/Irrlicht/CBurningShader_Raster_Reference.cpp
index c04db94..3d9dacc 100644
--- a/source/Irrlicht/CBurningShader_Raster_Reference.cpp
+++ b/source/Irrlicht/CBurningShader_Raster_Reference.cpp
@@ -5,7 +5,7 @@
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
-#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
+#if defined(_IRR_COMPILE_WITH_BURNINGSVIDEO_) && 0
namespace irr
@@ -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) );
- pShader.dst[pShader.i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
+ pShader.dst[pShader.i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
@@ -578,7 +578,7 @@ void CBurningShader_Raster_Reference::pShader_1 ()
ty0 = tofix ( line.t[0][0].y, inversew );
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
- pShader.dst[pShader.i] = fix_to_color ( r0, g0, b0 );
+ pShader.dst[pShader.i] = fix_to_sample( r0, g0, b0 );
}
@@ -690,15 +690,15 @@ REALINLINE void CBurningShader_Raster_Reference::depthWrite ()
REALINLINE void CBurningShader_Raster_Reference::scanline2()
{
// apply top-left fill-convention, left
- pShader.xStart = core::ceil32_fast( line.x[0] );
- pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ pShader.xStart = fill_convention_left( line.x[0] );
+ pShader.xEnd = fill_convention_right( line.x[1] );
pShader.dx = pShader.xEnd - pShader.xStart;
if ( pShader.dx < 0 )
return;
// slopes
- const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];
// store slopes in endpoint, and correct first pixel
@@ -707,7 +707,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
u32 i;
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;
@@ -721,6 +721,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
line.t[i][0] += line.t[i][1] * subPixel;
}
+ SOFTWARE_DRIVER_2_CLIPCHECK_REF;
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
@@ -734,7 +735,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
// advance next pixel
line.w[0] += line.w[1];
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][0] += line.c[i][1];
@@ -755,15 +756,15 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
u32 i;
// apply top-left fill-convention, left
- pShader.xStart = core::ceil32_fast( line.x[0] );
- pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ pShader.xStart = fill_convention_left( line.x[0] );
+ pShader.xEnd = fill_convention_right( line.x[1] );
pShader.dx = pShader.xEnd - pShader.xStart;
if ( pShader.dx < 0 )
return;
// slopes
- const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
@@ -787,6 +788,9 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
case BD3DCMP_EQUAL:
condition = a != pShader.z[pShader.i];
break;
+ default:
+ condition = 0;
+ break;
}
while ( a < pShader.z[pShader.i] )
{
@@ -807,7 +811,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
a = (f32) pShader.i + subPixel;
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;
@@ -832,7 +836,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
line.w[0] += line.w[1];
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][0] += line.c[i][1];
@@ -847,7 +851,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
}
-void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
sScanConvertData scan;
u32 i;
@@ -859,9 +863,9 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y );
- scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y );
- scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y );
+ scan.invDeltaY[0] = reciprocal_zero2( c->Pos.y - a->Pos.y );
+ scan.invDeltaY[1] = reciprocal_zero2( b->Pos.y - a->Pos.y );
+ scan.invDeltaY[2] = reciprocal_zero2( c->Pos.y - b->Pos.y );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -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];
scan.w[0] = a->Pos.w;
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] = a->Color[i];
@@ -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];
scan.w[1] = a->Pos.w;
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][1] = a->Color[i];
@@ -929,8 +933,8 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
}
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -941,12 +945,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0] * subPixel;
scan.c[i][1] += scan.slopeC[i][1] * subPixel;
}
-
+#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0] * subPixel;
@@ -962,7 +967,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
line.x[scan.right] = scan.x[1];
line.w[scan.right] = scan.w[1];
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][scan.left] = scan.c[i][0];
@@ -984,12 +989,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0];
scan.c[i][1] += scan.slopeC[i][1];
}
-
+#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0];
@@ -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];
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] = a->Color[i] + scan.slopeC[i][0] * temp[0];
@@ -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];
scan.w[1] = b->Pos.w;
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][1] = b->Color[i];
@@ -1043,8 +1049,8 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
}
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
subPixel = ( (f32) yStart ) - b->Pos.y;
@@ -1056,12 +1062,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0] * subPixel;
scan.c[i][1] += scan.slopeC[i][1] * subPixel;
}
-
+#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0] * subPixel;
@@ -1077,7 +1084,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
line.x[scan.right] = scan.x[1];
line.w[scan.right] = scan.w[1];
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][scan.left] = scan.c[i][0];
@@ -1099,12 +1106,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
- for ( i = 0; i != ShaderParam.TextureUnits; ++i )
+#if BURNING_MATERIAL_MAX_COLORS > 0
+ for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0];
scan.c[i][1] += scan.slopeC[i][1];
}
-
+#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0];
diff --git a/source/Irrlicht/CDepthBuffer.cpp b/source/Irrlicht/CDepthBuffer.cpp
index e9126bd..eed7234 100644
--- a/source/Irrlicht/CDepthBuffer.cpp
+++ b/source/Irrlicht/CDepthBuffer.cpp
@@ -30,30 +30,32 @@ CDepthBuffer::CDepthBuffer(const core::dimension2d<u32>& size)
//! destructor
CDepthBuffer::~CDepthBuffer()
{
- delete [] Buffer;
+ if (Buffer)
+ {
+ delete[] Buffer;
+ Buffer = 0;
+ }
}
//! clears the zbuffer
-void CDepthBuffer::clear()
+void CDepthBuffer::clear(f32 value)
{
+ ieee754 zMaxValue;
#ifdef SOFTWARE_DRIVER_2_USE_WBUFFER
- f32 zMax = 0.f;
+ zMaxValue.f = 1.f-value;
#else
- f32 zMax = 1.f;
+ zMaxValue.f = value;
#endif
- u32 zMaxValue;
- zMaxValue = IR(zMax);
-
- memset32 ( Buffer, zMaxValue, TotalSize );
+ memset32 ( Buffer, zMaxValue.u, TotalSize );
}
-//! sets the new size of the zbuffer
+//! sets the new size of the buffer
void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
{
if (size == Size)
@@ -65,13 +67,13 @@ void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
Pitch = size.Width * sizeof ( fp24 );
TotalSize = Pitch * size.Height;
- Buffer = new u8[TotalSize];
+ Buffer = new u8[align_next(TotalSize,16)];
clear ();
}
-//! returns the size of the zbuffer
+//! returns the size of the buffer
const core::dimension2d<u32>& CDepthBuffer::getSize() const
{
return Size;
@@ -80,11 +82,11 @@ const core::dimension2d<u32>& CDepthBuffer::getSize() const
// -----------------------------------------------------------------
//! constructor
-CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size)
-: Buffer(0), Size(0,0)
+CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size, unsigned bit)
+: Buffer(0), Size(0,0),Bit(bit)
{
#ifdef _DEBUG
- setDebugName("CDepthBuffer");
+ setDebugName("CStencilBuffer");
#endif
setSize(size);
@@ -95,20 +97,30 @@ CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size)
//! destructor
CStencilBuffer::~CStencilBuffer()
{
- delete [] Buffer;
+ if (Buffer)
+ {
+ delete[] Buffer;
+ Buffer = 0;
+ }
}
-//! clears the zbuffer
-void CStencilBuffer::clear()
+//! clears the buffer
+void CStencilBuffer::clear(u8 value)
{
- memset32 ( Buffer, 0, TotalSize );
+ u32 set = value;
+ if (Bit == 8)
+ {
+ set |= set << 8;
+ set |= set << 16;
+ }
+ memset32 ( Buffer, set, TotalSize );
}
-//! sets the new size of the zbuffer
+//! sets the new size of the buffer
void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
{
if (size == Size)
@@ -118,15 +130,15 @@ void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
delete [] Buffer;
- Pitch = size.Width * sizeof ( u32 );
+ Pitch = size.Width * sizeof (tStencilSample);
TotalSize = Pitch * size.Height;
- Buffer = new u8[TotalSize];
+ Buffer = new u8[align_next(TotalSize,16)];
clear ();
}
-//! returns the size of the zbuffer
+//! returns the size of the buffer
const core::dimension2d<u32>& CStencilBuffer::getSize() const
{
return Size;
@@ -155,11 +167,11 @@ IDepthBuffer* createDepthBuffer(const core::dimension2d<u32>& size)
}
-//! creates a ZBuffer
-IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size)
+//! creates a Stencil Buffer
+IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size, u32 bit)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
- return new CStencilBuffer(size);
+ return new CStencilBuffer(size,bit);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
diff --git a/source/Irrlicht/CDepthBuffer.h b/source/Irrlicht/CDepthBuffer.h
index 7964efa..aa9c33d 100644
--- a/source/Irrlicht/CDepthBuffer.h
+++ b/source/Irrlicht/CDepthBuffer.h
@@ -23,7 +23,7 @@ namespace video
virtual ~CDepthBuffer();
//! clears the zbuffer
- virtual void clear() _IRR_OVERRIDE_;
+ virtual void clear(f32 value=1.f) _IRR_OVERRIDE_;
//! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@@ -55,13 +55,13 @@ namespace video
public:
//! constructor
- CStencilBuffer(const core::dimension2d<u32>& size);
+ CStencilBuffer(const core::dimension2d<u32>& size, unsigned bit);
//! destructor
virtual ~CStencilBuffer();
//! clears the zbuffer
- virtual void clear() _IRR_OVERRIDE_;
+ virtual void clear(u8 value=0) _IRR_OVERRIDE_;
//! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@@ -80,11 +80,11 @@ namespace video
private:
-
u8* Buffer;
core::dimension2d<u32> Size;
u32 TotalSize;
u32 Pitch;
+ u32 Bit;
};
} // end namespace video
diff --git a/source/Irrlicht/CGUIContextMenu.cpp b/source/Irrlicht/CGUIContextMenu.cpp
index c28d30a..3a6484b 100644
--- a/source/Irrlicht/CGUIContextMenu.cpp
+++ b/source/Irrlicht/CGUIContextMenu.cpp
@@ -88,6 +88,7 @@ u32 CGUIContextMenu::insertItem(u32 idx, const wchar_t* text, s32 commandId, boo
s.IsSeparator = (text == 0);
s.SubMenu = 0;
s.CommandId = commandId;
+ s.PosY = 0;
if (hasSubMenu)
{
diff --git a/source/Irrlicht/CImage.cpp b/source/Irrlicht/CImage.cpp
index c59b060..ffd23fc 100644
--- a/source/Irrlicht/CImage.cpp
+++ b/source/Irrlicht/CImage.cpp
@@ -7,6 +7,7 @@
#include "CColorConverter.h"
#include "CBlit.h"
#include "os.h"
+#include "SoftwareDriver2_helper.h"
namespace irr
{
@@ -25,7 +26,7 @@ CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* d
{
const u32 dataSize = getDataSizeFromFormat(Format, Size.Width, Size.Height);
- Data = new u8[dataSize];
+ Data = new u8[align_next(dataSize,16)];
memcpy(Data, data, dataSize);
DeleteMemory = true;
}
@@ -35,7 +36,7 @@ CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* d
//! Constructor of empty image
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) : IImage(format, size, true)
{
- Data = new u8[getDataSizeFromFormat(Format, Size.Width, Size.Height)];
+ Data = new u8[align_next(getDataSizeFromFormat(Format, Size.Width, Size.Height),16)];
DeleteMemory = true;
}
@@ -133,9 +134,9 @@ void CImage::copyTo(IImage* target, const core::position2d<s32>& pos)
return;
}
- if ( !Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)
+ if (!Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)
&& target && pos.X == 0 && pos.Y == 0 &&
- CColorConverter::canConvertFormat(Format, target->getColorFormat()) )
+ CColorConverter::canConvertFormat(Format, target->getColorFormat()))
{
// No fast blitting, but copyToScaling uses other color conversions and might work
irr::core::dimension2du dim(target->getDimension());
@@ -166,16 +167,9 @@ void CImage::copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, c
return;
}
- if ( combineAlpha )
- {
- Blit(BLITTER_TEXTURE_COMBINE_ALPHA, target, clipRect, &pos, this, &sourceRect, color.color);
- }
- else
- {
- // color blend only necessary on not full spectrum aka. color.color != 0xFFFFFFFF
- Blit(color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND: BLITTER_TEXTURE_ALPHA_COLOR_BLEND,
- target, clipRect, &pos, this, &sourceRect, color.color);
- }
+ eBlitter op = combineAlpha ? BLITTER_TEXTURE_COMBINE_ALPHA :
+ color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND;
+ Blit(op,target, clipRect, &pos, this, &sourceRect, color.color);
}
@@ -386,5 +380,6 @@ inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) cons
}
+
} // end namespace video
} // end namespace irr
diff --git a/source/Irrlicht/CImageLoaderRGB.cpp b/source/Irrlicht/CImageLoaderRGB.cpp
index 1f0b141..dfb4b8b 100644
--- a/source/Irrlicht/CImageLoaderRGB.cpp
+++ b/source/Irrlicht/CImageLoaderRGB.cpp
@@ -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
if (oPtr + count*rgb.Header.BPC > buf + rgb.Header.Xsize * rgb.Header.BPC)
{
- count = ( (buf + rgb.Header.Xsize * rgb.Header.BPC) - oPtr ) / rgb.Header.BPC;
+ count = (s32)( (buf + rgb.Header.Xsize * rgb.Header.BPC) - oPtr ) / rgb.Header.BPC;
}
if (count<=0)
diff --git a/source/Irrlicht/CMY3DMeshFileLoader.h b/source/Irrlicht/CMY3DMeshFileLoader.h
index 0c29802..c0369d4 100644
--- a/source/Irrlicht/CMY3DMeshFileLoader.h
+++ b/source/Irrlicht/CMY3DMeshFileLoader.h
@@ -92,7 +92,9 @@ private:
{
SMyMaterialEntry ()
: Texture1FileName("null"), Texture2FileName("null"),
- Texture1(0), Texture2(0), MaterialType(video::EMT_SOLID) {}
+ Texture1(0), Texture2(0), MaterialType(video::EMT_SOLID) {
+ Header.Name[0] = 0;
+ }
SMyMaterialHeader Header;
core::stringc Texture1FileName;
diff --git a/source/Irrlicht/COBJMeshFileLoader.cpp b/source/Irrlicht/COBJMeshFileLoader.cpp
index d4ce82e..17dcec9 100644
--- a/source/Irrlicht/COBJMeshFileLoader.cpp
+++ b/source/Irrlicht/COBJMeshFileLoader.cpp
@@ -182,6 +182,8 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
smoothingGroup=0;
else
smoothingGroup=core::strtoul10(smooth);
+
+ (void)smoothingGroup; // disable unused variable warnings
}
break;
diff --git a/source/Irrlicht/COSOperator.cpp b/source/Irrlicht/COSOperator.cpp
index 1bdbdc1..6cef827 100644
--- a/source/Irrlicht/COSOperator.cpp
+++ b/source/Irrlicht/COSOperator.cpp
@@ -187,7 +187,8 @@ bool COSOperator::getProcessorSpeedMHz(u32* MHz) const
if (file)
{
char buffer[1024];
- fread(buffer, 1, 1024, file);
+ size_t r = fread(buffer, 1, 1023, file);
+ buffer[r] = 0;
buffer[1023]=0;
core::stringc str(buffer);
s32 pos = str.find("cpu MHz");
diff --git a/source/Irrlicht/CSoftware2MaterialRenderer.h b/source/Irrlicht/CSoftware2MaterialRenderer.h
index 7a88bc2..9715dc9 100644
--- a/source/Irrlicht/CSoftware2MaterialRenderer.h
+++ b/source/Irrlicht/CSoftware2MaterialRenderer.h
@@ -26,6 +26,13 @@ public:
{
}
+ virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
+ bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
+ {
+ if (Driver)
+ Driver->setFallback_Material(material.MaterialType);
+ }
+
protected:
video::CBurningVideoDriver* Driver;
@@ -47,7 +54,6 @@ public:
};
-
//! Transparent material renderer
class CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR : public CSoftware2MaterialRenderer
{
@@ -75,40 +81,6 @@ public:
};
-//! unsupported material renderer
-class CBurningShader_REFERENCE : public CSoftware2MaterialRenderer
-{
-public:
- CBurningShader_REFERENCE ( video::CBurningVideoDriver* driver )
- : CSoftware2MaterialRenderer ( driver ) {}
-
- virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
- bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
- {
- }
-
- virtual void OnUnsetMaterial() _IRR_OVERRIDE_
- {
- }
-
- virtual bool isTransparent() const _IRR_OVERRIDE_
- {
- return false;
- }
-
- virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_
- {
- return true;
- };
-
-
- virtual s32 getRenderCapability() const _IRR_OVERRIDE_
- {
- return 1;
- }
-
-};
-
} // end namespace video
diff --git a/source/Irrlicht/CSoftwareDriver2.cpp b/source/Irrlicht/CSoftwareDriver2.cpp
index 8b514c9..89f0f7b 100644
--- a/source/Irrlicht/CSoftwareDriver2.cpp
+++ b/source/Irrlicht/CSoftwareDriver2.cpp
@@ -8,6 +8,7 @@
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
#include "SoftwareDriver2_helper.h"
+#include "CSoftwareTexture.h"
#include "CSoftwareTexture2.h"
#include "CSoftware2MaterialRenderer.h"
#include "S3DVertex.h"
@@ -15,7 +16,259 @@
#include "CBlit.h"
-#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( tex ) )
+// Matrix now here
+
+template <class T>
+bool mat44_transposed_inverse(irr::core::CMatrix4<T>& out, const irr::core::CMatrix4<T>& M)
+{
+ const T* burning_restrict m = M.pointer();
+
+ double d =
+ (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) -
+ (m[0] * m[6] - m[2] * m[4]) * (m[9] * m[15] - m[11] * m[13]) +
+ (m[0] * m[7] - m[3] * m[4]) * (m[9] * m[14] - m[10] * m[13]) +
+ (m[1] * m[6] - m[2] * m[5]) * (m[8] * m[15] - m[11] * m[12]) -
+ (m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) +
+ (m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]);
+
+ if (fabs(d) < DBL_MIN)
+ {
+ out.makeIdentity();
+ return false;
+ }
+
+ d = 1.0 / d;
+ T* burning_restrict o = out.pointer();
+ o[0] = (T)(d*(m[5] * (m[10] * m[15] - m[11] * m[14]) + m[6] * (m[11] * m[13] - m[9] * m[15]) + m[7] * (m[9] * m[14] - m[10] * m[13])));
+ o[4] = (T)(d*(m[9] * (m[2] * m[15] - m[3] * m[14]) + m[10] * (m[3] * m[13] - m[1] * m[15]) + m[11] * (m[1] * m[14] - m[2] * m[13])));
+ o[8] = (T)(d*(m[13] * (m[2] * m[7] - m[3] * m[6]) + m[14] * (m[3] * m[5] - m[1] * m[7]) + m[15] * (m[1] * m[6] - m[2] * m[5])));
+ o[12] = (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])));
+
+ o[1] = (T)(d*(m[6] * (m[8] * m[15] - m[11] * m[12]) + m[7] * (m[10] * m[12] - m[8] * m[14]) + m[4] * (m[11] * m[14] - m[10] * m[15])));
+ o[5] = (T)(d*(m[10] * (m[0] * m[15] - m[3] * m[12]) + m[11] * (m[2] * m[12] - m[0] * m[14]) + m[8] * (m[3] * m[14] - m[2] * m[15])));
+ o[9] = (T)(d*(m[14] * (m[0] * m[7] - m[3] * m[4]) + m[15] * (m[2] * m[4] - m[0] * m[6]) + m[12] * (m[3] * m[6] - m[2] * m[7])));
+ o[13] = (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])));
+
+ o[2] = (T)(d*(m[7] * (m[8] * m[13] - m[9] * m[12]) + m[4] * (m[9] * m[15] - m[11] * m[13]) + m[5] * (m[11] * m[12] - m[8] * m[15])));
+ o[6] = (T)(d*(m[11] * (m[0] * m[13] - m[1] * m[12]) + m[8] * (m[1] * m[15] - m[3] * m[13]) + m[9] * (m[3] * m[12] - m[0] * m[15])));
+ o[10] = (T)(d*(m[15] * (m[0] * m[5] - m[1] * m[4]) + m[12] * (m[1] * m[7] - m[3] * m[5]) + m[13] * (m[3] * m[4] - m[0] * m[7])));
+ o[14] = (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])));
+
+ 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])));
+ 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])));
+ 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])));
+ 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])));
+
+ return true;
+}
+
+#if 0
+// difference to CMatrix4<T>::getInverse . higher precision in determinant. return identity on failure
+template <class T>
+bool mat44_inverse(CMatrix4<T>& out, const CMatrix4<T>& M)
+{
+ const T* m = M.pointer();
+
+ double d =
+ (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) -
+ (m[0] * m[6] - m[2] * m[4]) * (m[9] * m[15] - m[11] * m[13]) +
+ (m[0] * m[7] - m[3] * m[4]) * (m[9] * m[14] - m[10] * m[13]) +
+ (m[1] * m[6] - m[2] * m[5]) * (m[8] * m[15] - m[11] * m[12]) -
+ (m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) +
+ (m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]);
+
+ if (fabs(d) < DBL_MIN)
+ {
+ out.makeIdentity();
+ return false;
+ }
+
+ d = 1.0 / d;
+ T* o = out.pointer();
+ o[0] = (T)(d*(m[5] * (m[10] * m[15] - m[11] * m[14]) + m[6] * (m[11] * m[13] - m[9] * m[15]) + m[7] * (m[9] * m[14] - m[10] * m[13])));
+ o[1] = (T)(d*(m[9] * (m[2] * m[15] - m[3] * m[14]) + m[10] * (m[3] * m[13] - m[1] * m[15]) + m[11] * (m[1] * m[14] - m[2] * m[13])));
+ o[2] = (T)(d*(m[13] * (m[2] * m[7] - m[3] * m[6]) + m[14] * (m[3] * m[5] - m[1] * m[7]) + m[15] * (m[1] * m[6] - m[2] * m[5])));
+ 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])));
+
+ 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])));
+ o[5] = (T)(d*(m[10] * (m[0] * m[15] - m[3] * m[12]) + m[11] * (m[2] * m[12] - m[0] * m[14]) + m[8] * (m[3] * m[14] - m[2] * m[15])));
+ o[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])));
+ 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])));
+
+ 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])));
+ 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])));
+ o[10] = (T)(d*(m[15] * (m[0] * m[5] - m[1] * m[4]) + m[12] * (m[1] * m[7] - m[3] * m[5]) + m[13] * (m[3] * m[4] - m[0] * m[7])));
+ o[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])));
+
+ 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])));
+ 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])));
+ 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])));
+ 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])));
+
+ return true;
+}
+#endif
+
+// void CMatrix4<T>::transformVec4(T *out, const T * in) const
+template <class T>
+inline void transformVec4Vec4(const irr::core::CMatrix4<T>& m, T* burning_restrict out, const T* burning_restrict in)
+{
+ const T* burning_restrict M = m.pointer();
+
+ out[0] = in[0] * M[0] + in[1] * M[4] + in[2] * M[8] + in[3] * M[12];
+ out[1] = in[0] * M[1] + in[1] * M[5] + in[2] * M[9] + in[3] * M[13];
+ out[2] = in[0] * M[2] + in[1] * M[6] + in[2] * M[10] + in[3] * M[14];
+ out[3] = in[0] * M[3] + in[1] * M[7] + in[2] * M[11] + in[3] * M[15];
+}
+
+#if 0
+// void CMatrix4<T>::transformVect(T *out, const core::vector3df &in) const
+template <class T>
+inline void transformVec3Vec4(const irr::core::CMatrix4<T>& m,T* burning_restrict out, const core::vector3df &in)
+{
+ const T* burning_restrict M = m.pointer();
+ out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12];
+ out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13];
+ out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14];
+ out[3] = in.X*M[3] + in.Y*M[7] + in.Z*M[11] + M[15];
+}
+#endif
+
+template <class T>
+inline void rotateVec3Vec4(const irr::core::CMatrix4<T>& m, T* burning_restrict out, const T* burning_restrict in)
+{
+ const T* burning_restrict M = m.pointer();
+
+ out[0] = in[0] * M[0] + in[1] * M[4] + in[2] * M[8];
+ out[1] = in[0] * M[1] + in[1] * M[5] + in[2] * M[9];
+ out[2] = in[0] * M[2] + in[1] * M[6] + in[2] * M[10];
+ out[3] = 0.f;
+}
+
+//based on https://github.com/ekmett/approximate/blob/master/cbits/fast.c powf_fast_precise
+static inline float powf_limit(const float a, const float b)
+{
+ if (a <= 0.0000001f) return 0.f;
+ else if (a >= 1.f) return 1.f;
+
+ /* calculate approximation with fraction of the exponent */
+ int e = (int)b;
+ union { float f; int x; } u = { a };
+ u.x = (int)((b - e) * (u.x - 1065353216) + 1065353216);
+
+ float r = 1.0f;
+ float ua = a;
+ while (e) {
+ if (e & 1) {
+ r *= ua;
+ }
+ if (ua < 0.00000001f)
+ break;
+ ua *= ua;
+ e >>= 1;
+ }
+
+ r *= u.f;
+ return r;
+}
+
+
+#if defined(Tweak_Burning)
+
+// run time parameter
+struct tweakBurning
+{
+ tweakBurning()
+ {
+ current = 11;
+ step = 0.0001f;
+
+ ndc_shrink_x = -0.75f;
+ ndc_scale_x = 0.5f;
+ ndc_trans_x = -0.5f;
+
+ ndc_shrink_y = -0.75f;
+ ndc_scale_y = -0.5f;
+ ndc_trans_y = -0.5f;
+
+ tex_w_add = 0.f;
+ tex_h_add = 0.f;
+ tex_cx_add = 0.f;
+ tex_cy_add = 0.f;
+
+ AreaMinDrawSize = 0.001f;
+ }
+ int current;
+
+ union
+ {
+ struct {
+ f32 step;
+
+ f32 ndc_shrink_x;
+ f32 ndc_scale_x;
+ f32 ndc_trans_x;
+
+ f32 ndc_shrink_y;
+ f32 ndc_scale_y;
+ f32 ndc_trans_y;
+
+ f32 tex_w_add;
+ f32 tex_cx_add;
+ f32 tex_h_add;
+ f32 tex_cy_add;
+
+ f32 AreaMinDrawSize; //! minimal visible covered area for primitive
+ };
+ f32 val[16];
+ };
+ static const char* const name[16];
+ void postEventFromUser(const SEvent& e);
+};
+
+const char* const tweakBurning::name[] = { "step",
+ "ndc_shrink_x","ndc_scale_x","ndc_trans_x",
+ "ndc_shrink_y","ndc_scale_y","ndc_trans_y",
+ "tex_w_add","tex_cx_add","tex_h_add","tex_cy_add",
+ "dc_area",0 };
+
+void tweakBurning::postEventFromUser(const SEvent& e)
+{
+ int show = 0;
+ if (e.EventType == EET_KEY_INPUT_EVENT)
+ {
+ switch (e.KeyInput.Key)
+ {
+ case KEY_KEY_1: step *= 0.9f; if (step < 0.00001f) step = 0.0001f; show = 2; break;
+ case KEY_KEY_2: step *= 1.1f; show = 2; break;
+
+ case KEY_KEY_3: if (!e.KeyInput.PressedDown) { current -= 1; if (current < 1) current = 11; show = 1; } break;
+ case KEY_KEY_4: if (!e.KeyInput.PressedDown) { current += 1; if (current > 11) current = 1; show = 1; } break;
+
+ case KEY_KEY_5: val[current] -= e.KeyInput.Shift ? step * 100.f : step; show = 1; break;
+ case KEY_KEY_6: val[current] += e.KeyInput.Shift ? step * 100.f : step; show = 1; break;
+ default:
+ break;
+ }
+ }
+ if (show)
+ {
+ if (step < 0.0001f) step = 0.0001f;
+ char buf[256];
+ if (show == 2) sprintf(buf, "%s %f\n", name[0], val[0]);
+ else sprintf(buf, "%s %f\n", name[current], val[current]);
+ os::Printer::print(buf);
+ }
+}
+
+void CBurningVideoDriver::postEventFromUser(const void* sevent)
+{
+ if (sevent) Tweak.postEventFromUser(*(const SEvent*)sevent);
+}
+
+tweakBurning Tweak;
+#endif //defined(Tweak_Burning)
+
namespace irr
@@ -28,13 +281,17 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
: CNullDriver(io, params.WindowSize), BackBuffer(0), Presenter(presenter),
WindowId(0), SceneSourceRect(0),
RenderTargetTexture(0), RenderTargetSurface(0), CurrentShader(0),
- DepthBuffer(0), StencilBuffer ( 0 ),
- CurrentOut ( 16 * 2, 256 ), Temp ( 16 * 2, 256 )
+ DepthBuffer(0), StencilBuffer ( 0 )
{
+ //enable fpu exception
+ //unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM);
+
#ifdef _DEBUG
setDebugName("CBurningVideoDriver");
#endif
+ VertexCache_map_source_format();
+
// create backbuffer
BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, params.WindowSize);
if (BackBuffer)
@@ -47,24 +304,25 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
// create stencil buffer
if ( params.Stencilbuffer )
- StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension());
+ StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension(),8);
}
- DriverAttributes->setAttribute("MaxTextures", 2);
DriverAttributes->setAttribute("MaxIndices", 1<<16);
- DriverAttributes->setAttribute("MaxTextureSize", SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE);
+ DriverAttributes->setAttribute("MaxTextures", BURNING_MATERIAL_MAX_TEXTURES);
+ DriverAttributes->setAttribute("MaxTextureSize", SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1<<20);
DriverAttributes->setAttribute("MaxLights", 1024 ); //glsl::gl_MaxLights);
DriverAttributes->setAttribute("MaxTextureLODBias", 16.f);
- DriverAttributes->setAttribute("Version", 49);
+ DriverAttributes->setAttribute("Version", 50);
// create triangle renderers
- irr::memset32 ( BurningShader, 0, sizeof ( BurningShader ) );
+ memset( BurningShader, 0, sizeof ( BurningShader ) );
//BurningShader[ETR_FLAT] = createTRFlat2(DepthBuffer);
//BurningShader[ETR_FLAT_WIRE] = createTRFlatWire2(DepthBuffer);
BurningShader[ETR_GOURAUD] = createTriangleRendererGouraud2(this);
- BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(this );
- BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(this );
+ BurningShader[ETR_GOURAUD_NOZ] = createTriangleRendererGouraudNoZ2(this);
+ //BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(this );
+ BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(this ); // 2D
//BurningShader[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire2(DepthBuffer);
//BurningShader[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat2(DepthBuffer);
//BurningShader[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire2(DepthBuffer);
@@ -89,13 +347,15 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
BurningShader[ETR_STENCIL_SHADOW] = createTRStencilShadow ( this );
BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend( this );
- BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this );
+ BurningShader[ETR_TRANSPARENT_REFLECTION_2_LAYER] = createTriangleRendererTexture_transparent_reflection_2_layer(this);
+ //BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this );
+ BurningShader[ETR_COLOR] = create_burning_shader_color(this);
// add the same renderer for all solid types
CSoftware2MaterialRenderer_SOLID* smr = new CSoftware2MaterialRenderer_SOLID( this);
CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR* tmr = new CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR( this);
- CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this );
+ //CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this );
//!TODO: addMaterialRenderer depends on pushing order....
addMaterialRenderer ( smr ); // EMT_SOLID
@@ -108,7 +368,7 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M2,
addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M4,
addMaterialRenderer ( smr ); // EMT_DETAIL_MAP,
- addMaterialRenderer ( umr ); // EMT_SPHERE_MAP,
+ addMaterialRenderer ( smr ); // EMT_SPHERE_MAP,
addMaterialRenderer ( smr ); // EMT_REFLECTION_2_LAYER,
addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ADD_COLOR,
addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL,
@@ -116,7 +376,7 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_VERTEX_ALPHA,
addMaterialRenderer ( smr ); // EMT_TRANSPARENT_REFLECTION_2_LAYER,
addMaterialRenderer ( smr ); // EMT_NORMAL_MAP_SOLID,
- addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR,
+ addMaterialRenderer ( tmr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR,
addMaterialRenderer ( tmr ); // EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA,
addMaterialRenderer ( smr ); // EMT_PARALLAX_MAP_SOLID,
addMaterialRenderer ( tmr ); // EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR,
@@ -125,16 +385,17 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
smr->drop ();
tmr->drop ();
- umr->drop ();
+ //umr->drop ();
// select render target
setRenderTargetImage(BackBuffer);
//reset Lightspace
- LightSpace.reset ();
+ EyeSpace.reset();
+ EyeSpace.resetFog();
// select the right renderer
- setCurrentShader();
+ setMaterial(Material.org);
}
@@ -143,161 +404,45 @@ CBurningVideoDriver::~CBurningVideoDriver()
{
// delete Backbuffer
if (BackBuffer)
+ {
BackBuffer->drop();
+ BackBuffer = 0;
+ }
// delete triangle renderers
-
for (s32 i=0; i<ETR2_COUNT; ++i)
{
if (BurningShader[i])
+ {
BurningShader[i]->drop();
+ BurningShader[i] = 0;
+ }
}
// delete Additional buffer
if (StencilBuffer)
- StencilBuffer->drop();
-
- if (DepthBuffer)
- DepthBuffer->drop();
-
- if (RenderTargetTexture)
- RenderTargetTexture->drop();
-
- if (RenderTargetSurface)
- RenderTargetSurface->drop();
-}
-
-
-/*!
- selects the right triangle renderer based on the render states.
-*/
-void CBurningVideoDriver::setCurrentShader()
-{
- ITexture *texture0 = Material.org.getTexture(0);
- ITexture *texture1 = Material.org.getTexture(1);
-
- bool zMaterialTest = Material.org.ZBuffer != ECFN_DISABLED &&
- Material.org.ZWriteEnable != video::EZW_OFF &&
- ( AllowZWriteOnTransparent || !Material.org.isTransparent() );
-
- EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ;
-
- TransformationFlag[ ETS_TEXTURE_0] &= ~(ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION);
- LightSpace.Flags &= ~VERTEXTRANSFORM;
-
- switch ( Material.org.MaterialType )
{
- case EMT_ONETEXTURE_BLEND:
- shader = ETR_TEXTURE_BLEND;
- break;
-
- case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
- Material.org.MaterialTypeParam = 0.5f;
- // fall through
- case EMT_TRANSPARENT_ALPHA_CHANNEL:
- if ( texture0 && texture0->hasAlpha () )
- {
- shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ;
- break;
- }
- else
- {
- shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;
- }
- break;
-
- case EMT_TRANSPARENT_ADD_COLOR:
- shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z;
- break;
-
- case EMT_TRANSPARENT_VERTEX_ALPHA:
- shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;
- break;
-
- case EMT_LIGHTMAP:
- case EMT_LIGHTMAP_LIGHTING:
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;
- break;
-
- case EMT_LIGHTMAP_M2:
- case EMT_LIGHTMAP_LIGHTING_M2:
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2;
- break;
-
- case EMT_LIGHTMAP_LIGHTING_M4:
- if ( texture1 )
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4;
- break;
- case EMT_LIGHTMAP_M4:
- if ( texture1 )
- shader = ETR_TEXTURE_LIGHTMAP_M4;
- break;
-
- case EMT_LIGHTMAP_ADD:
- if ( texture1 )
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD;
- break;
-
- case EMT_DETAIL_MAP:
- if ( texture1 )
- shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP;
- break;
-
- case EMT_SPHERE_MAP:
- TransformationFlag[ ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_REFLECTION; // ETF_TEXGEN_CAMERA_NORMAL;
- LightSpace.Flags |= VERTEXTRANSFORM;
- break;
- case EMT_REFLECTION_2_LAYER:
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;
- TransformationFlag[ ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION;
- LightSpace.Flags |= VERTEXTRANSFORM;
- break;
-
- case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
- case EMT_NORMAL_MAP_SOLID:
- case EMT_PARALLAX_MAP_SOLID:
- case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
- shader = ETR_NORMAL_MAP_SOLID;
- LightSpace.Flags |= VERTEXTRANSFORM;
- break;
-
- default:
- break;
-
+ StencilBuffer->drop();
+ StencilBuffer = 0;
}
- if ( !texture0 )
+ if (DepthBuffer)
{
- shader = ETR_GOURAUD;
+ DepthBuffer->drop();
+ DepthBuffer = 0;
}
- if ( Material.org.Wireframe )
+ if (RenderTargetTexture)
{
- shader = ETR_TEXTURE_GOURAUD_WIRE;
+ RenderTargetTexture->drop();
+ RenderTargetTexture = 0;
}
- //shader = ETR_REFERENCE;
-
- // switchToTriangleRenderer
- CurrentShader = BurningShader[shader];
- if ( CurrentShader )
+ if (RenderTargetSurface)
{
- CurrentShader->setZCompareFunc ( Material.org.ZBuffer );
- CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);
- CurrentShader->setMaterial ( Material );
-
- switch ( shader )
- {
- case ETR_TEXTURE_GOURAUD_ALPHA:
- case ETR_TEXTURE_GOURAUD_ALPHA_NOZ:
- case ETR_TEXTURE_BLEND:
- CurrentShader->setParam ( 0, Material.org.MaterialTypeParam );
- break;
- default:
- break;
- }
+ RenderTargetSurface->drop();
+ RenderTargetSurface = 0;
}
-
}
@@ -305,31 +450,63 @@ void CBurningVideoDriver::setCurrentShader()
//! queries the features of the driver, returns true if feature is available
bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
{
- if (!FeatureEnabled[feature])
- return false;
-
+ int on = 0;
switch (feature)
{
#ifdef SOFTWARE_DRIVER_2_BILINEAR
case EVDF_BILINEAR_FILTER:
- return true;
+ on = 1;
+ break;
#endif
#ifdef SOFTWARE_DRIVER_2_MIPMAPPING
case EVDF_MIP_MAP:
- return true;
+ on = 1;
+ break;
#endif
case EVDF_STENCIL_BUFFER:
- return StencilBuffer != 0;
+ on = StencilBuffer != 0;
+ break;
case EVDF_RENDER_TO_TARGET:
case EVDF_MULTITEXTURE:
case EVDF_HARDWARE_TL:
case EVDF_TEXTURE_NSQUARE:
- return true;
+ case EVDF_TEXTURE_MATRIX:
+ on = 1;
+ break;
+
+ case EVDF_DEPTH_CLAMP: // shadow
+ on = 1;
+ break;
+
+ case EVDF_TEXTURE_NPOT: // for 2D
+ on = 0;
+ break;
+ case EVDF_ARB_FRAGMENT_PROGRAM_1:
+ case EVDF_ARB_VERTEX_PROGRAM_1:
+ on = 1;
+ break;
+#if defined(PATCH_SUPERTUX_8_0_1)
+ case EVDF_TEXTURE_NPOT:
+ case EVDF_ARB_GLSL:
+ on = 1;
+ break;
+#endif
+
+#if defined(SOFTWARE_DRIVER_2_2D_AS_3D)
+#if defined(IRRLICHT_FREE_CANVAS)
+ case EVDF_VIEWPORT_SCALE_GUI:
+ on = 1;
+ break;
+#endif
+#endif
default:
- return false;
+ on = 0;
+ break;
}
+
+ return on && FeatureEnabled[feature];
}
@@ -344,52 +521,161 @@ IRenderTarget* CBurningVideoDriver::addRenderTarget()
}
-
-//! sets transformation
-void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
+//matrix multiplication
+void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state)
{
- Transformation[state] = mat;
- core::setbit_cond ( TransformationFlag[state], mat.isIdentity(), ETF_IDENTITY );
+ size_t* flag = TransformationFlag[TransformationStack];
+ if (flag[state] & ETF_VALID ) return;
+ //check
+ int ok = 0;
switch ( state )
{
- case ETS_VIEW:
- Transformation[ETS_VIEW_PROJECTION].setbyproduct_nocheck (
- Transformation[ETS_PROJECTION],
- Transformation[ETS_VIEW]
- );
- getCameraPosWorldSpace ();
+ case ETS_PROJ_MODEL_VIEW:
+ if ( 0 == (flag[ETS_VIEW_PROJECTION] & ETF_VALID) ) transform_calc (ETS_VIEW_PROJECTION);
+ ok = flag[ETS_WORLD] & flag[ETS_VIEW] & flag[ETS_PROJECTION] & flag[ETS_VIEW_PROJECTION] & ETF_VALID;
+ break;
+ case ETS_VIEW_PROJECTION:
+ ok = flag[ETS_VIEW] & flag[ETS_PROJECTION] & ETF_VALID;
+ break;
+ case ETS_MODEL_VIEW:
+ ok = flag[ETS_WORLD] & flag[ETS_VIEW] & ETF_VALID;
+ break;
+ case ETS_NORMAL:
+ ok = flag[ETS_MODEL_VIEW] & ETF_VALID;
+ break;
+ default:
break;
+ }
- case ETS_WORLD:
- if ( TransformationFlag[state] & ETF_IDENTITY )
+ if ( !ok )
+ {
+ char buf[256];
+ sprintf(buf,"transform_calc not valid for %d\n",state);
+ os::Printer::log(buf, ELL_WARNING);
+ }
+
+ core::matrix4* matrix = Transformation[TransformationStack];
+
+ switch ( state )
+ {
+ case ETS_PROJ_MODEL_VIEW:
+ if (flag[ETS_WORLD] & ETF_IDENTITY )
+ {
+ matrix[state] = matrix[ETS_VIEW_PROJECTION];
+ }
+ else
+ {
+ matrix[state].setbyproduct_nocheck(matrix[ETS_VIEW_PROJECTION], matrix[ETS_WORLD]);
+ }
+ break;
+
+ case ETS_VIEW_PROJECTION:
+ matrix[state].setbyproduct_nocheck (matrix[ETS_PROJECTION], matrix[ETS_VIEW]);
+ break;
+ case ETS_MODEL_VIEW:
+ if ( flag[ETS_WORLD] & ETF_IDENTITY )
{
- Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD];
- TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY;
- Transformation[ETS_CURRENT] = Transformation[ETS_VIEW_PROJECTION];
+ matrix[state] = matrix[ETS_VIEW];
}
else
{
- //Transformation[ETS_WORLD].getInversePrimitive ( Transformation[ETS_WORLD_INVERSE] );
- Transformation[ETS_CURRENT].setbyproduct_nocheck (
- Transformation[ETS_VIEW_PROJECTION],
- Transformation[ETS_WORLD]
- );
+ matrix[state].setbyproduct_nocheck(matrix[ETS_VIEW], matrix[ETS_WORLD]);
}
- TransformationFlag[ETS_CURRENT] = 0;
- //getLightPosObjectSpace ();
+ break;
+ case ETS_NORMAL:
+ mat44_transposed_inverse(matrix[state], matrix[ETS_MODEL_VIEW]);
+ break;
+
+ default:
+ break;
+ }
+ flag[state] |= ETF_VALID;
+}
+
+
+//! sets transformation
+void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
+{
+ size_t* flag = TransformationFlag[TransformationStack];
+ core::matrix4* matrix = Transformation[TransformationStack];
+
+#if 0
+ int changed = 1;
+ if (flag[state] & ETF_VALID)
+ {
+ changed = memcmp(mat.pointer(), matrix[state].pointer(), sizeof(mat));
+ }
+ if (changed)
+#endif
+ {
+ matrix[state] = mat;
+ flag[state] |= ETF_VALID;
+ }
+
+ //maybe identity (mostly for texturematrix to avoid costly multiplication)
+#if defined ( USE_MATRIX_TEST )
+ burning_setbit( TransformationFlag[state], mat.getDefinitelyIdentityMatrix(), ETF_IDENTITY );
+#else
+ burning_setbit(flag[state],
+ !memcmp(mat.pointer(), core::IdentityMatrix.pointer(),sizeof(mat)),ETF_IDENTITY
+ );
+#endif
+
+#if 0
+ if ( changed )
+#endif
+ switch ( state )
+ {
+ case ETS_PROJECTION:
+ flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;
+ flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID;
+ break;
+ case ETS_VIEW:
+ flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;
+ flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID;
+ flag[ETS_MODEL_VIEW] &= ~ETF_VALID;
+ flag[ETS_NORMAL] &= ~ETF_VALID;
+ break;
+ case ETS_WORLD:
+ flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;
+ flag[ETS_MODEL_VIEW] &= ~ETF_VALID;
+ flag[ETS_NORMAL] &= ~ETF_VALID;
break;
case ETS_TEXTURE_0:
case ETS_TEXTURE_1:
case ETS_TEXTURE_2:
case ETS_TEXTURE_3:
- if ( 0 == (TransformationFlag[state] & ETF_IDENTITY ) )
- LightSpace.Flags |= VERTEXTRANSFORM;
+#if _IRR_MATERIAL_MAX_TEXTURES_>4
+ case ETS_TEXTURE_4:
+#endif
+#if _IRR_MATERIAL_MAX_TEXTURES_>5
+ case ETS_TEXTURE_5:
+#endif
+#if _IRR_MATERIAL_MAX_TEXTURES_>6
+ case ETS_TEXTURE_6:
+#endif
+#if _IRR_MATERIAL_MAX_TEXTURES_>7
+ case ETS_TEXTURE_7:
+#endif
+ if ( 0 == (flag[state] & ETF_IDENTITY ) )
+ {
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;
+ }
+ break;
default:
break;
}
+
+}
+
+//! Returns the transformation set by setTransform
+const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const
+{
+ return Transformation[TransformationStack][state];
}
+
bool CBurningVideoDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
{
CNullDriver::beginScene(clearFlag, clearColor, clearDepth, clearStencil, videoData, sourceRect);
@@ -398,7 +684,7 @@ bool CBurningVideoDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clear
clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);
- memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) );
+ //memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) );
return true;
}
@@ -438,13 +724,13 @@ bool CBurningVideoDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag
return true;
}
-
//! sets a render target
void CBurningVideoDriver::setRenderTargetImage(video::CImage* image)
{
if (RenderTargetSurface)
RenderTargetSurface->drop();
+ core::dimension2d<u32> current = RenderTargetSize;
RenderTargetSurface = image;
RenderTargetSize.Width = 0;
RenderTargetSize.Height = 0;
@@ -455,7 +741,11 @@ void CBurningVideoDriver::setRenderTargetImage(video::CImage* image)
RenderTargetSize = RenderTargetSurface->getDimension();
}
- setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height));
+ int not_changed = current == RenderTargetSize;
+ burning_setbit(TransformationFlag[0][ETS_PROJECTION], not_changed, ETF_VALID);
+ burning_setbit(TransformationFlag[1][ETS_PROJECTION], not_changed, ETF_VALID);
+
+ setViewPort(core::recti(RenderTargetSize));
if (DepthBuffer)
DepthBuffer->setSize(RenderTargetSize);
@@ -465,6 +755,67 @@ void CBurningVideoDriver::setRenderTargetImage(video::CImage* image)
}
+//--------- Transform from NDC to DC, transform TexCoo ----------------------------------------------
+
+// controls subtexel and fill convention
+#if defined(SOFTWARE_DRIVER_2_SUBTEXEL)
+#define SOFTWARE_DRIVER_2_PIXEL_CENTER -0.5f
+#else
+#define SOFTWARE_DRIVER_2_PIXEL_CENTER -0.5f
+#endif
+
+#if 1
+
+// used to scale <-1,-1><1,1> to viewport
+void buildNDCToDCMatrix(f32* m, const core::rect<s32>& viewport, f32 tx)
+{
+ m[0] = (viewport.getWidth() + tx) * 0.5f;
+ m[1] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ((viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X) * 0.5f);
+
+ m[2] = (viewport.getHeight() + tx) * -0.5f;
+ m[3] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ((viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y) * 0.5f);
+}
+
+
+#else
+// used to scale <-1,-1><1,1> to viewport
+void buildNDCToDCMatrix( core::matrix4& out, const core::rect<s32>& viewport)
+{
+ //guard band to stay in screen bounds.(empirical). get holes left side otherwise or out of screen
+ //TODO: match openGL or D3D.
+ //assumption pixel center, top-left rule and rounding error projection deny exact match without additional clipping
+ //or triangle render scanline doesn't step on correct texel center
+ //or sampler is not on texel center
+
+ f32* m = out.pointer();
+#if defined(Tweak_Burning) && 0
+ m[0] = (viewport.getWidth() + Tweak.ndc_shrink_x ) * Tweak.ndc_scale_x;
+ m[5] = (viewport.getHeight() + Tweak.ndc_shrink_y ) * Tweak.ndc_scale_y;
+ m[12] = Tweak.ndc_trans_x + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) * 0.5f );
+ m[13] = Tweak.ndc_trans_y + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) * 0.5f );
+#endif
+
+ m[0] = (viewport.getWidth() - 0.75f ) * 0.5f;
+ m[1] = 0.f;
+ m[2] = 0.f;
+ m[3] = 0.f;
+ m[4] = 0.f;
+ m[5] = (viewport.getHeight() - 0.75f ) * -0.5f;
+ m[6] = 0.f;
+ m[7] = 0.f;
+ m[8] = 0.f;
+ m[9] = 0.f;
+ m[10] = 1.f;
+ m[11] = 0.f;
+ m[12] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) * 0.5f );
+ m[13] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) * 0.5f );
+ m[14] = 0.f;
+ m[15] = 1.f;
+}
+#endif
+
+
+//--------- Transform from NCD to DC ----------------------------------------------
//! sets a viewport
void CBurningVideoDriver::setViewPort(const core::rect<s32>& area)
@@ -474,19 +825,40 @@ void CBurningVideoDriver::setViewPort(const core::rect<s32>& area)
core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height);
ViewPort.clipAgainst(rendert);
- Transformation [ ETS_CLIPSCALE ].buildNDCToDCMatrix ( ViewPort, 1 );
+ buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[0], ViewPort,-0.375f);
+ buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[1], ViewPort, 0.f); // OverrideMaterial2DEnabled ? -0.375f : 0.f);
if (CurrentShader)
CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);
}
+void CBurningVideoDriver::setScissor(int x, int y, int width, int height)
+{
+ AbsRectangle v0;
+ v0.x0 = x;
+ v0.y0 = y;
+ v0.x1 = x+width;
+ v0.y1 = y+width;
+
+ const core::dimension2d<u32>& rt = getCurrentRenderTargetSize();
+ AbsRectangle v1;
+ v1.x0 = 0;
+ v1.y0 = 0;
+ v1.x1 = rt.Width;
+ v1.y1 = rt.Height;
+
+ intersect(Scissor, v0, v1);
+}
+
/*
generic plane clipping in homogenous coordinates
special case ndc frustum <-w,w>,<-w,w>,<-w,w>
can be rewritten with compares e.q near plane, a.z < -a.w and b.z < -b.w
+
+ cam is (0,0,-1)
*/
-const sVec4 CBurningVideoDriver::NDCPlane[6] =
+const sVec4 CBurningVideoDriver::NDCPlane[6+2] =
{
sVec4( 0.f, 0.f, -1.f, -1.f ), // near
sVec4( 0.f, 0.f, 1.f, -1.f ), // far
@@ -497,7 +869,6 @@ const sVec4 CBurningVideoDriver::NDCPlane[6] =
};
-
/*
test a vertex if it's inside the standard frustum
@@ -507,24 +878,24 @@ const sVec4 CBurningVideoDriver::NDCPlane[6] =
for ( u32 i = 0; i!= 6; ++i )
{
dotPlane = v->Pos.dotProduct ( NDCPlane[i] );
- core::setbit_cond( flag, dotPlane <= 0.f, 1 << i );
+ burning_setbit32( flag, dotPlane <= 0.f, 1 << i );
}
// this is the base for ndc frustum <-w,w>,<-w,w>,<-w,w>
- core::setbit_cond( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 );
- core::setbit_cond( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 );
- core::setbit_cond( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 );
- core::setbit_cond( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 );
- core::setbit_cond( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 );
- core::setbit_cond( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 );
+ burning_setbit32( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 );
+ burning_setbit32( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 );
+ burning_setbit32( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 );
+ burning_setbit32( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 );
+ burning_setbit32( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 );
+ burning_setbit32( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 );
*/
#ifdef IRRLICHT_FAST_MATH
-REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const
+REALINLINE size_t CBurningVideoDriver::clipToFrustumTest ( const s4DVertex* v ) const
{
- f32 test[6];
- u32 flag;
+ register size_t flag;
+ f32 test[8];
const f32 w = - v->Pos.w;
// a conditional move is needed....FCOMI ( but we don't have it )
@@ -538,13 +909,22 @@ REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) c
test[4] = v->Pos.y + w;
test[5] = -v->Pos.y + w;
+ const u32* a = F32_AS_U32_POINTER(test);
+ flag = (a[0] ) >> 31;
+ flag |= (a[1] & 0x80000000) >> 30;
+ flag |= (a[2] & 0x80000000) >> 29;
+ flag |= (a[3] & 0x80000000) >> 28;
+ flag |= (a[4] & 0x80000000) >> 27;
+ flag |= (a[5] & 0x80000000) >> 26;
+
+/*
flag = (IR ( test[0] ) ) >> 31;
flag |= (IR ( test[1] ) & 0x80000000 ) >> 30;
flag |= (IR ( test[2] ) & 0x80000000 ) >> 29;
flag |= (IR ( test[3] ) & 0x80000000 ) >> 28;
flag |= (IR ( test[4] ) & 0x80000000 ) >> 27;
flag |= (IR ( test[5] ) & 0x80000000 ) >> 26;
-
+*/
/*
flag = F32_LOWER_EQUAL_0 ( test[0] );
flag |= F32_LOWER_EQUAL_0 ( test[1] ) << 1;
@@ -559,33 +939,24 @@ REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) c
#else
-REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const
+REALINLINE size_t clipToFrustumTest ( const s4DVertex* v )
{
- u32 flag = 0;
+ size_t flag = 0;
- flag |= v->Pos.z <= v->Pos.w ? 1 : 0;
- flag |= -v->Pos.z <= v->Pos.w ? 2 : 0;
+ flag |= v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_NEAR : 0;
+ flag |= -v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_FAR : 0;
- flag |= v->Pos.x <= v->Pos.w ? 4 : 0;
- flag |= -v->Pos.x <= v->Pos.w ? 8 : 0;
+ flag |= v->Pos.x <= v->Pos.w ? VERTEX4D_CLIP_LEFT : 0;
+ flag |= -v->Pos.x <= v->Pos.w ? VERTEX4D_CLIP_RIGHT : 0;
- flag |= v->Pos.y <= v->Pos.w ? 16 : 0;
- flag |= -v->Pos.y <= v->Pos.w ? 32 : 0;
+ flag |= v->Pos.y <= v->Pos.w ? VERTEX4D_CLIP_BOTTOM : 0;
+ flag |= -v->Pos.y <= v->Pos.w ? VERTEX4D_CLIP_TOP : 0;
-/*
- if ( v->Pos.z <= v->Pos.w ) flag |= 1;
- if (-v->Pos.z <= v->Pos.w ) flag |= 2;
- if ( v->Pos.x <= v->Pos.w ) flag |= 4;
- if (-v->Pos.x <= v->Pos.w ) flag |= 8;
-
- if ( v->Pos.y <= v->Pos.w ) flag |= 16;
- if (-v->Pos.y <= v->Pos.w ) flag |= 32;
-*/
/*
- for ( u32 i = 0; i!= 6; ++i )
+ for ( u32 i = 0; i <= 6; ++i )
{
- core::setbit_cond( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i );
+ if (v->Pos.dot_xyzw(NDCPlane[i]) <= 0.f) flag |= ((size_t)1) << i;
}
*/
return flag;
@@ -593,87 +964,136 @@ REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) c
#endif // _MSC_VER
-u32 CBurningVideoDriver::clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane )
-{
- u32 outCount = 0;
- s4DVertex * out = dest;
- const s4DVertex * a;
- const s4DVertex * b = source;
+size_t clipToHyperPlane (
+ s4DVertexPair* burning_restrict dest,
+ const s4DVertexPair* burning_restrict source,
+ const size_t inCount,
+ const sVec4& plane
+)
+{
+ size_t outCount = 0;
+ s4DVertexPair* out = dest;
- f32 bDotPlane;
+ const s4DVertex* a;
+ const s4DVertex* b = source;
- bDotPlane = b->Pos.dotProduct ( plane );
+ ipoltype bDotPlane;
+ bDotPlane = b->Pos.dot_xyzw( plane );
+/*
for( u32 i = 1; i < inCount + 1; ++i)
{
- // i really have problem
+#if 0
+ a = source + (i%inCount)*2;
+#else
const s32 condition = i - inCount;
const s32 index = (( ( condition >> 31 ) & ( i ^ condition ) ) ^ condition ) << 1;
-
- a = &source[ index ];
+ a = source + index;
+#endif
+*/
+ //Sutherland–Hodgman
+ for(size_t i = 0; i < inCount; ++i)
+ {
+ a = source + (i == inCount-1 ? 0 : s4DVertex_ofs(i+1));
// current point inside
- if ( a->Pos.dotProduct ( plane ) <= 0.f )
+ if (ipol_lower_equal_0(a->Pos.dot_xyzw( plane )) )
{
// last point outside
- if ( F32_GREATER_0 ( bDotPlane ) )
+ if (ipol_greater_0( bDotPlane ) )
{
// intersect line segment with plane
- out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) );
- out += 2;
+ out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane) );
+ out += sizeof_s4DVertexPairRel;
outCount += 1;
}
// copy current to out
//*out = *a;
- irr::memcpy32_small ( out, a, SIZEOF_SVERTEX * 2 );
+ memcpy_s4DVertexPair( out, a);
b = out;
- out += 2;
+ out += sizeof_s4DVertexPairRel;
outCount += 1;
}
else
{
// current point outside
-
- if ( F32_LOWER_EQUAL_0 ( bDotPlane ) )
+ if (ipol_lower_equal_0( bDotPlane ) )
{
// previous was inside
// intersect line segment with plane
- out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) );
- out += 2;
+ out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane) );
+ out += sizeof_s4DVertexPairRel;
outCount += 1;
}
// pointer
b = a;
}
- bDotPlane = b->Pos.dotProduct ( plane );
-
+ bDotPlane = b->Pos.dot_xyzw( plane );
}
return outCount;
}
-u32 CBurningVideoDriver::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u32 vIn )
+/*
+ Clip on all planes. Clipper.data
+ clipmask per face
+*/
+size_t CBurningVideoDriver::clipToFrustum(const size_t vIn /*, const size_t clipmask_for_face*/ )
{
- u32 vOut = vIn;
+ s4DVertexPair* v0 = Clipper.data;
+ s4DVertexPair* v1 = Clipper_temp.data;
+ size_t vOut = vIn;
+
+ //clear all clipping & projected flags
+ const u32 flag = v0[0].flag & VERTEX4D_FORMAT_MASK;
+ for (size_t g = 0; g != Clipper.ElementSize; ++g)
+ {
+ v0[g].flag = flag;
+ v1[g].flag = flag;
+ }
+
+#if 0
+ for (size_t i = 0; i < 6; ++i)
+ {
+ v0 = i & 1 ? Clipper_temp.data : Clipper.data;
+ v1 = i & 1 ? Clipper.data : Clipper_temp.data;
+
+ //clipMask checked outside - always clip all planes
+#if 0
+ if (0 == (clipMask & ((size_t)1<<i)))
+ {
+ vOut = vIn;
+ memcpy_s4DVertexPair(v1, v0);
+ }
+ else
+#endif
+ {
+ vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[i]);
+ if (vOut < vIn) return vOut;
+ }
+ }
+#endif
+
+
+ vOut = clipToHyperPlane( v1, v0, vOut, NDCPlane[0] ); if ( vOut < vIn) return vOut;
+ vOut = clipToHyperPlane( v0, v1, vOut, NDCPlane[1] ); if ( vOut < vIn ) return vOut;
+ vOut = clipToHyperPlane( v1, v0, vOut, NDCPlane[2] ); if ( vOut < vIn ) return vOut;
+ vOut = clipToHyperPlane( v0, v1, vOut, NDCPlane[3] ); if ( vOut < vIn ) return vOut;
+ vOut = clipToHyperPlane( v1, v0, vOut, NDCPlane[4] ); if ( vOut < vIn ) return vOut;
+ vOut = clipToHyperPlane( v0, v1, vOut, NDCPlane[5] );
- vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[0] ); if ( vOut < vIn ) return vOut;
- vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[1] ); if ( vOut < vIn ) return vOut;
- vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[2] ); if ( vOut < vIn ) return vOut;
- vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[3] ); if ( vOut < vIn ) return vOut;
- vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[4] ); if ( vOut < vIn ) return vOut;
- vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[5] );
return vOut;
}
/*!
Part I:
apply Clip Scale matrix
- From Normalized Device Coordiante ( NDC ) Space to Device Coordinate Space ( DC )
+ From Normalized Device Coordiante ( NDC ) Space to Device Coordinate ( DC ) Space
Part II:
Project homogeneous vector
@@ -682,204 +1102,381 @@ u32 CBurningVideoDriver::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u3
Incoming: ( xw, yw, zw, w, u, v, 1, R, G, B, A )
Outgoing: ( xw/w, yw/w, zw/w, w/w, u/w, v/w, 1/w, R/w, G/w, B/w, A/w )
-
replace w/w by 1/w
*/
-inline void CBurningVideoDriver::ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const
+//aliasing problems! [dest = source + 1]
+inline void CBurningVideoDriver::ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair *source, const size_t vIn ) const
{
- u32 g;
+ const f32* dc = Transformation_ETS_CLIPSCALE[TransformationStack];
- for ( g = 0; g != vIn; g += 2 )
+ for ( size_t g = 0; g != vIn; g += sizeof_s4DVertexPairRel)
{
- if ( (dest[g].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED )
- continue;
-
- dest[g].flag = source[g].flag | VERTEX4D_PROJECTED;
+ //cache doesn't work anymore?
+ //if ( dest[g].flag & VERTEX4D_PROJECTED )
+ // continue;
+ //dest[g].flag = source[g].flag | VERTEX4D_PROJECTED;
- const f32 w = source[g].Pos.w;
- const f32 iw = core::reciprocal ( w );
+ const f32 iw = reciprocal_zero (source[g].Pos.w);
// to device coordinates
- dest[g].Pos.x = iw * ( source[g].Pos.x * Transformation [ ETS_CLIPSCALE ][ 0] + w * Transformation [ ETS_CLIPSCALE ][12] );
- dest[g].Pos.y = iw * ( source[g].Pos.y * Transformation [ ETS_CLIPSCALE ][ 5] + w * Transformation [ ETS_CLIPSCALE ][13] );
+ dest[g].Pos.x = iw * source[g].Pos.x * dc[0] + dc[1];
+ dest[g].Pos.y = iw * source[g].Pos.y * dc[2] + dc[3];
+
+ //burning uses direct Z. for OpenGL it should be -Z,[-1;1] and texture flip
+#if !defined(SOFTWARE_DRIVER_2_USE_WBUFFER) || 1
+ dest[g].Pos.z = -iw * source[g].Pos.z * 0.5f + 0.5f;
+#endif
+ dest[g].Pos.w = iw;
-#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER
- dest[g].Pos.z = iw * source[g].Pos.z;
+// Texture Coordinates will be projected after mipmap selection
+// satisfy write-combiner
+#if 1
+#if BURNING_MATERIAL_MAX_TEXTURES > 0
+ dest[g].Tex[0] = source[g].Tex[0];
+#endif
+#if BURNING_MATERIAL_MAX_TEXTURES > 1
+ dest[g].Tex[1] = source[g].Tex[1];
+#endif
+#if BURNING_MATERIAL_MAX_TEXTURES > 2
+ dest[g].Tex[2] = source[g].Tex[2];
+#endif
+#if BURNING_MATERIAL_MAX_TEXTURES > 3
+ dest[g].Tex[3] = source[g].Tex[3];
#endif
- #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS > 0
#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
- dest[g].Color[0] = source[g].Color[0] * iw;
+ dest[g].Color[0] = source[g].Color[0] * iw; // alpha?
#else
dest[g].Color[0] = source[g].Color[0];
#endif
+#endif
- #endif
+#if BURNING_MATERIAL_MAX_COLORS > 1
+#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+ dest[g].Color[1] = source[g].Color[1] * iw; // alpha?
+#else
+ dest[g].Color[1] = source[g].Color[1];
+#endif
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS > 2
+#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+ dest[g].Color[2] = source[g].Color[2] * iw; // alpha?
+#else
+ dest[g].Color[2] = source[g].Color[2];
+#endif
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS > 3
+#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+ dest[g].Color[3] = source[g].Color[3] * iw; // alpha?
+#else
+ dest[g].Color[3] = source[g].Color[3];
+#endif
+#endif
+
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
dest[g].LightTangent[0] = source[g].LightTangent[0] * iw;
- dest[g].Pos.w = iw;
+#endif
+
}
}
-inline void CBurningVideoDriver::ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const
+
+/*!
+ crossproduct in projected 2D, face
+*/
+REALINLINE f32 CBurningVideoDriver::screenarea_inside(const s4DVertexPair* burning_restrict const face[] ) const
{
- u32 g;
+ return ( ((face[1]+1)->Pos.x - (face[0]+1)->Pos.x) * ((face[2]+1)->Pos.y - (face[0]+1)->Pos.y) ) -
+ ( ((face[2]+1)->Pos.x - (face[0]+1)->Pos.x) * ((face[1]+1)->Pos.y - (face[0]+1)->Pos.y) );
+/*
+ float signedArea = 0;
+ for (int k = 1; k < output->count; k++) {
+ signedArea += (output->vertices[k - 1].values[0] * output->vertices[k - 0].values[1]);
+ signedArea -= (output->vertices[k - 0].values[0] * output->vertices[k - 1].values[1]);
+ }
+*/
+}
- for ( g = 0; g != size; g += 1 )
- {
- s4DVertex * a = (s4DVertex*) v[g];
+#if 0
+static inline f32 dot(const sVec2& a,const sVec2& b) { return a.x * b.x + a.y * b.y; }
+sVec2 dFdx(const sVec2& v) { return v; }
+sVec2 dFdy(const sVec2& v) { return v; }
- if ( (a[1].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED )
- continue;
+f32 MipmapLevel(const sVec2& uv, const sVec2& textureSize)
+{
+ sVec2 dx = dFdx(uv * textureSize.x);
+ sVec2 dy = dFdy(uv * textureSize.y);
+ f32 d = core::max_(dot(dx, dx), dot(dy, dy));
+ return log2f(sqrtf(d));
+}
+#endif
- a[1].flag = a->flag | VERTEX4D_PROJECTED;
+#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( (u32)tex ) )
- // project homogenous vertex, store 1/w
- const f32 w = a->Pos.w;
- const f32 iw = core::reciprocal ( w );
+/*!
+ calculate from unprojected.
+ attribute need not to follow winding rule from position.
+ Edge-walking problem
+ Texture Wrapping problem
+ Atlas problem
+*/
+REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burning_restrict const face[],
+ const size_t m, f32 dc_area, f32 lod_bias) const
+{
+ /*
+ sVec2 a(v[1]->Tex[tex].x - v[0]->Tex[tex].x,v[1]->Tex[tex].y - v[0]->Tex[tex].y);
+ sVec2 b(v[2]->Tex[tex].x - v[0]->Tex[tex].x,v[2]->Tex[tex].y - v[0]->Tex[tex].y);
+ f32 area = a.x * b.y - b.x * a.y;
+ */
- // to device coordinates
- const f32 * p = Transformation [ ETS_CLIPSCALE ].pointer();
- a[1].Pos.x = iw * ( a->Pos.x * p[ 0] + w * p[12] );
- a[1].Pos.y = iw * ( a->Pos.y * p[ 5] + w * p[13] );
-#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER
- a[1].Pos.z = a->Pos.z * iw;
-#endif
+ /*
+ degenerate(A, B, C, minarea) = ((B - A).cross(C - A)).lengthSquared() < (4.0f * minarea * minarea);
+ check for collapsed or "long thin triangles"
+ */
+ ieee754 signedArea;
- #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
- #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
- a[1].Color[0] = a->Color[0] * iw;
- #else
- a[1].Color[0] = a->Color[0];
- #endif
- #endif
+ ieee754 t[4];
+ t[0].f = face[1]->Tex[m].x - face[0]->Tex[m].x;
+ t[1].f = face[1]->Tex[m].y - face[0]->Tex[m].y;
- a[1].LightTangent[0] = a[0].LightTangent[0] * iw;
- a[1].Pos.w = iw;
+ t[2].f = face[2]->Tex[m].x - face[0]->Tex[m].x;
+ t[3].f = face[2]->Tex[m].y - face[0]->Tex[m].y;
- }
+ //crossproduct in projected 2D -> screen area triangle
+ signedArea.f = t[0].f * t[3].f - t[2].f * t[1].f;
-}
+ //signedArea =
+ // ((face[1]->Tex[m].x - face[0]->Tex[m].x) * (face[2]->Tex[m].y - face[0]->Tex[m].y))
+ // - ((face[2]->Tex[m].x - face[0]->Tex[m].x) * (face[1]->Tex[m].y - face[0]->Tex[m].y));
+ //if (signedArea*signedArea <= 0.00000000001f)
+ if (signedArea.fields.exp == 0 )
+ {
+ ieee754 _max;
+ _max.u = t[0].abs.frac_exp;
+ if (t[1].abs.frac_exp > _max.u) _max.u = t[1].abs.frac_exp;
+ if (t[2].abs.frac_exp > _max.u) _max.u = t[2].abs.frac_exp;
+ if (t[3].abs.frac_exp > _max.u) _max.u = t[3].abs.frac_exp;
-/*!
- crossproduct in projected 2D -> screen area triangle
+ signedArea.u = _max.fields.exp ? _max.u : ieee754_one;
+
+/*
+ //dot,length
+ ieee754 v[2];
+ v[0].f = t[0] * t[2];
+ v[1].f = t[1] * t[3];
+
+ //signedArea.f = t[4] > t[5] ? t[4] : t[5];
+ signedArea.u = v[0].fields.frac > v[1].fields.frac ? v[0].u : v[1].u;
+ if (signedArea.fields.exp == 0)
+ {
+ return -1;
+ }
*/
-inline f32 CBurningVideoDriver::screenarea ( const s4DVertex *v ) const
-{
- return ( ( v[3].Pos.x - v[1].Pos.x ) * ( v[5].Pos.y - v[1].Pos.y ) ) -
- ( ( v[3].Pos.y - v[1].Pos.y ) * ( v[5].Pos.x - v[1].Pos.x ) );
-}
+ }
+ //only guessing: take more detail (lower mipmap) in light+bump textures
+ //assume transparent add is ~50% transparent -> more detail
+ const u32* d = MAT_TEXTURE(m)->getMipMap0_Area();
+ f32 texelspace = d[0] * d[1] * lod_bias; //(m ? 0.5f : 0.5f);
-/*!
-*/
-inline f32 CBurningVideoDriver::texelarea ( const s4DVertex *v, int tex ) const
-{
- f32 z;
+ ieee754 ratio;
+ ratio.f = (signedArea.f * texelspace) * dc_area;
+ ratio.fields.sign = 0;
- z = ( (v[2].Tex[tex].x - v[0].Tex[tex].x ) * (v[4].Tex[tex].y - v[0].Tex[tex].y ) )
- - ( (v[4].Tex[tex].x - v[0].Tex[tex].x ) * (v[2].Tex[tex].y - v[0].Tex[tex].y ) );
+ //log2(0)==denormal [ use high lod] [ only if dc_area == 0 checked outside ]
+#if 0
+ if (ratio.fields.exp == 0)
+ {
+ int g = 1;
+ }
+#endif
+ //log2
+ return (ratio.fields.exp & 0x80) ? ratio.fields.exp - 127 : 0; /*denormal very high lod*/
- return MAT_TEXTURE ( tex )->getLODFactor ( z );
-}
+ //return (ratio.f <= 1.f) ? 0 : 1;
+ //f32 texArea = MAT_TEXTURE(m)->getLODFactor(signedArea); // texelarea_inside(face, m);
+ //s32 lodFactor = s32_log2_f32(texArea * dc_area); /* avoid denorm */
-/*!
- crossproduct in projected 2D
-*/
-inline f32 CBurningVideoDriver::screenarea2 ( const s4DVertex **v ) const
-{
- return ( (( v[1] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) * ( (v[2] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) ) -
- ( (( v[1] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) * ( (v[2] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) );
+ //return MAT_TEXTURE(m)->getLODFactor(signedArea);
}
+
/*!
+ texcoo in current mipmap dimension (face, already clipped)
+ -> want to help fixpoint
*/
-inline f32 CBurningVideoDriver::texelarea2 ( const s4DVertex **v, s32 tex ) const
+inline void CBurningVideoDriver::select_polygon_mipmap_inside(s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b) const
{
- f32 z;
- z = ( (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[2]->Tex[tex].y - v[0]->Tex[tex].y ) )
- - ( (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[1]->Tex[tex].y - v[0]->Tex[tex].y ) );
+#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+#if defined(Tweak_Burning)
+ (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);
+ (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);
+
+ (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);
+ (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);
+
+ (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);
+ (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);
+#else
+ (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * (face[0] + 1)->Pos.w * b.w + b.cx;
+ (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * (face[0] + 1)->Pos.w * b.h + b.cy;
+
+ (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * (face[1] + 1)->Pos.w * b.w + b.cx;
+ (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * (face[1] + 1)->Pos.w * b.h + b.cy;
+
+ (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * (face[2] + 1)->Pos.w * b.w + b.cx;
+ (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * (face[2] + 1)->Pos.w * b.h + b.cy;
+#endif
+#else
+ (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * b.w;
+ (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * b.h;
+
+ (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * b.w;
+ (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * b.h;
+
+ (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * b.w;
+ (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * b.h;
+#endif
- return MAT_TEXTURE ( tex )->getLODFactor ( z );
}
-/*!
-*/
-inline void CBurningVideoDriver::select_polygon_mipmap ( s4DVertex *v, u32 vIn, u32 tex, const core::dimension2du& texSize ) const
+// Vertex Cache
+
+//! setup Vertex Format
+void CBurningVideoDriver::VertexCache_map_source_format()
{
- f32 f[2];
+ u32 s0 = sizeof(s4DVertex);
+ u32 s1 = sizeof(s4DVertex_proxy);
- f[0] = (f32) texSize.Width - 0.25f;
- f[1] = (f32) texSize.Height - 0.25f;
+ if ( s1 <= sizeof_s4DVertex /2 )
+ {
+ os::Printer::log ( "BurningVideo vertex format unnecessary to large", ELL_WARNING );
+ }
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
- for ( u32 g = 0; g != vIn; g += 2 )
+ //memcpy_vertex
+ if ( s0 != sizeof_s4DVertex || ((sizeof_s4DVertex * sizeof_s4DVertexPairRel)&31))
{
- (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * ( v + g + 1 )->Pos.w * f[0];
- (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * ( v + g + 1 )->Pos.w * f[1];
+ os::Printer::log ( "BurningVideo vertex format compile problem", ELL_ERROR );
+ _IRR_DEBUG_BREAK_IF(1);
}
-#else
- for ( u32 g = 0; g != vIn; g += 2 )
+
+#if defined(ENV64BIT)
+ if (sizeof(void*) != 8)
{
- (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * f[0];
- (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * f[1];
+ os::Printer::log("BurningVideo pointer should be 8 bytes", ELL_ERROR);
+ _IRR_DEBUG_BREAK_IF(1);
}
#endif
-}
-inline void CBurningVideoDriver::select_polygon_mipmap2 ( s4DVertex **v, u32 tex, const core::dimension2du& texSize ) const
-{
- f32 f[2];
+ SVSize* vSize = VertexCache.vSize;
+ //vSize[E4VT_STANDARD].Format = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_SPECULAR;
+ vSize[E4VT_STANDARD].Format = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_2_FOG;
+ vSize[E4VT_STANDARD].Pitch = sizeof(S3DVertex);
+ vSize[E4VT_STANDARD].TexSize = 1;
+ vSize[E4VT_STANDARD].TexCooSize = 1;
+
+ vSize[E4VT_2TCOORDS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1;
+ vSize[E4VT_2TCOORDS].Pitch = sizeof(S3DVertex2TCoords);
+ vSize[E4VT_2TCOORDS].TexSize = 2;
+ vSize[E4VT_2TCOORDS].TexCooSize = 2;
+
+ //vSize[E4VT_TANGENTS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_BUMP_DOT3;
+ vSize[E4VT_TANGENTS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_2_FOG | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_BUMP_DOT3;
+ vSize[E4VT_TANGENTS].Pitch = sizeof(S3DVertexTangents);
+ vSize[E4VT_TANGENTS].TexSize = 2;
+ vSize[E4VT_TANGENTS].TexCooSize = 2;
+
+ // reflection map
+ vSize[E4VT_REFLECTION_MAP].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1;
+ vSize[E4VT_REFLECTION_MAP].Pitch = sizeof(S3DVertex);
+ vSize[E4VT_REFLECTION_MAP].TexSize = 2;
+ vSize[E4VT_REFLECTION_MAP].TexCooSize = 1; //TexCoo2 generated
+
+ // shadow
+ vSize[E4VT_SHADOW].Format = 0;
+ vSize[E4VT_SHADOW].Pitch = sizeof(f32) * 3; // core::vector3df*
+ vSize[E4VT_SHADOW].TexSize = 0;
+ vSize[E4VT_SHADOW].TexCooSize = 0;
+
+ // color shading only (no texture)
+ vSize[E4VT_NO_TEXTURE].Format = VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_SPECULAR;
+ vSize[E4VT_NO_TEXTURE].Pitch = sizeof(S3DVertex);
+ vSize[E4VT_NO_TEXTURE].TexSize = 0;
+ vSize[E4VT_NO_TEXTURE].TexCooSize = 0;
+
+ //Line
+ vSize[E4VT_LINE].Format = VERTEX4D_FORMAT_COLOR_1;
+ vSize[E4VT_LINE].Pitch = sizeof(S3DVertex);
+ vSize[E4VT_LINE].TexSize = 0;
+ vSize[E4VT_LINE].TexCooSize = 0;
+
+ size_t size;
+ for ( size_t i = 0; i < E4VT_COUNT; ++i )
+ {
+ size_t& flag = vSize[i].Format;
- f[0] = (f32) texSize.Width - 0.25f;
- f[1] = (f32) texSize.Height - 0.25f;
+#if !defined(SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR)
+ flag &= ~VERTEX4D_FORMAT_SPECULAR;
+#endif
+ if ( vSize[i].TexSize > BURNING_MATERIAL_MAX_TEXTURES )
+ vSize[i].TexSize = BURNING_MATERIAL_MAX_TEXTURES;
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
- (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * ( v[0] + 1 )->Pos.w * f[0];
- (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * ( v[0] + 1 )->Pos.w * f[1];
+ size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;
+ if ( size > BURNING_MATERIAL_MAX_TEXTURES )
+ {
+ flag = (flag & ~VERTEX4D_FORMAT_MASK_TEXTURE) | (BURNING_MATERIAL_MAX_TEXTURES << 16);
+ }
- (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * ( v[1] + 1 )->Pos.w * f[0];
- (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * ( v[1] + 1 )->Pos.w * f[1];
+ size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;
+ if ( size > BURNING_MATERIAL_MAX_COLORS )
+ {
+ flag = (flag & ~VERTEX4D_FORMAT_MASK_COLOR) | (BURNING_MATERIAL_MAX_COLORS << 20);
+ }
- (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * ( v[2] + 1 )->Pos.w * f[0];
- (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * ( v[2] + 1 )->Pos.w * f[1];
+ size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24;
+ if ( size > BURNING_MATERIAL_MAX_LIGHT_TANGENT)
+ {
+ flag = (flag & ~VERTEX4D_FORMAT_MASK_LIGHT) | (BURNING_MATERIAL_MAX_LIGHT_TANGENT << 24);
+ }
+ }
-#else
- (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * f[0];
- (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * f[1];
+ VertexCache.mem.resize(VERTEXCACHE_ELEMENT * 2);
+ VertexCache.vType = E4VT_STANDARD;
- (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * f[0];
- (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * f[1];
+ Clipper.resize(VERTEXCACHE_ELEMENT * 2);
+ Clipper_temp.resize(VERTEXCACHE_ELEMENT * 2);
- (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * f[0];
- (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * f[1];
-#endif
-}
+ TransformationStack = 0;
+ memset(TransformationFlag, 0, sizeof(TransformationFlag));
+ memset(Transformation_ETS_CLIPSCALE, 0, sizeof(Transformation_ETS_CLIPSCALE));
+
+ Material.resetRenderStates = true;
+ Material.Fallback_MaterialType = EMT_SOLID;
-// Vertex Cache
-const SVSize CBurningVideoDriver::vSize[] =
-{
- { VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 1 },
- { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex2TCoords),2 },
- { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_BUMP_DOT3, sizeof(S3DVertexTangents),2 },
- { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 2 }, // reflection map
- { 0, sizeof(f32) * 3, 0 }, // core::vector3df*
-};
+
+}
/*!
- fill a cache line with transformed, light and clipp test triangles
+ fill a cache line with transformed, light and clip test triangles
+ overhead - if primitive is outside or culled, vertexLighting and TextureTransform is still done
*/
void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex)
{
- u8 * source;
- s4DVertex *dest;
+ u8* burning_restrict source;
+ s4DVertex* burning_restrict dest;
- source = (u8*) VertexCache.vertices + ( sourceIndex * vSize[VertexCache.vType].Pitch );
+ source = (u8*) VertexCache.vertices + ( sourceIndex * VertexCache.vSize[VertexCache.vType].Pitch );
// it's a look ahead so we never hit it..
// but give priority...
@@ -890,71 +1487,233 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
VertexCache.info[ destIndex ].hit = 0;
// destination Vertex
- dest = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( destIndex << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );
+ dest = VertexCache.mem.data + s4DVertex_ofs(destIndex);
+
+ //Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents
+ const S3DVertex* base = ((S3DVertex*)source);
// transform Model * World * Camera * Projection * NDCSpace matrix
- const S3DVertex *base = ((S3DVertex*) source );
- Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, base->Pos );
+ const core::matrix4* matrix = Transformation[TransformationStack];
+ matrix[ETS_PROJ_MODEL_VIEW].transformVect(&dest->Pos.x, base->Pos);
+
+ //mhm ... maybe no goto
+ if (VertexCache.vType == E4VT_SHADOW)
+ {
+ //core::vector3df i = base->Pos;
+ //i.Z -= 0.5f;
+ //matrix[ETS_PROJ_MODEL_VIEW].transformVect(&dest->Pos.x, i);
- //mhm ;-) maybe no goto
- if ( VertexCache.vType == 4 ) goto clipandproject;
+ //GL_DEPTH_CLAMP,EVDF_DEPTH_CLAMP
+ //if ( dest->Pos.z < dest->Pos.w)
+ // dest->Pos.z = dest->Pos.w*0.99f;
+
+ //glPolygonOffset // self shadow wanted or not?
+ dest->Pos.w *= 1.005f;
+
+ //flag |= v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_NEAR : 0;
+ //flag |= -v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_FAR : 0;
+
+ goto clipandproject;
+ }
#if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )
- // vertex normal in light space
- if ( Material.org.Lighting || (LightSpace.Flags & VERTEXTRANSFORM) )
+ // vertex, normal in light(eye) space
+ if ( Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM|TL_FOG)) )
{
- if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY )
- {
- LightSpace.normal.set ( base->Normal.X, base->Normal.Y, base->Normal.Z, 1.f );
- LightSpace.vertex.set ( base->Pos.X, base->Pos.Y, base->Pos.Z, 1.f );
- }
- else
- {
- Transformation[ETS_WORLD].rotateVect ( &LightSpace.normal.x, base->Normal );
+ sVec4 vertex4; //eye coordinate position of vertex
+ matrix[ETS_MODEL_VIEW].transformVect ( &vertex4.x, base->Pos );
- // vertex in light space
- if ( LightSpace.Flags & ( POINTLIGHT | FOG | SPECULAR | VERTEXTRANSFORM) )
- Transformation[ETS_WORLD].transformVect ( &LightSpace.vertex.x, base->Pos );
- }
+ f32 iw = reciprocal_zero(vertex4.w);
+ EyeSpace.vertex.x = vertex4.x * iw;
+ EyeSpace.vertex.y = vertex4.y * iw;
+ EyeSpace.vertex.z = vertex4.z * iw;
+ EyeSpace.vertex.w = iw;
- if ( LightSpace.Flags & NORMALIZE )
- LightSpace.normal.normalize_xyz();
+ //EyeSpace.cam_distance = EyeSpace.vertex.length_xyz();
+ EyeSpace.cam_dir = EyeSpace.vertex;
+ EyeSpace.cam_dir.normalize_dir_xyz();
+
+ matrix[ETS_NORMAL].rotateVect(&EyeSpace.normal.x, base->Normal);
+ if (EyeSpace.TL_Flag & TL_NORMALIZE_NORMALS)
+ EyeSpace.normal.normalize_dir_xyz();
}
#endif
-#if defined ( SOFTWARE_DRIVER_2_USE_VERTEX_COLOR )
- // apply lighting model
- #if defined (SOFTWARE_DRIVER_2_LIGHTING)
- if ( Material.org.Lighting )
- {
- lightVertex ( dest, base->Color.color );
- }
- else
- {
- dest->Color[0].setA8R8G8B8 ( base->Color.color );
- }
- #else
+#if BURNING_MATERIAL_MAX_COLORS > 1
+ dest->Color[1].a = 1.f;
+ dest->Color[1].r = 0.f;
+ dest->Color[1].g = 0.f;
+ dest->Color[1].b = 0.f;
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS > 2
+ dest->Color[2].a = 1.f;
+ dest->Color[2].r = 0.f;
+ dest->Color[2].g = 0.f;
+ dest->Color[2].b = 0.f;
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS > 3
+ dest->Color[3].a = 1.f;
+ dest->Color[3].r = 0.f;
+ dest->Color[3].g = 0.f;
+ dest->Color[3].b = 0.f;
+#endif
+
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
+ dest->LightTangent[0].x = 0.f;
+ dest->LightTangent[0].y = 0.f;
+ dest->LightTangent[0].z = 0.f;
+#endif
+
+
+#if BURNING_MATERIAL_MAX_COLORS > 0
+// apply lighting model
+#if defined (SOFTWARE_DRIVER_2_LIGHTING)
+ if ( Material.org.Lighting )
+ {
+ lightVertex_eye ( dest, base->Color.color );
+ }
+ else
+ {
dest->Color[0].setA8R8G8B8 ( base->Color.color );
- #endif
+ }
+#else
+ dest->Color[0].setA8R8G8B8 ( base->Color.color );
+#endif
#endif
+ //vertex fog
+ if (EyeSpace.TL_Flag & TL_FOG ) //Material.org.FogEnable
+ {
+ f32 fog_factor = 1.f;
+
+ // GL_FRAGMENT_DEPTH -> abs(EyeSpace.vertex.z)
+ ieee754 fog_frag_coord;
+ fog_frag_coord.f = EyeSpace.vertex.z;
+ fog_frag_coord.fields.sign = 0;
+
+ switch (FogType)
+ {
+ case EFT_FOG_LINEAR:
+ fog_factor = (FogEnd - fog_frag_coord.f) * EyeSpace.fog_scale;
+ break;
+ case EFT_FOG_EXP:
+ fog_factor = (f32)exp(-FogDensity * fog_frag_coord.f);
+ break;
+ case EFT_FOG_EXP2:
+ fog_factor = (f32)exp(-FogDensity * FogDensity * fog_frag_coord.f * fog_frag_coord.f);
+ break;
+ }
+
+ sVec4* a = dest->Color + ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG) ? 1 : 0);
+ a->a = core::clamp(fog_factor, 0.f, 1.f);
+ }
+
// Texture Transform
-#if !defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )
- irr::memcpy32_small ( &dest->Tex[0],&base->TCoords,
- vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 )
- );
-#else
+#if defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )
- if ( 0 == (LightSpace.Flags & VERTEXTRANSFORM) )
+ if ( 0 == (EyeSpace.TL_Flag & TL_TEXTURE_TRANSFORM) )
+#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
{
- irr::memcpy32_small ( &dest->Tex[0],&base->TCoords,
- vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 )
- );
+ // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address!
+ const f32* baseTCoord = &base->TCoords.X;
+
+ switch (VertexCache.vSize[VertexCache.vType].TexCooSize)
+ {
+#if BURNING_MATERIAL_MAX_TEXTURES == 4
+ case 0:
+ dest->Tex[0].x = 0.f;
+ dest->Tex[0].y = 0.f;
+ dest->Tex[1].x = 0.f;
+ dest->Tex[1].y = 0.f;
+ dest->Tex[2].x = 0.f;
+ dest->Tex[2].y = 0.f;
+ dest->Tex[3].x = 0.f;
+ dest->Tex[3].y = 0.f;
+ break;
+ case 1:
+ dest->Tex[0].x = baseTCoord[0];
+ dest->Tex[0].y = baseTCoord[1];
+ dest->Tex[1].x = 0.f;
+ dest->Tex[1].y = 0.f;
+ dest->Tex[2].x = 0.f;
+ dest->Tex[2].y = 0.f;
+ dest->Tex[3].x = 0.f;
+ dest->Tex[3].y = 0.f;
+ break;
+ case 2:
+ dest->Tex[0].x = baseTCoord[0];
+ dest->Tex[0].y = baseTCoord[1];
+ dest->Tex[1].x = baseTCoord[2];
+ dest->Tex[1].y = baseTCoord[3];
+ dest->Tex[2].x = 0.f;
+ dest->Tex[2].y = 0.f;
+ dest->Tex[3].x = 0.f;
+ dest->Tex[3].y = 0.f;
+ break;
+ case 3:
+ dest->Tex[0].x = baseTCoord[0];
+ dest->Tex[0].y = baseTCoord[1];
+ dest->Tex[1].x = baseTCoord[2];
+ dest->Tex[1].y = baseTCoord[3];
+ dest->Tex[2].x = baseTCoord[4];
+ dest->Tex[2].y = baseTCoord[5];
+ dest->Tex[3].x = 0.f;
+ dest->Tex[3].y = 0.f;
+ break;
+ case 4:
+ dest->Tex[0].x = baseTCoord[0];
+ dest->Tex[0].y = baseTCoord[1];
+ dest->Tex[1].x = baseTCoord[2];
+ dest->Tex[1].y = baseTCoord[3];
+ dest->Tex[2].x = baseTCoord[4];
+ dest->Tex[2].y = baseTCoord[5];
+ dest->Tex[3].x = baseTCoord[6];
+ dest->Tex[3].y = baseTCoord[7];
+ break;
+#endif
+
+#if BURNING_MATERIAL_MAX_TEXTURES == 2
+ case 0:
+ dest->Tex[0].x = 0.f;
+ dest->Tex[0].y = 0.f;
+ dest->Tex[1].x = 0.f;
+ dest->Tex[1].y = 0.f;
+ break;
+
+ case 1:
+ dest->Tex[0].x = baseTCoord[0];
+ dest->Tex[0].y = baseTCoord[1];
+ dest->Tex[1].x = 0.f;
+ dest->Tex[1].y = 0.f;
+ break;
+ case 2:
+ dest->Tex[0].x = baseTCoord[0];
+ dest->Tex[0].y = baseTCoord[1];
+ dest->Tex[1].x = baseTCoord[2];
+ dest->Tex[1].y = baseTCoord[3];
+ break;
+#endif
+#if BURNING_MATERIAL_MAX_TEXTURES == 1
+ case 0:
+ dest->Tex[0].x = 0.f;
+ dest->Tex[0].y = 0.f;
+ break;
+ case 1:
+ dest->Tex[0].x = baseTCoord[0];
+ dest->Tex[0].y = baseTCoord[1];
+ break;
+#endif
+ default:
+ break;
+ }
}
+#if defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )
else
{
/*
@@ -968,222 +1727,195 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
Uw Vw 0 0
*/
- u32 t;
- sVec4 n;
- sVec2 srcT;
+ const sVec4& u = EyeSpace.cam_dir; // EyeSpace.vertex.normalized
+ const sVec4& n = EyeSpace.normal;
+ sVec4 r;
- for ( t = 0; t != vSize[VertexCache.vType].TexSize; ++t )
+ const size_t* flag = TransformationFlag[TransformationStack];
+ for ( u32 t = 0; t != VertexCache.vSize[VertexCache.vType].TexSize; ++t )
{
- const core::matrix4& M = Transformation [ ETS_TEXTURE_0 + t ];
-
// texgen
- if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & (ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION) )
+ if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_SPHERE )
{
- n.x = LightSpace.campos.x - LightSpace.vertex.x;
- n.y = LightSpace.campos.x - LightSpace.vertex.y;
- n.z = LightSpace.campos.x - LightSpace.vertex.z;
- n.normalize_xyz();
- n.x += LightSpace.normal.x;
- n.y += LightSpace.normal.y;
- n.z += LightSpace.normal.z;
- n.normalize_xyz();
-
- const f32 *view = Transformation[ETS_VIEW].pointer();
-
- if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & ETF_TEXGEN_CAMERA_REFLECTION )
- {
- srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[4] + n.z * view[8] ));
- srcT.y = 0.5f * ( 1.f + (n.x * view[1] + n.y * view[5] + n.z * view[9] ));
- }
- else
- {
- srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[1] + n.z * view[2] ));
- srcT.y = 0.5f * ( 1.f + (n.x * view[4] + n.y * view[5] + n.z * view[6] ));
- }
+ //reflect(u,N) u - 2.0 * dot(N, u) * N
+ // cam is (0,0,-1), tex flipped
+ f32 dot = -2.f * n.dot_xyz(u);
+ r.x = u.x + dot * n.x;
+ r.y = u.y + dot * n.y;
+ r.z = u.z + dot * n.z;
+
+ //openGL
+ f32 m = 2.f * sqrtf(r.x*r.x+r.y*r.y+(r.z+1.f)*(r.z+1.f));
+ dest[0].Tex[t].x = r.x / m + 0.5f;
+ dest[0].Tex[t].y = -r.y / m + 0.5f;
+
+/*
+ //~d3d with spheremap scale
+ f32 m = 0.25f / (0.00001f + sqrtf(r.x*r.x+r.y*r.y+r.z*r.z));
+ dest[0].Tex[t].x = r.x * m + 0.5f;
+ dest[0].Tex[t].y = -r.y * m + 0.5f;
+*/
}
- else
+ else if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_REFLECTION )
{
- irr::memcpy32_small ( &srcT,(&base->TCoords) + t,
- sizeof ( f32 ) * 2 );
+ //reflect(u,N) u - 2.0 * dot(N, u) * N
+ // cam is (0,0,-1), tex flipped
+ f32 dot = -2.f * n.dot_xyz(u);
+ r.x = u.x + dot * n.x;
+ r.y = u.y + dot * n.y;
+ r.z = u.z + dot * n.z;
+
+ //openGL
+ dest[0].Tex[t].x = r.x;
+ dest[0].Tex[t].y = -r.y;
+/*
+ //~d3d with spheremap scale
+ dest[0].Tex[t].x = r.x;
+ dest[0].Tex[t].y = r.y;
+*/
}
-
- switch ( Material.org.TextureLayer[t].TextureWrapU )
+ else if (VertexCache.vSize[VertexCache.vType].TexCooSize > t)
{
- case ETC_CLAMP:
- case ETC_CLAMP_TO_EDGE:
- case ETC_CLAMP_TO_BORDER:
- dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );
+ const f32* M = matrix[ETS_TEXTURE_0 + t].pointer();
+
+ // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address!
+ const f32* baseTCoord = &base->TCoords.X;
+
+ sVec4 srcT;
+ srcT.x = baseTCoord[(t * 2) + 0];
+ srcT.y = baseTCoord[(t * 2) + 1];
+
+ switch ( Material.org.TextureLayer[t].TextureWrapU )
+ {
+ case ETC_CLAMP:
+ case ETC_CLAMP_TO_EDGE:
+ case ETC_CLAMP_TO_BORDER:
+ dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );
+ break;
+ case ETC_MIRROR:
+ dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];
+ if (core::fract(dest->Tex[t].x)>0.5f)
+ dest->Tex[t].x=1.f-dest->Tex[t].x;
break;
- case ETC_MIRROR:
- dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];
- if (core::fract(dest->Tex[t].x)>0.5f)
- dest->Tex[t].x=1.f-dest->Tex[t].x;
- break;
- case ETC_MIRROR_CLAMP:
- case ETC_MIRROR_CLAMP_TO_EDGE:
- case ETC_MIRROR_CLAMP_TO_BORDER:
- dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );
- if (core::fract(dest->Tex[t].x)>0.5f)
- dest->Tex[t].x=1.f-dest->Tex[t].x;
- break;
- case ETC_REPEAT:
- default:
- dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];
+ case ETC_MIRROR_CLAMP:
+ case ETC_MIRROR_CLAMP_TO_EDGE:
+ case ETC_MIRROR_CLAMP_TO_BORDER:
+ dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );
+ if (core::fract(dest->Tex[t].x)>0.5f)
+ dest->Tex[t].x=1.f-dest->Tex[t].x;
break;
- }
- switch ( Material.org.TextureLayer[t].TextureWrapV )
- {
- case ETC_CLAMP:
- case ETC_CLAMP_TO_EDGE:
- case ETC_CLAMP_TO_BORDER:
- dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );
+ case ETC_REPEAT:
+ default:
+ dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];
+ break;
+ }
+ switch ( Material.org.TextureLayer[t].TextureWrapV )
+ {
+ case ETC_CLAMP:
+ case ETC_CLAMP_TO_EDGE:
+ case ETC_CLAMP_TO_BORDER:
+ dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );
+ break;
+ case ETC_MIRROR:
+ dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];
+ if (core::fract(dest->Tex[t].y)>0.5f)
+ dest->Tex[t].y=1.f-dest->Tex[t].y;
break;
- case ETC_MIRROR:
- dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];
- if (core::fract(dest->Tex[t].y)>0.5f)
- dest->Tex[t].y=1.f-dest->Tex[t].y;
- break;
- case ETC_MIRROR_CLAMP:
- case ETC_MIRROR_CLAMP_TO_EDGE:
- case ETC_MIRROR_CLAMP_TO_BORDER:
- dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );
- if (core::fract(dest->Tex[t].y)>0.5f)
- dest->Tex[t].y=1.f-dest->Tex[t].y;
- break;
- case ETC_REPEAT:
- default:
- dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];
+ case ETC_MIRROR_CLAMP:
+ case ETC_MIRROR_CLAMP_TO_EDGE:
+ case ETC_MIRROR_CLAMP_TO_BORDER:
+ dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );
+ if (core::fract(dest->Tex[t].y)>0.5f)
+ dest->Tex[t].y=1.f-dest->Tex[t].y;
break;
+ case ETC_REPEAT:
+ default:
+ dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];
+ break;
+ }
}
}
}
-#if 0
- // tangent space light vector, emboss
- if ( Lights.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) )
- {
- const S3DVertexTangents *tangent = ((S3DVertexTangents*) source );
- const SBurningShaderLight &light = LightSpace.Light[0];
-
- sVec4 vp;
-
- vp.x = light.pos.x - LightSpace.vertex.x;
- vp.y = light.pos.y - LightSpace.vertex.y;
- vp.z = light.pos.z - LightSpace.vertex.z;
-
- vp.normalize_xyz();
-
- LightSpace.tangent.x = vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z;
- LightSpace.tangent.y = vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z;
- //LightSpace.tangent.z = vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z;
- LightSpace.tangent.z = 0.f;
- LightSpace.tangent.normalize_xyz();
-
- f32 scale = 1.f / 128.f;
- if ( Material.org.MaterialTypeParam > 0.f )
- scale = Material.org.MaterialTypeParam;
-
- // emboss, shift coordinates
- dest->Tex[1].x = dest->Tex[0].x + LightSpace.tangent.x * scale;
- dest->Tex[1].y = dest->Tex[0].y + LightSpace.tangent.y * scale;
- //dest->Tex[1].z = LightSpace.tangent.z * scale;
- }
-#endif
- if ( LightSpace.Light.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) )
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
+ if ((EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) &&
+ ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_MASK_TANGENT) == VERTEX4D_FORMAT_BUMP_DOT3)
+ )
{
const S3DVertexTangents *tangent = ((S3DVertexTangents*) source );
sVec4 vp;
-
- dest->LightTangent[0].x = 0.f;
- dest->LightTangent[0].y = 0.f;
- dest->LightTangent[0].z = 0.f;
- for ( u32 i = 0; i < 2 && i < LightSpace.Light.size (); ++i )
+ sVec4 light_accu;
+ light_accu.x = 0.f;
+ light_accu.y = 0.f;
+ light_accu.z = 0.f;
+ light_accu.w = 0.f;
+ for ( u32 i = 0; i < 2 && i < EyeSpace.Light.size (); ++i )
{
- const SBurningShaderLight &light = LightSpace.Light[i];
-
+ const SBurningShaderLight &light = EyeSpace.Light[i];
if ( !light.LightIsOn )
continue;
- vp.x = light.pos.x - LightSpace.vertex.x;
- vp.y = light.pos.y - LightSpace.vertex.y;
- vp.z = light.pos.z - LightSpace.vertex.z;
-
- /*
- vp.x = light.pos_objectspace.x - base->Pos.X;
- vp.y = light.pos_objectspace.y - base->Pos.Y;
- vp.z = light.pos_objectspace.z - base->Pos.Z;
- */
-
- vp.normalize_xyz();
-
+ // lightcolor with standard model
+ // but shader is different. treating light and vertex in same space
+#if 1
+ vp.x = light.pos.x - base->Pos.X;
+ vp.y = light.pos.y - base->Pos.Y;
+ vp.z = light.pos.z - base->Pos.Z;
+#else
+ vp.x = light.pos4.x - EyeSpace.vertex.x;
+ vp.y = light.pos4.y - EyeSpace.vertex.y;
+ vp.z = light.pos4.z - EyeSpace.vertex.z;
+#endif
// transform by tangent matrix
- sVec3 l;
- #if 1
- l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z );
- l.y = (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z );
- l.z = (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z );
- #else
- l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Binormal.X + vp.z * tangent->Normal.X );
- l.y = (vp.x * tangent->Tangent.Y + vp.y * tangent->Binormal.Y + vp.z * tangent->Normal.Y );
- l.z = (vp.x * tangent->Tangent.Z + vp.y * tangent->Binormal.Z + vp.z * tangent->Normal.Z );
- #endif
-
-
- /*
- f32 scale = 1.f / 128.f;
- scale /= dest->LightTangent[0].b;
-
- // emboss, shift coordinates
- dest->Tex[1].x = dest->Tex[0].x + l.r * scale;
- dest->Tex[1].y = dest->Tex[0].y + l.g * scale;
- */
- dest->Tex[1].x = dest->Tex[0].x;
- dest->Tex[1].y = dest->Tex[0].y;
-
- // scale bias
- dest->LightTangent[0].x += l.x;
- dest->LightTangent[0].y += l.y;
- dest->LightTangent[0].z += l.z;
+ light_accu.x += (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z );
+ light_accu.y += (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z );
+ light_accu.z += (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z );
}
- dest->LightTangent[0].setLength ( 0.5f );
- dest->LightTangent[0].x += 0.5f;
- dest->LightTangent[0].y += 0.5f;
- dest->LightTangent[0].z += 0.5f;
- }
+ //normalize [-1,+1] to [0,1] -> obsolete
+ light_accu.normalize_pack_xyz(dest->LightTangent[0],1.f, 0.f);
+ dest->Tex[1].x = dest->Tex[0].x;
+ dest->Tex[1].y = dest->Tex[0].y;
+ }
+ else if (Material.org.Lighting)
+ {
+ //dest->LightTangent[0].x = 0.f;
+ //dest->LightTangent[0].y = 0.f;
+ //dest->LightTangent[0].z = 0.f;
+ }
+#endif //if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
-#endif
+#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
clipandproject:
- dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format;
- // test vertex
- dest[0].flag |= clipToFrustumTest ( dest);
+ // test vertex visible
+ dest[0].flag = (u32) (clipToFrustumTest(dest) | VertexCache.vSize[VertexCache.vType].Format);
+ dest[1].flag = dest[0].flag;
// to DC Space, project homogenous vertex
if ( (dest[0].flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE )
{
- ndc_2_dc_and_project2 ( (const s4DVertex**) &dest, 1 );
+ ndc_2_dc_and_project ( dest+1, dest, s4DVertex_ofs(1));
}
- //return dest;
}
-//
-REALINLINE s4DVertex * CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex )
+//todo: this should return only index
+s4DVertexPair* CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex ) const
{
- for ( s32 i = 0; i < VERTEXCACHE_ELEMENT; ++i )
+ for ( size_t i = 0; i < VERTEXCACHE_ELEMENT; ++i )
{
if ( VertexCache.info[ i ].index == sourceIndex )
{
- return (s4DVertex *) ( (u8*) VertexCache.mem.data + ( i << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );
+ return VertexCache.mem.data + s4DVertex_ofs(i);
}
}
- return 0;
+ return VertexCache.mem.data; //error
}
@@ -1192,24 +1924,29 @@ REALINLINE s4DVertex * CBurningVideoDriver::VertexCache_getVertex ( const u32 so
fill blockwise on the next 16(Cache_Size) unique vertices in indexlist
merge the next 16 vertices with the current
*/
-REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
+void CBurningVideoDriver::VertexCache_get(s4DVertexPair* face[4])
{
- SCacheInfo info[VERTEXCACHE_ELEMENT];
-
// next primitive must be complete in cache
- if ( VertexCache.indicesIndex - VertexCache.indicesRun < 3 &&
+ if ( VertexCache.indicesIndex - VertexCache.indicesRun < VertexCache.primitiveHasVertex &&
VertexCache.indicesIndex < VertexCache.indexCount
)
{
+
+ size_t i;
+ //memset(info, VERTEXCACHE_MISS, sizeof(info));
+ for (i = 0; i != VERTEXCACHE_ELEMENT; ++i)
+ {
+ VertexCache.info_temp[i].hit = VERTEXCACHE_MISS;
+ VertexCache.info_temp[i].index = VERTEXCACHE_MISS;
+ }
+
// rewind to start of primitive
VertexCache.indicesIndex = VertexCache.indicesRun;
- irr::memset32 ( info, VERTEXCACHE_MISS, sizeof ( info ) );
// get the next unique vertices cache line
u32 fillIndex = 0;
u32 dIndex = 0;
- u32 i = 0;
u32 sourceIndex = 0;
while ( VertexCache.indicesIndex < VertexCache.indexCount &&
@@ -1218,13 +1955,14 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
{
switch ( VertexCache.iType )
{
- case 1:
+ case E4IT_16BIT:
sourceIndex = ((u16*)VertexCache.indices) [ VertexCache.indicesIndex ];
break;
- case 2:
+ case E4IT_32BIT:
sourceIndex = ((u32*)VertexCache.indices) [ VertexCache.indicesIndex ];
break;
- case 4:
+ default:
+ case E4IT_NONE:
sourceIndex = VertexCache.indicesIndex;
break;
}
@@ -1235,7 +1973,7 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
s32 exist = 0;
for ( dIndex = 0; dIndex < fillIndex; ++dIndex )
{
- if ( info[ dIndex ].index == sourceIndex )
+ if (VertexCache.info_temp[ dIndex ].index == sourceIndex )
{
exist = 1;
break;
@@ -1244,7 +1982,7 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
if ( 0 == exist )
{
- info[fillIndex++].index = sourceIndex;
+ VertexCache.info_temp[fillIndex++].index = sourceIndex;
}
}
@@ -1259,9 +1997,9 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
{
for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex )
{
- if ( VertexCache.info[ dIndex ].index == info[i].index )
+ if ( VertexCache.info[ dIndex ].index == VertexCache.info_temp[i].index )
{
- info[i].hit = dIndex;
+ VertexCache.info_temp[i].hit = dIndex;
VertexCache.info[ dIndex ].hit = 1;
break;
}
@@ -1271,45 +2009,46 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
// fill new
for ( i = 0; i!= fillIndex; ++i )
{
- if ( info[i].hit != VERTEXCACHE_MISS )
+ if (VertexCache.info_temp[i].hit != VERTEXCACHE_MISS )
continue;
for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex )
{
if ( 0 == VertexCache.info[dIndex].hit )
{
- VertexCache_fill ( info[i].index, dIndex );
+ VertexCache_fill (VertexCache.info_temp[i].index, dIndex );
VertexCache.info[dIndex].hit += 1;
- info[i].hit = dIndex;
+ VertexCache.info_temp[i].hit = dIndex;
break;
}
}
}
}
- const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );
+ //const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );
+ const u32 i0 = VertexCache.pType != scene::EPT_TRIANGLE_FAN ? VertexCache.indicesRun : 0;
switch ( VertexCache.iType )
{
- case 1:
+ case E4IT_16BIT:
{
- const u16 *p = (const u16 *) VertexCache.indices;
+ const u16* p = (const u16*) VertexCache.indices;
face[0] = VertexCache_getVertex ( p[ i0 ] );
face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] );
face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] );
}
break;
- case 2:
+ case E4IT_32BIT:
{
- const u32 *p = (const u32 *) VertexCache.indices;
+ const u32* p = (const u32*) VertexCache.indices;
face[0] = VertexCache_getVertex ( p[ i0 ] );
face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] );
face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] );
}
break;
- case 4:
+ case E4IT_NONE:
face[0] = VertexCache_getVertex ( VertexCache.indicesRun + 0 );
face[1] = VertexCache_getVertex ( VertexCache.indicesRun + 1 );
face[2] = VertexCache_getVertex ( VertexCache.indicesRun + 2 );
@@ -1318,122 +2057,149 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
face[0] = face[1] = face[2] = VertexCache_getVertex(VertexCache.indicesRun + 0);
break;
}
-
- VertexCache.indicesRun += VertexCache.primitivePitch;
+ face[3] = face[0]; // quad unsupported
+ VertexCache.indicesRun += VertexCache.indicesPitch;
}
-/*!
-*/
-REALINLINE void CBurningVideoDriver::VertexCache_getbypass ( s4DVertex ** face )
-{
- const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );
-
- if ( VertexCache.iType == 1 )
- {
- const u16 *p = (const u16 *) VertexCache.indices;
- VertexCache_fill ( p[ i0 ], 0 );
- VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 );
- VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 );
- }
- else
- {
- const u32 *p = (const u32 *) VertexCache.indices;
- VertexCache_fill ( p[ i0 ], 0 );
- VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 );
- VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 );
- }
-
- VertexCache.indicesRun += VertexCache.primitivePitch;
-
- face[0] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );
- face[1] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );
- face[2] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );
-
-}
/*!
*/
-void CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCount,
+int CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCount,
const void* indices, u32 primitiveCount,
E_VERTEX_TYPE vType,
scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType)
{
+
+ // These calls would lead to crashes due to wrong index usage.
+ // The vertex cache needs to be rewritten for these primitives.
+ if (0 == CurrentShader ||
+ pType == scene::EPT_POINTS || pType == scene::EPT_LINE_STRIP ||
+ pType == scene::EPT_LINE_LOOP || pType == scene::EPT_LINES ||
+ pType == scene::EPT_POLYGON ||
+ pType == scene::EPT_POINT_SPRITES)
+ {
+ return 1;
+ }
+
VertexCache.vertices = vertices;
VertexCache.vertexCount = vertexCount;
+ switch (Material.org.MaterialType) // (Material.Fallback_MaterialType)
+ {
+ case EMT_REFLECTION_2_LAYER:
+ case EMT_TRANSPARENT_REFLECTION_2_LAYER:
+ VertexCache.vType = E4VT_REFLECTION_MAP;
+ break;
+ default:
+ VertexCache.vType = (e4DVertexType)vType;
+ break;
+ }
+
+ //check material
+ SVSize* vSize = VertexCache.vSize;
+ for (int m = (int)vSize[VertexCache.vType].TexSize-1; m >= 0 ; --m)
+ {
+ ITexture* tex = MAT_TEXTURE(m);
+ if (!tex)
+ {
+ vSize[E4VT_NO_TEXTURE] = vSize[VertexCache.vType];
+ vSize[E4VT_NO_TEXTURE].TexSize = m;
+ vSize[E4VT_NO_TEXTURE].TexCooSize = m;
+ VertexCache.vType = E4VT_NO_TEXTURE;
+ //flags downconvert?
+ }
+ }
+
VertexCache.indices = indices;
VertexCache.indicesIndex = 0;
VertexCache.indicesRun = 0;
- if ( Material.org.MaterialType == video::EMT_REFLECTION_2_LAYER )
- VertexCache.vType = 3;
- else
- VertexCache.vType = vType;
- VertexCache.pType = pType;
-
switch ( iType )
{
- case EIT_16BIT: VertexCache.iType = 1; break;
- case EIT_32BIT: VertexCache.iType = 2; break;
+ case EIT_16BIT: VertexCache.iType = E4IT_16BIT; break;
+ case EIT_32BIT: VertexCache.iType = E4IT_32BIT; break;
default:
- VertexCache.iType = iType; break;
+ VertexCache.iType = (e4DIndexType)iType; break;
}
+ if (!VertexCache.indices)
+ VertexCache.iType = E4IT_NONE;
+ VertexCache.pType = pType;
+ VertexCache.primitiveHasVertex = 3;
+ VertexCache.indicesPitch = 1;
switch ( VertexCache.pType )
{
// most types here will not work as expected, only triangles/triangle_fan
// is known to work.
case scene::EPT_POINTS:
VertexCache.indexCount = primitiveCount;
- VertexCache.primitivePitch = 1;
+ VertexCache.indicesPitch = 1;
+ VertexCache.primitiveHasVertex = 1;
break;
case scene::EPT_LINE_STRIP:
VertexCache.indexCount = primitiveCount+1;
- VertexCache.primitivePitch = 1;
+ VertexCache.indicesPitch = 1;
+ VertexCache.primitiveHasVertex = 2;
break;
case scene::EPT_LINE_LOOP:
VertexCache.indexCount = primitiveCount+1;
- VertexCache.primitivePitch = 1;
+ VertexCache.indicesPitch = 1;
+ VertexCache.primitiveHasVertex = 2;
break;
case scene::EPT_LINES:
VertexCache.indexCount = 2*primitiveCount;
- VertexCache.primitivePitch = 2;
+ VertexCache.indicesPitch = 2;
+ VertexCache.primitiveHasVertex = 2;
break;
case scene::EPT_TRIANGLE_STRIP:
VertexCache.indexCount = primitiveCount+2;
- VertexCache.primitivePitch = 1;
+ VertexCache.indicesPitch = 1;
+ VertexCache.primitiveHasVertex = 3;
break;
case scene::EPT_TRIANGLES:
VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount;
- VertexCache.primitivePitch = 3;
+ VertexCache.indicesPitch = 3;
+ VertexCache.primitiveHasVertex = 3;
break;
case scene::EPT_TRIANGLE_FAN:
VertexCache.indexCount = primitiveCount + 2;
- VertexCache.primitivePitch = 1;
+ VertexCache.indicesPitch = 1;
+ VertexCache.primitiveHasVertex = 3;
break;
case scene::EPT_QUAD_STRIP:
VertexCache.indexCount = 2*primitiveCount + 2;
- VertexCache.primitivePitch = 2;
+ VertexCache.indicesPitch = 2;
+ VertexCache.primitiveHasVertex = 4;
break;
case scene::EPT_QUADS:
VertexCache.indexCount = 4*primitiveCount;
- VertexCache.primitivePitch = 4;
+ VertexCache.indicesPitch = 4;
+ VertexCache.primitiveHasVertex = 4;
break;
case scene::EPT_POLYGON:
VertexCache.indexCount = primitiveCount+1;
- VertexCache.primitivePitch = 1;
+ VertexCache.indicesPitch = 1;
+ VertexCache.primitiveHasVertex = primitiveCount;
break;
case scene::EPT_POINT_SPRITES:
VertexCache.indexCount = primitiveCount;
- VertexCache.primitivePitch = 1;
+ VertexCache.indicesPitch = 1;
+ VertexCache.primitiveHasVertex = 1;
break;
}
- irr::memset32 ( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) );
+ //memset( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) );
+ for (size_t i = 0; i != VERTEXCACHE_ELEMENT; ++i)
+ {
+ VertexCache.info[i].hit = VERTEXCACHE_MISS;
+ VertexCache.info[i].index = VERTEXCACHE_MISS;
+ }
+ return 0;
}
+//! draws a vertex primitive list
void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
@@ -1444,134 +2210,138 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);
- // These calls would lead to crashes due to wrong index usage.
- // The vertex cache needs to be rewritten for these primitives.
- if (pType==scene::EPT_POINTS || pType==scene::EPT_LINE_STRIP ||
- pType==scene::EPT_LINE_LOOP || pType==scene::EPT_LINES ||
- pType==scene::EPT_POLYGON ||
- pType==scene::EPT_POINT_SPRITES)
+ if (VertexCache_reset(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType))
return;
- if ( 0 == CurrentShader )
- return;
+ if ((u32)Material.org.MaterialType < MaterialRenderers.size())
+ {
+ MaterialRenderers[Material.org.MaterialType].Renderer->OnRender(this, vType);
+ }
+
+ //Matrices needed for this primitive
+ transform_calc(ETS_PROJ_MODEL_VIEW);
+ if ( Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM | TL_FOG)) )
+ {
+ transform_calc(ETS_MODEL_VIEW);
+ transform_calc(ETS_NORMAL);
+ }
- VertexCache_reset ( vertices, vertexCount, indexList, primitiveCount, vType, pType, iType );
- const s4DVertex * face[3];
+ s4DVertexPair* face[4];
- f32 dc_area;
- s32 lodLevel;
- u32 i;
- u32 g;
- u32 m;
- video::CSoftwareTexture2* tex;
+ size_t vOut;
+ size_t vertex_from_clipper; // from VertexCache or CurrentOut
+ size_t has_vertex_run;
- for ( i = 0; i < (u32) primitiveCount; ++i )
+ for ( size_t primitive_run = 0; primitive_run < primitiveCount; ++primitive_run)
{
+ //collect pointer to face vertices
VertexCache_get(face);
- // if fully outside or outside on same side
- if ( ( (face[0]->flag | face[1]->flag | face[2]->flag) & VERTEX4D_CLIPMASK )
- != VERTEX4D_INSIDE
- )
- continue;
+ register size_t clipMask_i;
+ register size_t clipMask_o;
- // if fully inside
- if ( ( face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE )
- {
- dc_area = screenarea2 ( face );
- if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0( dc_area ) )
- continue;
- else
- if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) )
- continue;
+ clipMask_i = face[0]->flag;
+ clipMask_o = face[0]->flag;
- // select mipmap
- dc_area = core::reciprocal ( dc_area );
- for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m )
- {
- if ( 0 == (tex = MAT_TEXTURE ( m )) )
- {
- CurrentShader->setTextureParam(m, 0, 0);
- continue;
- }
+ for (has_vertex_run = 1; has_vertex_run < VertexCache.primitiveHasVertex; ++has_vertex_run)
+ {
+ clipMask_i |= face[has_vertex_run]->flag; // if fully outside or outside on same side
+ clipMask_o &= face[has_vertex_run]->flag; // if fully inside
+ }
- lodLevel = s32_log2_f32 ( texelarea2 ( face, m ) * dc_area );
- CurrentShader->setTextureParam(m, tex, lodLevel );
- select_polygon_mipmap2 ( (s4DVertex**) face, m, tex->getSize() );
- }
+ clipMask_i &= VERTEX4D_CLIPMASK;
+ clipMask_o &= VERTEX4D_CLIPMASK;
- // rasterize
- CurrentShader->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 );
+ if (clipMask_i != VERTEX4D_INSIDE )
+ {
+ // if primitive fully outside or outside on same side
continue;
+ vOut = 0;
+ vertex_from_clipper = 0;
}
-
- // else if not complete inside clipping necessary
- irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[0], SIZEOF_SVERTEX * 2 );
- irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[1], SIZEOF_SVERTEX * 2 );
- irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[2], SIZEOF_SVERTEX * 2 );
-
- const u32 flag = CurrentOut.data->flag & VERTEX4D_FORMAT_MASK;
-
- for ( g = 0; g != CurrentOut.ElementSize; ++g )
+ else if (clipMask_o == VERTEX4D_INSIDE )
{
- CurrentOut.data[g].flag = flag;
- Temp.data[g].flag = flag;
+ // if primitive fully inside
+ vOut = VertexCache.primitiveHasVertex;
+ vertex_from_clipper = 0;
}
+ else
+#if defined(SOFTWARE_DRIVER_2_CLIPPING)
+ {
+ // else if not complete inside clipping necessary
+ // check: clipping should reuse vertexcache (try to minimize clipping)
+ for (has_vertex_run = 0; has_vertex_run < VertexCache.primitiveHasVertex; ++has_vertex_run)
+ {
+ memcpy_s4DVertexPair(Clipper.data + s4DVertex_ofs(has_vertex_run), face[has_vertex_run]);
+ }
+
+ vOut = clipToFrustum(VertexCache.primitiveHasVertex);
+ vertex_from_clipper = 1;
- u32 vOut;
- vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 );
- if ( vOut < 3 )
+ // to DC Space, project homogenous vertex
+ ndc_2_dc_and_project(Clipper.data + s4DVertex_proj(0), Clipper.data, s4DVertex_ofs(vOut));
+ }
+#else
+ {
continue;
+ vOut = 0;
+ vertex_from_clipper = 0;
+ }
+#endif
+ // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )
+ for (has_vertex_run = 0; (has_vertex_run + VertexCache.primitiveHasVertex) <= vOut; has_vertex_run += 1)
+ {
+ // set from clipped geometry
+ if (vertex_from_clipper)
+ {
+ face[0] = Clipper.data + s4DVertex_ofs(0);
+ face[1] = Clipper.data + s4DVertex_ofs(has_vertex_run + 1);
+ face[2] = Clipper.data + s4DVertex_ofs(has_vertex_run + 2);
+ }
- vOut <<= 1;
+ //area of primitive in device space
+ f32 dc_area = screenarea_inside(face);
- // to DC Space, project homogenous vertex
- ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );
+ //geometric clipping has problem with invisible or very small Triangles
+ //size_t sign = dc_area < 0.001f ? CULL_BACK : dc_area > 0.001f ? CULL_FRONT : CULL_INVISIBLE;
+ ieee754 t;
+ t.f = dc_area;
+ size_t sign = t.fields.sign ? CULL_BACK : CULL_FRONT;
+ sign |= t.abs.frac_exp < 981668463 /*0.01f*/ ? CULL_INVISIBLE : 0;
+ if (Material.CullFlag & sign)
+ break; //continue;
- // check 2d backface culling on first
- dc_area = screenarea ( CurrentOut.data );
- if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) )
- continue;
- else if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) )
- continue;
+ //select mipmap ratio between drawing space and texture space
+ dc_area = reciprocal_zero(dc_area);
- // select mipmap
- dc_area = core::reciprocal ( dc_area );
- for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m )
- {
- if ( 0 == (tex = MAT_TEXTURE ( m )) )
+ // select mipmap
+ for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m)
{
- CurrentShader->setTextureParam(m, 0, 0);
- continue;
- }
+ video::CSoftwareTexture2* tex = MAT_TEXTURE(m);
- lodLevel = s32_log2_f32 ( texelarea ( CurrentOut.data, m ) * dc_area );
- CurrentShader->setTextureParam(m, tex, lodLevel );
- select_polygon_mipmap ( CurrentOut.data, vOut, m, tex->getSize() );
- }
+ //only guessing: take more detail (lower mipmap) in light+bump textures
+ //assume transparent add is ~50% transparent -> more detail
+ f32 lod_bias = Material.org.MaterialType == EMT_TRANSPARENT_ADD_COLOR ? 0.1f : 0.33f;
+ lod_bias *= tex->get_lod_bias();
+ s32 lodFactor = lodFactor_inside(face, m, dc_area, lod_bias);
+ CurrentShader->setTextureParam(m, tex, lodFactor);
+ //currently shader receives texture coordinate as Pixelcoo of 1 Texture
+ select_polygon_mipmap_inside(face, m, tex->getTexBound());
+ }
- // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )
- for ( g = 0; g <= vOut - 6; g += 2 )
- {
- // rasterize
- CurrentShader->drawTriangle ( CurrentOut.data + 0 + 1,
- CurrentOut.data + g + 3,
- CurrentOut.data + g + 5);
+ CurrentShader->drawWireFrameTriangle(face[0] + 1, face[1] + 1, face[2] + 1);
+ vertex_from_clipper = 1;
}
}
- // dump statistics
-/*
- char buf [64];
- sprintf ( buf,"VCount:%d PCount:%d CacheMiss: %d",
- vertexCount, primitiveCount,
- VertexCache.CacheMiss
- );
- os::Printer::log( buf );
-*/
+ //release texture
+ for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m)
+ {
+ CurrentShader->setTextureParam(m, 0, 0);
+ }
}
@@ -1581,8 +2351,7 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
//! \param color: New color of the ambient light.
void CBurningVideoDriver::setAmbientLight(const SColorf& color)
{
- CNullDriver::setAmbientLight(color);
- LightSpace.Global_AmbientLight.setColorf ( color );
+ EyeSpace.Global_AmbientLight.setColorf ( color );
}
@@ -1600,54 +2369,102 @@ s32 CBurningVideoDriver::addDynamicLight(const SLight& dl)
l.DiffuseColor.setColorf ( dl.DiffuseColor );
l.SpecularColor.setColorf ( dl.SpecularColor );
+ //should always be valid?
+ sVec4 nDirection;
+ nDirection.x = dl.Direction.X;
+ nDirection.y = dl.Direction.Y;
+ nDirection.z = dl.Direction.Z;
+ nDirection.normalize_dir_xyz();
+
+
switch ( dl.Type )
{
- case video::ELT_DIRECTIONAL:
- l.pos.x = -dl.Direction.X;
- l.pos.y = -dl.Direction.Y;
- l.pos.z = -dl.Direction.Z;
- l.pos.w = 1.f;
+ case ELT_DIRECTIONAL:
+ l.pos.x = dl.Position.X;
+ l.pos.y = dl.Position.Y;
+ l.pos.z = dl.Position.Z;
+ l.pos.w = 0.f;
+
+ l.constantAttenuation = 1.f;
+ l.linearAttenuation = 0.f;
+ l.quadraticAttenuation = 0.f;
+
+ l.spotDirection.x = -nDirection.x;
+ l.spotDirection.y = -nDirection.y;
+ l.spotDirection.z = -nDirection.z;
+ l.spotDirection.w = 0.f;
+ l.spotCosCutoff = -1.f;
+ l.spotCosInnerCutoff = 1.f;
+ l.spotExponent = 0.f;
break;
+
case ELT_POINT:
- case ELT_SPOT:
- LightSpace.Flags |= POINTLIGHT;
l.pos.x = dl.Position.X;
l.pos.y = dl.Position.Y;
l.pos.z = dl.Position.Z;
l.pos.w = 1.f;
-/*
- l.radius = (1.f / dl.Attenuation.Y) * (1.f / dl.Attenuation.Y);
+
l.constantAttenuation = dl.Attenuation.X;
l.linearAttenuation = dl.Attenuation.Y;
l.quadraticAttenuation = dl.Attenuation.Z;
-*/
- l.radius = dl.Radius * dl.Radius;
+
+ l.spotDirection.x = -nDirection.x;
+ l.spotDirection.y = -nDirection.y;
+ l.spotDirection.z = -nDirection.z;
+ l.spotDirection.w = 0.f;
+ l.spotCosCutoff = -1.f;
+ l.spotCosInnerCutoff = 1.f;
+ l.spotExponent = 0.f;
+ break;
+
+ case ELT_SPOT:
+ l.pos.x = dl.Position.X;
+ l.pos.y = dl.Position.Y;
+ l.pos.z = dl.Position.Z;
+ l.pos.w = 1.f;
+
l.constantAttenuation = dl.Attenuation.X;
- l.linearAttenuation = 1.f / dl.Radius;
+ l.linearAttenuation = dl.Attenuation.Y;
l.quadraticAttenuation = dl.Attenuation.Z;
+ l.spotDirection.x = nDirection.x;
+ l.spotDirection.y = nDirection.y;
+ l.spotDirection.z = nDirection.z;
+ l.spotDirection.w = 0.0f;
+ l.spotCosCutoff = cosf(dl.OuterCone * 2.0f * core::DEGTORAD * 0.5f);
+ l.spotCosInnerCutoff = cosf(dl.InnerCone * 2.0f * core::DEGTORAD * 0.5f);
+ l.spotExponent = dl.Falloff;
break;
default:
break;
}
- LightSpace.Light.push_back ( l );
- return LightSpace.Light.size() - 1;
+ //which means ETS_VIEW
+ setTransform(ETS_WORLD,irr::core::IdentityMatrix);
+ transform_calc(ETS_MODEL_VIEW);
+
+ const core::matrix4* matrix = Transformation[TransformationStack];
+ transformVec4Vec4(matrix[ETS_MODEL_VIEW], &l.pos4.x, &l.pos.x );
+ rotateVec3Vec4(matrix[ETS_MODEL_VIEW], &l.spotDirection4.x, &l.spotDirection.x );
+
+ EyeSpace.Light.push_back ( l );
+ return EyeSpace.Light.size() - 1;
}
+
//! Turns a dynamic light on or off
void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn)
{
- if(lightIndex > -1 && lightIndex < (s32)LightSpace.Light.size())
+ if((u32)lightIndex < EyeSpace.Light.size())
{
- LightSpace.Light[lightIndex].LightIsOn = turnOn;
+ EyeSpace.Light[lightIndex].LightIsOn = turnOn;
}
}
//! deletes all dynamic lights there are
void CBurningVideoDriver::deleteAllDynamicLights()
{
- LightSpace.reset ();
+ EyeSpace.reset ();
CNullDriver::deleteAllDynamicLights();
}
@@ -1655,248 +2472,498 @@ void CBurningVideoDriver::deleteAllDynamicLights()
//! returns the maximal amount of dynamic lights the device can handle
u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const
{
- return 8;
+ return 8; //no limit 8 only for convenience
}
//! sets a material
void CBurningVideoDriver::setMaterial(const SMaterial& material)
{
+// ---------- Override
Material.org = material;
+ OverrideMaterial.apply(Material.org);
+
+ const SMaterial& in = Material.org;
+
+// ---------- Notify Shader
+ // unset old material
+ u32 mi;
+ mi = (u32)Material.lastMaterial.MaterialType;
+ if (mi != material.MaterialType && mi < MaterialRenderers.size())
+ MaterialRenderers[mi].Renderer->OnUnsetMaterial();
+
+ // set new material.
+ mi = (u32)in.MaterialType;
+ if (mi < MaterialRenderers.size())
+ MaterialRenderers[mi].Renderer->OnSetMaterial(
+ in, Material.lastMaterial, Material.resetRenderStates, this);
+
+ Material.lastMaterial = in;
+ Material.resetRenderStates = false;
+
+ //CSoftware2MaterialRenderer sets Material.Fallback_MaterialType
+
+ //Material.Fallback_MaterialType = material.MaterialType;
+
+//-----------------
+
+ //Material.org = material;
+ Material.CullFlag = CULL_INVISIBLE | (in.BackfaceCulling ? CULL_BACK : 0) | (in.FrontfaceCulling ? CULL_FRONT : 0);
+
+ size_t* flag = TransformationFlag[TransformationStack];
#ifdef SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
- for (u32 i = 0; i < 2; ++i)
+ for (u32 m = 0; m < BURNING_MATERIAL_MAX_TEXTURES /*&& m < vSize[VertexCache.vType].TexSize*/; ++m)
{
- setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i),
- material.getTextureMatrix(i));
+ setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + m),in.getTextureMatrix(m));
+ flag[ETS_TEXTURE_0+m] &= ~ETF_TEXGEN_MASK;
}
#endif
#ifdef SOFTWARE_DRIVER_2_LIGHTING
- Material.AmbientColor.setR8G8B8 ( Material.org.AmbientColor.color );
- Material.DiffuseColor.setR8G8B8 ( Material.org.DiffuseColor.color );
- Material.EmissiveColor.setR8G8B8 ( Material.org.EmissiveColor.color );
- Material.SpecularColor.setR8G8B8 ( Material.org.SpecularColor.color );
- core::setbit_cond ( LightSpace.Flags, Material.org.Shininess != 0.f, SPECULAR );
- core::setbit_cond ( LightSpace.Flags, Material.org.FogEnable, FOG );
- core::setbit_cond ( LightSpace.Flags, Material.org.NormalizeNormals, NORMALIZE );
+ Material.AmbientColor.setA8R8G8B8( in.AmbientColor.color );
+ Material.DiffuseColor.setA8R8G8B8( in.ColorMaterial ? 0xFFFFFFFF : in.DiffuseColor.color );
+ Material.EmissiveColor.setA8R8G8B8(in.EmissiveColor.color );
+ Material.SpecularColor.setA8R8G8B8( in.SpecularColor.color );
+
+ burning_setbit(EyeSpace.TL_Flag, in.Lighting, TL_LIGHT);
+ burning_setbit( EyeSpace.TL_Flag, (in.Shininess != 0.f) & (in.SpecularColor.color & 0x00ffffff), TL_SPECULAR );
+ burning_setbit( EyeSpace.TL_Flag, in.FogEnable, TL_FOG );
+ burning_setbit( EyeSpace.TL_Flag, in.NormalizeNormals, TL_NORMALIZE_NORMALS );
+ //if (EyeSpace.Flags & SPECULAR ) EyeSpace.Flags |= NORMALIZE_NORMALS;
+
#endif
- setCurrentShader();
-}
+ //--------------- setCurrentShader
+ ITexture* texture0 = in.getTexture(0);
+ ITexture* texture1 = in.getTexture(1);
+ //ITexture* texture2 = in.getTexture(2);
+ //ITexture* texture3 = in.getTexture(3);
-/*!
- Camera Position in World Space
-*/
-void CBurningVideoDriver::getCameraPosWorldSpace ()
-{
- Transformation[ETS_VIEW_INVERSE] = Transformation[ ETS_VIEW ];
- Transformation[ETS_VIEW_INVERSE].makeInverse ();
- TransformationFlag[ETS_VIEW_INVERSE] = 0;
+ //visual studio code analysis
+ u32 maxTex = BURNING_MATERIAL_MAX_TEXTURES;
+ if (maxTex < 1) texture0 = 0;
+ if (maxTex < 2) texture1 = 0;
+ //if (maxTex < 3) texture2 = 0;
+ //if (maxTex < 4) texture3 = 0;
- const f32 *M = Transformation[ETS_VIEW_INVERSE].pointer ();
+ EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP);
- /* The viewpoint is at (0., 0., 0.) in eye space.
- Turning this into a vector [0 0 0 1] and multiply it by
- the inverse of the view matrix, the resulting vector is the
- object space location of the camera.
- */
+ //todo: seperate depth test from depth write
+ Material.depth_write = getWriteZBuffer(in);
+ Material.depth_test = in.ZBuffer != ECFN_DISABLED && Material.depth_write;
- LightSpace.campos.x = M[12];
- LightSpace.campos.y = M[13];
- LightSpace.campos.z = M[14];
- LightSpace.campos.w = 1.f;
-}
+ EBurningFFShader shader = Material.depth_test ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ;
-void CBurningVideoDriver::getLightPosObjectSpace ()
-{
- if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY )
+ switch (Material.Fallback_MaterialType) //(Material.org.MaterialType)
{
- Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD];
- TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY;
+ case EMT_ONETEXTURE_BLEND:
+ shader = ETR_TEXTURE_BLEND;
+ break;
+
+ case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
+ Material.org.MaterialTypeParam = 0.5f;
+ //fallthrough
+
+ case EMT_TRANSPARENT_ALPHA_CHANNEL:
+ if (texture0 && texture0->hasAlpha())
+ {
+ shader = Material.depth_test ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ;
+ }
+ else
+ {
+ //fall back to EMT_TRANSPARENT_VERTEX_ALPHA
+ shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;
+ }
+ break;
+
+ case EMT_TRANSPARENT_ADD_COLOR:
+ shader = Material.depth_test ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z;
+ break;
+
+ case EMT_TRANSPARENT_VERTEX_ALPHA:
+ shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;
+ break;
+
+ case EMT_LIGHTMAP:
+ case EMT_LIGHTMAP_LIGHTING:
+ if (texture1)
+ shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;
+ break;
+
+ case EMT_LIGHTMAP_M2:
+ case EMT_LIGHTMAP_LIGHTING_M2:
+ if (texture1)
+ shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2;
+ break;
+
+ case EMT_LIGHTMAP_LIGHTING_M4:
+ if (texture1)
+ shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4;
+ break;
+ case EMT_LIGHTMAP_M4:
+ if (texture1)
+ shader = ETR_TEXTURE_LIGHTMAP_M4;
+ break;
+
+ case EMT_LIGHTMAP_ADD:
+ if (texture1)
+ shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD;
+ break;
+
+ case EMT_DETAIL_MAP:
+ if (texture1)
+ shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP;
+ break;
+
+ case EMT_SPHERE_MAP:
+ flag[ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_SPHERE;
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;
+ break;
+ case EMT_REFLECTION_2_LAYER:
+ case EMT_TRANSPARENT_REFLECTION_2_LAYER:
+ if (texture1)
+ {
+ shader = ETR_TRANSPARENT_REFLECTION_2_LAYER;
+ flag[ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION;
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;
+ }
+ break;
+
+ case EMT_NORMAL_MAP_SOLID:
+ case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
+ case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
+ if (texture1)
+ {
+ shader = ETR_NORMAL_MAP_SOLID;
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP;
+ }
+ break;
+ case EMT_PARALLAX_MAP_SOLID:
+ case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
+ case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
+ if (texture1)
+ {
+ shader = ETR_NORMAL_MAP_SOLID;
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP;
+ }
+ break;
+
+ default:
+ break;
+
}
- else
+
+ if (!texture0)
{
- Transformation[ETS_WORLD].getInverse ( Transformation[ETS_WORLD_INVERSE] );
- TransformationFlag[ETS_WORLD_INVERSE] &= ~ETF_IDENTITY;
+ shader = Material.depth_test ? ETR_GOURAUD :
+ shader == ETR_TEXTURE_GOURAUD_VERTEX_ALPHA ?
+ ETR_GOURAUD_ALPHA_NOZ: // 2D Gradient
+ ETR_GOURAUD_NOZ;
+
+ shader = ETR_COLOR;
}
- for ( u32 i = 0; i < 1 && i < LightSpace.Light.size(); ++i )
+ if (in.Wireframe)
{
- SBurningShaderLight &l = LightSpace.Light[i];
+ IBurningShader* candidate = BurningShader[shader];
+ if (!candidate || (candidate && !candidate->canWireFrame()))
+ {
+ shader = ETR_TEXTURE_GOURAUD_WIRE;
+ }
+ }
- Transformation[ETS_WORLD_INVERSE].transformVec3 ( &l.pos_objectspace.x, &l.pos.x );
+ if (in.PointCloud)
+ {
+ IBurningShader* candidate = BurningShader[shader];
+ if (!candidate || (candidate && !candidate->canPointCloud()))
+ {
+ shader = ETR_TEXTURE_GOURAUD_WIRE;
+ }
}
-}
+ //shader = ETR_REFERENCE;
+
+ // switchToTriangleRenderer
+ CurrentShader = BurningShader[shader];
+ if (CurrentShader)
+ {
+ CurrentShader->setTLFlag(EyeSpace.TL_Flag);
+ if (EyeSpace.TL_Flag & TL_FOG) CurrentShader->setFog(FogColor);
+ if (EyeSpace.TL_Flag & TL_SCISSOR) CurrentShader->setScissor(Scissor);
+ CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);
+ CurrentShader->OnSetMaterial(Material);
+ CurrentShader->pushEdgeTest(in.Wireframe, in.PointCloud, 0);
+ }
+
+
+/*
+ mi = (u32)Material.org.MaterialType;
+ if (mi < MaterialRenderers.size())
+ MaterialRenderers[mi].Renderer->OnRender(this, (video::E_VERTEX_TYPE)VertexCache.vType);
+*/
+}
-#ifdef SOFTWARE_DRIVER_2_LIGHTING
//! Sets the fog mode.
void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start,
f32 end, f32 density, bool pixelFog, bool rangeFog)
{
CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog);
- LightSpace.FogColor.setA8R8G8B8 ( color.color );
+
+ EyeSpace.fog_scale = reciprocal_zero2(FogEnd - FogStart);
}
+
+
+#if defined(SOFTWARE_DRIVER_2_LIGHTING) && BURNING_MATERIAL_MAX_COLORS > 0
+
+
/*!
applies lighting model
*/
-void CBurningVideoDriver::lightVertex ( s4DVertex *dest, u32 vertexargb )
+void CBurningVideoDriver::lightVertex_eye(s4DVertex *dest, u32 vertexargb)
{
- sVec3 dColor;
-
- dColor = LightSpace.Global_AmbientLight;
- dColor.add ( Material.EmissiveColor );
-
- if ( Lights.size () == 0 )
- {
- dColor.saturate( dest->Color[0], vertexargb);
- return;
- }
+ //gl_FrontLightModelProduct.sceneColor = gl_FrontMaterial.emission + gl_FrontMaterial.ambient * gl_LightModel.ambient
- sVec3 ambient;
- sVec3 diffuse;
- sVec3 specular;
+ sVec3Color ambient;
+ sVec3Color diffuse;
+ sVec3Color specular;
// the universe started in darkness..
- ambient.set ( 0.f, 0.f, 0.f );
- diffuse.set ( 0.f, 0.f, 0.f );
- specular.set ( 0.f, 0.f, 0.f );
+ ambient = EyeSpace.Global_AmbientLight;
+ diffuse.set(0.f);
+ specular.set(0.f);
u32 i;
f32 dot;
- f32 len;
+ f32 distance;
f32 attenuation;
sVec4 vp; // unit vector vertex to light
sVec4 lightHalf; // blinn-phong reflection
- for ( i = 0; i!= LightSpace.Light.size (); ++i )
- {
- const SBurningShaderLight &light = LightSpace.Light[i];
+ f32 spotDot; // cos of angle between spotlight and point on surface
- if ( !light.LightIsOn )
+ for (i = 0; i < EyeSpace.Light.size(); ++i)
+ {
+ const SBurningShaderLight& light = EyeSpace.Light[i];
+ if (!light.LightIsOn)
continue;
- // accumulate ambient
- ambient.add ( light.AmbientColor );
-
- switch ( light.Type )
+ switch (light.Type)
{
- case video::ELT_SPOT:
- case video::ELT_POINT:
- // surface to light
- vp.x = light.pos.x - LightSpace.vertex.x;
- vp.y = light.pos.y - LightSpace.vertex.y;
- vp.z = light.pos.z - LightSpace.vertex.z;
- //vp.x = light.pos_objectspace.x - LightSpace.vertex.x;
- //vp.y = light.pos_objectspace.y - LightSpace.vertex.x;
- //vp.z = light.pos_objectspace.z - LightSpace.vertex.x;
-
- len = vp.get_length_xyz_square();
- if ( light.radius < len )
- continue;
-
- len = core::reciprocal_squareroot ( len );
-
- // build diffuse reflection
-
- //angle between normal and light vector
- vp.mul ( len );
- dot = LightSpace.normal.dot_xyz ( vp );
- if ( dot < 0.f )
- continue;
-
- attenuation = light.constantAttenuation + ( 1.f - ( len * light.linearAttenuation ) );
-
- // diffuse component
- diffuse.mulAdd ( light.DiffuseColor, 3.f * dot * attenuation );
-
- if ( !(LightSpace.Flags & SPECULAR) )
- continue;
-
- // build specular
- // surface to view
- lightHalf.x = LightSpace.campos.x - LightSpace.vertex.x;
- lightHalf.y = LightSpace.campos.y - LightSpace.vertex.y;
- lightHalf.z = LightSpace.campos.z - LightSpace.vertex.z;
- lightHalf.normalize_xyz();
- lightHalf += vp;
- lightHalf.normalize_xyz();
-
- // specular
- dot = LightSpace.normal.dot_xyz ( lightHalf );
- if ( dot < 0.f )
- continue;
-
- //specular += light.SpecularColor * ( powf ( Material.org.Shininess ,dot ) * attenuation );
- specular.mulAdd ( light.SpecularColor, dot * attenuation );
- break;
-
- case video::ELT_DIRECTIONAL:
-
- //angle between normal and light vector
- dot = LightSpace.normal.dot_xyz ( light.pos );
- if ( dot < 0.f )
- continue;
-
- // diffuse component
- diffuse.mulAdd ( light.DiffuseColor, dot );
- break;
- default:
- break;
+ case ELT_DIRECTIONAL:
+
+ //angle between normal and light vector
+ dot = EyeSpace.normal.dot_xyz(light.spotDirection4);
+
+ // accumulate ambient
+ ambient.add_rgb(light.AmbientColor);
+
+ // diffuse component
+ if (dot > 0.f)
+ diffuse.mad_rgb(light.DiffuseColor, dot);
+ break;
+
+ case ELT_POINT:
+ // surface to light
+ vp.x = light.pos4.x - EyeSpace.vertex.x;
+ vp.y = light.pos4.y - EyeSpace.vertex.y;
+ vp.z = light.pos4.z - EyeSpace.vertex.z;
+
+ distance = vp.length_xyz();
+
+ attenuation = light.constantAttenuation
+ + light.linearAttenuation * distance
+ + light.quadraticAttenuation * (distance * distance);
+ attenuation = reciprocal_one(attenuation);
+
+ //att = clamp(1.0 - dist/radius, 0.0, 1.0); att *= att
+
+ // accumulate ambient
+ ambient.mad_rgb(light.AmbientColor, attenuation);
+
+ // build diffuse reflection
+
+ //angle between normal and light vector
+ vp.mul_xyz(reciprocal_zero(distance)); //normalize
+ dot = EyeSpace.normal.dot_xyz(vp);
+ if (dot <= 0.f) continue;
+
+ // diffuse component
+ diffuse.mad_rgb(light.DiffuseColor, dot * attenuation);
+
+ if (!(EyeSpace.TL_Flag & TL_SPECULAR))
+ continue;
+
+ lightHalf.x = vp.x + 0.f; // EyeSpace.cam_eye_pos.x;
+ lightHalf.y = vp.y + 0.f; // EyeSpace.cam_eye_pos.y;
+ lightHalf.z = vp.z - 1.f; // EyeSpace.cam_eye_pos.z;
+ lightHalf.normalize_dir_xyz();
+
+ //specular += light.SpecularColor * pow(max(dot(Eyespace.normal,lighthalf),0,Material.org.Shininess)*attenuation
+ specular.mad_rgb(light.SpecularColor,
+ powf_limit(EyeSpace.normal.dot_xyz(lightHalf), Material.org.Shininess)*attenuation
+ );
+ break;
+
+ case ELT_SPOT:
+ // surface to light
+ vp.x = light.pos4.x - EyeSpace.vertex.x;
+ vp.y = light.pos4.y - EyeSpace.vertex.y;
+ vp.z = light.pos4.z - EyeSpace.vertex.z;
+
+ distance = vp.length_xyz();
+
+ //normalize
+ vp.mul_xyz(reciprocal_zero(distance));
+
+ // point on surface inside cone of illumination
+ spotDot = vp.dot_minus_xyz(light.spotDirection4);
+ if (spotDot < light.spotCosCutoff)
+ continue;
+
+ attenuation = light.constantAttenuation
+ + light.linearAttenuation * distance
+ + light.quadraticAttenuation * distance * distance;
+ attenuation = reciprocal_one(attenuation);
+ attenuation *= powf_limit(spotDot, light.spotExponent);
+
+ // accumulate ambient
+ ambient.mad_rgb(light.AmbientColor, attenuation);
+
+
+ // build diffuse reflection
+ //angle between normal and light vector
+ dot = EyeSpace.normal.dot_xyz(vp);
+ if (dot < 0.f) continue;
+
+ // diffuse component
+ diffuse.mad_rgb(light.DiffuseColor, dot * attenuation);
+
+ if (!(EyeSpace.TL_Flag & TL_SPECULAR))
+ continue;
+
+ lightHalf.x = vp.x + 0.f; // EyeSpace.cam_eye_pos.x;
+ lightHalf.y = vp.y + 0.f; // EyeSpace.cam_eye_pos.y;
+ lightHalf.z = vp.z - 1.f; // EyeSpace.cam_eye_pos.z;
+ lightHalf.normalize_dir_xyz();
+
+ //specular += light.SpecularColor * pow(max(dot(Eyespace.normal,lighthalf),0,Material.org.Shininess)*attenuation
+ specular.mad_rgb(light.SpecularColor,
+ powf_limit(EyeSpace.normal.dot_xyz(lightHalf), Material.org.Shininess)*attenuation
+ );
+ break;
+
+ default:
+ break;
}
}
// sum up lights
- dColor.mulAdd (ambient, Material.AmbientColor );
- dColor.mulAdd (diffuse, Material.DiffuseColor);
- dColor.mulAdd (specular, Material.SpecularColor);
+ sVec3Color dColor;
+ dColor.set(0.f);
+ dColor.mad_rgbv(diffuse, Material.DiffuseColor);
+
+ //diffuse * vertex color.
+ //has to move to shader (for vertex color only this will fit [except clamping])
+
+ sVec3Color c;
+ c.setA8R8G8B8(vertexargb);
+ dColor.r *= c.r;
+ dColor.g *= c.g;
+ dColor.b *= c.b;
+
+ //separate specular
+#if defined(SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR)
+ if ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG))
+ {
+ specular.sat_xyz(dest->Color[1], Material.SpecularColor);
+ }
+ else
+ if ( !(EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) &&
+ (VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_MASK_LIGHT)
+ )
+ {
+ specular.sat_xyz(dest->LightTangent[0], Material.SpecularColor);
+ }
+ else
+#endif
+ {
+ dColor.mad_rgbv(specular, Material.SpecularColor);
+ }
+
+
+ dColor.mad_rgbv(ambient, Material.AmbientColor);
+ dColor.add_rgb(Material.EmissiveColor);
+
+
+ dColor.sat(dest->Color[0], vertexargb);
- dColor.saturate ( dest->Color[0], vertexargb );
}
#endif
+CImage* getImage(const video::ITexture* texture)
+{
+ if (!texture) return 0;
+
+ CImage* img = 0;
+ switch (texture->getDriverType())
+ {
+ case EDT_BURNINGSVIDEO:
+ img = ((CSoftwareTexture2*)texture)->getImage();
+ break;
+ case EDT_SOFTWARE:
+ img = ((CSoftwareTexture*)texture)->getImage();
+ break;
+ default:
+ os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);
+ break;
+ }
+ return img;
+}
+
+/*
+ draw2DImage with single color scales into destination quad & cliprect(more like viewport)
+ draw2DImage with 4 color scales on destination and cliprect is scissor
+*/
+
+static const u16 quad_triangle_indexList[6] = { 0,1,2,0,2,3 };
+
+
+#if defined(SOFTWARE_DRIVER_2_2D_AS_2D)
//! 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.
void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
- const core::rect<s32>& sourceRect,
- const core::rect<s32>* clipRect, SColor color,
- bool useAlphaChannelOfTexture)
+ const core::rect<s32>& sourceRect,
+ const core::rect<s32>* clipRect, SColor color,
+ bool useAlphaChannelOfTexture)
{
if (texture)
{
- if (texture->getDriverType() != EDT_BURNINGSVIDEO)
+ if (texture->getOriginalSize() != texture->getSize())
{
- os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);
+ core::rect<s32> destRect(destPos, sourceRect.getSize());
+ SColor c4[4] = { color,color,color,color };
+ draw2DImage(texture, destRect, sourceRect, clipRect, c4, useAlphaChannelOfTexture);
return;
}
-#if 0
- // 2d methods don't use viewPort
- core::position2di dest = destPos;
- core::recti clip=ViewPort;
- if (ViewPort.getSize().Width != ScreenSize.Width)
+ if (texture->getDriverType() != EDT_BURNINGSVIDEO)
{
- dest.X=ViewPort.UpperLeftCorner.X+core::round32_fast(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width);
- dest.Y=ViewPort.UpperLeftCorner.Y+core::round32_fast(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height);
- if (clipRect)
- {
- clip.constrainTo(*clipRect);
- }
- clipRect = &clip;
+ os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);
+ return;
}
-#endif
+
if (useAlphaChannelOfTexture)
((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha(
- RenderTargetSurface, destPos, sourceRect, color, clipRect);
+ RenderTargetSurface, destPos, sourceRect, color, clipRect);
else
((CSoftwareTexture2*)texture)->getImage()->copyTo(
RenderTargetSurface, destPos, sourceRect, clipRect);
@@ -1906,8 +2973,8 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core
//! Draws a part of the texture into the rectangle.
void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
- const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
- const video::SColor* const colors, bool useAlphaChannelOfTexture)
+ const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
+ const video::SColor* const colors, bool useAlphaChannelOfTexture)
{
if (texture)
{
@@ -1917,98 +2984,392 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core
return;
}
- if (useAlphaChannelOfTexture)
- StretchBlit(BLITTER_TEXTURE_ALPHA_BLEND, RenderTargetSurface, &destRect, &sourceRect,
- ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0));
- else
- StretchBlit(BLITTER_TEXTURE, RenderTargetSurface, &destRect, &sourceRect,
- ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0));
+ u32 argb = (colors ? colors[0].color : 0xFFFFFFFF);
+ eBlitter op = useAlphaChannelOfTexture ?
+ (argb == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND) : BLITTER_TEXTURE;
+
+ StretchBlit(op, RenderTargetSurface, clipRect, &destRect,
+ ((CSoftwareTexture2*)texture)->getImage(), &sourceRect, &texture->getOriginalSize(), argb);
+
}
}
-//! Draws a 2d line.
-void CBurningVideoDriver::draw2DLine(const core::position2d<s32>& start,
- const core::position2d<s32>& end,
- SColor color)
+//!Draws an 2d rectangle with a gradient.
+void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position,
+ SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
+ const core::rect<s32>* clip)
{
- drawLine(BackBuffer, start, end, color );
+ core::rect<s32> p(position);
+ if (clip) p.clipAgainst(*clip);
+ if (p.isValid()) drawRectangle(RenderTargetSurface, p, colorLeftUp);
}
+#endif //defined(SOFTWARE_DRIVER_2_2D_AS_2D)
-//! Draws a pixel
-void CBurningVideoDriver::drawPixel(u32 x, u32 y, const SColor & color)
+
+
+
+
+#if 0
+void transform_for_BlitJob2D( SBlitJob& out,
+ const S3DVertex quad2DVertices[4], const core::dimension2d<u32>& renderTargetSize,
+ CBurningVideoDriver* driver
+)
+{
+ //assume. z = 0.f, w = 1.f
+ //MVP 2D
+ core::matrix4 m;
+ m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f);
+ m.setTranslation(core::vector3df(-1.f, 1.f, 0));
+
+ //setTransform(ETS_WORLD, m);
+ //m.setTranslation(core::vector3df(0.375f, 0.375f, 0.0f));
+ //setTransform(ETS_VIEW, m);
+
+ s4DVertexPair v[4*sizeof_s4DVertexPairRel];
+ for (int i = 0; i < 4; ++i)
+ {
+ m.transformVect(&v[s4DVertex_ofs(i)].Pos.x, quad2DVertices[i].Pos);
+ v[s4DVertex_ofs(i)].Tex[0].x = quad2DVertices[i].TCoords.X;
+ v[s4DVertex_ofs(i)].Tex[0].y = quad2DVertices[i].TCoords.Y;
+ v[s4DVertex_ofs(i)].Color[0].setA8R8G8B8(quad2DVertices[i].Color.color);
+ v[s4DVertex_ofs(i)].flag = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1;
+ v[s4DVertex_ofs(i)].flag |= clipToFrustumTest(v + i);
+ }
+
+ size_t vOut = driver->clipToFrustum(4);
+
+ struct s2DVertex
+ {
+ union
+ {
+ struct {
+ f32 x, y;
+ f32 u, v;
+ f32 a, r, g, b;
+ };
+ f32 attr[8];
+ };
+
+ // f = a * t + b * ( 1 - t )
+ void interpolate(const s2DVertex& b, const s2DVertex& a, const f32 t)
+ {
+ for (int i = 0; i < 8; ++i)
+ {
+ attr[i] = b.attr[i] + ((a.attr[i] - b.attr[i]) * t);
+ }
+ }
+
+ };
+
+ // 0 5
+ f32 m2[2];
+ m2[0] = renderTargetSize.Width ? 2.f / renderTargetSize.Width : 0.f;
+ m2[1] = renderTargetSize.Height ? -2.f / renderTargetSize.Height : 0.f;
+
+ s2DVertex p[4];
+ for (int i = 0; i < 4; ++i)
+ {
+ p[i].x = quad2DVertices[i].Pos.X*m2[0] - 1.f;
+ p[i].y = quad2DVertices[i].Pos.Y*m2[1] + 1.f;
+ p[i].u = quad2DVertices[i].TCoords.X;
+ p[i].v = quad2DVertices[i].TCoords.Y;
+
+ p[i].a = quad2DVertices[i].Color.getAlpha() * (1.f / 255.f);
+ p[i].r = quad2DVertices[i].Color.getRed() * (1.f / 255.f);
+ p[i].g = quad2DVertices[i].Color.getBlue() * (1.f / 255.f);
+ p[i].b = quad2DVertices[i].Color.getGreen() * (1.f / 255.f);
+
+ }
+
+}
+#endif
+
+
+//! Enable the 2d override material
+void CBurningVideoDriver::enableMaterial2D(bool enable)
{
- BackBuffer->setPixel(x, y, color, true);
+ CNullDriver::enableMaterial2D(enable);
+ burning_setbit(TransformationFlag[1][ETS_PROJECTION], 0, ETF_VALID);
}
+size_t compare_2d_material(const SMaterial& a, const SMaterial& b)
+{
+ size_t flag = 0;
+ flag |= a.MaterialType == b.MaterialType ? 0 : 1;
+ flag |= a.ZBuffer == b.ZBuffer ? 0 : 2;
+ flag |= a.TextureLayer[0].Texture == b.TextureLayer[0].Texture ? 0 : 4;
+ flag |= a.TextureLayer[0].BilinearFilter == b.TextureLayer[0].BilinearFilter ? 0 : 8;
+ flag |= a.MaterialTypeParam == b.MaterialTypeParam ? 0 : 16;
+ if (flag) return flag;
+
+ flag |= a.TextureLayer[1].Texture == b.TextureLayer[1].Texture ? 0 : 32;
+ flag |= a.ZWriteEnable == b.ZWriteEnable ? 0 : 64;
+
+ return flag;
+}
-//! draw an 2d rectangle
-void CBurningVideoDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos,
- const core::rect<s32>* clip)
+void CBurningVideoDriver::setRenderStates2DMode(const video::SColor& color, video::ITexture* texture, bool useAlphaChannelOfTexture)
{
- if (clip)
- {
- core::rect<s32> p(pos);
+ //save current 3D Material
+ //Material.save3D = Material.org;
- p.clipAgainst(*clip);
+ //build new 2D Material
- if(!p.isValid())
- return;
+ bool vertexAlpha = color.getAlpha() < 255;
- drawRectangle(BackBuffer, p, color);
+ //2D uses textureAlpa*vertexAlpha 3D not..
+ if (useAlphaChannelOfTexture && texture && texture->hasAlpha())
+ {
+ Material.mat2D.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;
+ }
+ else if (vertexAlpha)
+ {
+ Material.mat2D.MaterialType = EMT_TRANSPARENT_VERTEX_ALPHA;
}
else
{
- if(!pos.isValid())
- return;
+ Material.mat2D.MaterialType = EMT_SOLID;
+ }
+
+ Material.mat2D.ZBuffer = ECFN_DISABLED;
+ Material.mat2D.ZWriteEnable = EZW_OFF;
+ Material.mat2D.Lighting = false;
+
+ Material.mat2D.setTexture(0, (video::ITexture*)texture);
+
+ //used for text. so stay as sharp as possible (like HW Driver)
+ bool mip = false;
+
+ const SMaterial& currentMaterial = (!OverrideMaterial2DEnabled) ? InitMaterial2D : OverrideMaterial2D;
+ mip = currentMaterial.TextureLayer[0].BilinearFilter;
+
+ Material.mat2D.setFlag(video::EMF_BILINEAR_FILTER, mip);
+
+
+ //switch to 2D Matrix Stack [ Material set Texture Matrix ]
+ TransformationStack = 1;
+
+ //2D GUI Matrix
+ if (!(TransformationFlag[TransformationStack][ETS_PROJECTION] & ETF_VALID))
+ {
+ const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
+ core::matrix4 m(core::matrix4::EM4CONST_NOTHING);
+ m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f);
+ m.setTranslation(core::vector3df(-1.f, 1.f, 0));
+ setTransform(ETS_PROJECTION, m);
+
+ m.makeIdentity();
+ setTransform(ETS_WORLD, m);
+
+ if ( mip ) m.setTranslation(core::vector3df(0.375f, 0.375f, 0.0f));
+
+ setTransform(ETS_VIEW, m);
+
+ buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[TransformationStack], ViewPort, mip ? -0.187f : 0.f);
- drawRectangle(BackBuffer, pos, color);
}
-}
+ //compare
+ if (compare_2d_material(Material.org,Material.mat2D))
+ {
+ setMaterial(Material.mat2D);
+ }
+ if (CurrentShader)
+ {
+ CurrentShader->setPrimitiveColor(color.color);
+ }
+
+}
-//! Only used by the internal engine. Used to notify the driver that
-//! the window was resized.
-void CBurningVideoDriver::OnResize(const core::dimension2d<u32>& size)
+void CBurningVideoDriver::setRenderStates3DMode()
{
- // make sure width and height are multiples of 2
- core::dimension2d<u32> realSize(size);
+ //restoreRenderStates3DMode
- if (realSize.Width % 2)
- realSize.Width += 1;
+ //setMaterial(Material.save3D);
+ //switch to 3D Matrix Stack
+ TransformationStack = 0;
+}
- if (realSize.Height % 2)
- realSize.Height += 1;
+//! draws a vertex primitive list in 2d
+void CBurningVideoDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,
+ const void* indexList, u32 primitiveCount,
+ E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
+{
+ if (!checkPrimitiveCount(primitiveCount))
+ return;
- if (ScreenSize != realSize)
+ CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);
+
+ bool useAlphaChannelOfTexture = false;
+ video::SColor color(0xFFFFFFFF);
+ switch (Material.org.MaterialType)
{
- if (ViewPort.getWidth() == (s32)ScreenSize.Width &&
- ViewPort.getHeight() == (s32)ScreenSize.Height)
- {
- ViewPort.UpperLeftCorner.X = 0;
- ViewPort.UpperLeftCorner.Y = 0;
- ViewPort.LowerRightCorner.X = realSize.Width;
- ViewPort.LowerRightCorner.X = realSize.Height;
- }
+ case EMT_TRANSPARENT_ALPHA_CHANNEL:
+ useAlphaChannelOfTexture = true;
+ break;
+ case EMT_TRANSPARENT_VERTEX_ALPHA:
+ color.setAlpha(127);
+ break;
+ default:
+ break;
+ }
+ setRenderStates2DMode(color, Material.org.getTexture(0), useAlphaChannelOfTexture);
- ScreenSize = realSize;
+ drawVertexPrimitiveList(vertices, vertexCount,
+ indexList, primitiveCount,
+ vType, pType, iType);
- bool resetRT = (RenderTargetSurface == BackBuffer);
+ setRenderStates3DMode();
- if (BackBuffer)
- BackBuffer->drop();
- BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, realSize);
+}
- if (resetRT)
- setRenderTargetImage(BackBuffer);
+//setup a quad
+#if defined(SOFTWARE_DRIVER_2_2D_AS_3D)
+
+//! 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.
+void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
+ const core::rect<s32>& sourceRect,
+ const core::rect<s32>* clipRect, SColor color,
+ bool useAlphaChannelOfTexture)
+{
+ if (!texture)
+ return;
+
+ if (!sourceRect.isValid())
+ return;
+
+ // clip these coordinates
+ core::rect<s32> targetRect(destPos, sourceRect.getSize());
+ if (clipRect)
+ {
+ targetRect.clipAgainst(*clipRect);
+ if (targetRect.getWidth() < 0 || targetRect.getHeight() < 0)
+ return;
}
+
+ const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
+ targetRect.clipAgainst(core::rect<s32>(0, 0, (s32)renderTargetSize.Width, (s32)renderTargetSize.Height));
+ if (targetRect.getWidth() < 0 || targetRect.getHeight() < 0)
+ return;
+
+ // ok, we've clipped everything.
+ // now draw it.
+ const core::dimension2d<s32> sourceSize(targetRect.getSize());
+ const core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner + (targetRect.UpperLeftCorner - destPos));
+
+ const core::dimension2d<u32>& tex_orgsize = texture->getOriginalSize();
+ const f32 invW = 1.f / static_cast<f32>(tex_orgsize.Width);
+ const f32 invH = 1.f / static_cast<f32>(tex_orgsize.Height);
+ const core::rect<f32> tcoords(
+ sourcePos.X * invW,
+ sourcePos.Y * invH,
+ (sourcePos.X + sourceSize.Width) * invW,
+ (sourcePos.Y + sourceSize.Height) * invH);
+
+
+ Quad2DVertices[0].Color = color;
+ Quad2DVertices[1].Color = color;
+ Quad2DVertices[2].Color = color;
+ Quad2DVertices[3].Color = color;
+
+ Quad2DVertices[0].Pos = core::vector3df((f32)targetRect.UpperLeftCorner.X, (f32)targetRect.UpperLeftCorner.Y, 0.0f);
+ Quad2DVertices[1].Pos = core::vector3df((f32)targetRect.LowerRightCorner.X, (f32)targetRect.UpperLeftCorner.Y, 0.0f);
+ Quad2DVertices[2].Pos = core::vector3df((f32)targetRect.LowerRightCorner.X, (f32)targetRect.LowerRightCorner.Y, 0.0f);
+ Quad2DVertices[3].Pos = core::vector3df((f32)targetRect.UpperLeftCorner.X, (f32)targetRect.LowerRightCorner.Y, 0.0f);
+
+ Quad2DVertices[0].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
+ Quad2DVertices[1].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
+ Quad2DVertices[2].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
+ Quad2DVertices[3].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
+
+ //SBlitJob job;
+ //transform_for_BlitJob2D(job, Quad2DVertices, renderTargetSize,this);
+
+ setRenderStates2DMode(color, (video::ITexture*) texture, useAlphaChannelOfTexture);
+
+ drawVertexPrimitiveList(Quad2DVertices, 4,
+ quad_triangle_indexList, 2,
+ EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);
+
+ setRenderStates3DMode();
+
}
-//! returns the current render target size
-const core::dimension2d<u32>& CBurningVideoDriver::getCurrentRenderTargetSize() const
-{
- return RenderTargetSize;
+//! Draws a part of the texture into the rectangle.
+void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
+ const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
+ const video::SColor* const colors, bool useAlphaChannelOfTexture)
+{
+ const core::dimension2d<u32>& st = texture->getOriginalSize();
+ const f32 invW = 1.f / static_cast<f32>(st.Width);
+ const f32 invH = 1.f / static_cast<f32>(st.Height);
+ const core::rect<f32> tcoords(
+ sourceRect.UpperLeftCorner.X * invW,
+ sourceRect.UpperLeftCorner.Y * invH,
+ sourceRect.LowerRightCorner.X * invW,
+ sourceRect.LowerRightCorner.Y *invH);
+
+ const video::SColor temp[4] =
+ {
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF,
+ 0xFFFFFFFF
+ };
+
+ const video::SColor* const useColor = colors ? colors : temp;
+
+
+ Quad2DVertices[0].Color = useColor[0];
+ Quad2DVertices[1].Color = useColor[3];
+ Quad2DVertices[2].Color = useColor[2];
+ Quad2DVertices[3].Color = useColor[1];
+
+ Quad2DVertices[0].Pos = core::vector3df((f32)destRect.UpperLeftCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f);
+ Quad2DVertices[1].Pos = core::vector3df((f32)destRect.LowerRightCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f);
+ Quad2DVertices[2].Pos = core::vector3df((f32)destRect.LowerRightCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f);
+ Quad2DVertices[3].Pos = core::vector3df((f32)destRect.UpperLeftCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f);
+
+ Quad2DVertices[0].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
+ Quad2DVertices[1].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
+ Quad2DVertices[2].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
+ Quad2DVertices[3].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
+
+
+ const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
+
+ if (clipRect)
+ {
+ if (!clipRect->isValid())
+ return;
+
+ //glEnable(GL_SCISSOR_TEST);
+ EyeSpace.TL_Flag |= TL_SCISSOR;
+ setScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,
+ clipRect->getWidth(), clipRect->getHeight());
+ }
+
+ video::SColor alphaTest;
+ alphaTest.color = useColor[0].color & useColor[0].color & useColor[0].color & useColor[0].color;
+
+ //SBlitJob job;
+ //transform_for_BlitJob2D(job, Quad2DVertices, renderTargetSize, this);
+
+ setRenderStates2DMode(alphaTest, (video::ITexture*) texture, useAlphaChannelOfTexture);
+
+ drawVertexPrimitiveList(Quad2DVertices, 4,
+ quad_triangle_indexList, 2,
+ EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);
+
+
+ if (clipRect)
+ EyeSpace.TL_Flag &= ~TL_SCISSOR;
+
+ setRenderStates3DMode();
+
+
}
@@ -2017,8 +3378,6 @@ void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position,
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
const core::rect<s32>* clip)
{
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
-
core::rect<s32> pos = position;
if (clip)
@@ -2027,149 +3386,173 @@ void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position,
if (!pos.isValid())
return;
- const core::dimension2d<s32> renderTargetSize ( ViewPort.getSize() );
-
- const s32 xPlus = -(renderTargetSize.Width>>1);
- const f32 xFact = 1.0f / (renderTargetSize.Width>>1);
+ Quad2DVertices[0].Color = colorLeftUp;
+ Quad2DVertices[1].Color = colorRightUp;
+ Quad2DVertices[2].Color = colorRightDown;
+ Quad2DVertices[3].Color = colorLeftDown;
- const s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1);
- const f32 yFact = 1.0f / (renderTargetSize.Height>>1);
+ Quad2DVertices[0].Pos = core::vector3df((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f);
+ Quad2DVertices[1].Pos = core::vector3df((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f);
+ Quad2DVertices[2].Pos = core::vector3df((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f);
+ Quad2DVertices[3].Pos = core::vector3df((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f);
- // fill VertexCache direct
- s4DVertex *v;
+ Quad2DVertices[0].TCoords.X = 0.f;
+ Quad2DVertices[0].TCoords.Y = 0.f;
+ Quad2DVertices[1].TCoords.X = 0.f;
+ Quad2DVertices[1].TCoords.Y = 0.f;
+ Quad2DVertices[2].TCoords.X = 0.f;
+ Quad2DVertices[3].TCoords.Y = 0.f;
+ Quad2DVertices[3].TCoords.X = 0.f;
+ Quad2DVertices[3].TCoords.Y = 0.f;
- VertexCache.vertexCount = 4;
- VertexCache.info[0].index = 0;
- VertexCache.info[1].index = 1;
- VertexCache.info[2].index = 2;
- VertexCache.info[3].index = 3;
+ video::SColor alphaTest;
+ alphaTest.color = colorLeftUp.color & colorRightUp.color & colorRightDown.color & colorLeftDown.color;
+ setRenderStates2DMode(alphaTest, 0, 0);
- v = &VertexCache.mem.data [ 0 ];
+ drawVertexPrimitiveList(Quad2DVertices, 4,
+ quad_triangle_indexList, 2,
+ EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);
- v[0].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f );
- v[0].Color[0].setA8R8G8B8 ( colorLeftUp.color );
+ setRenderStates3DMode();
- v[2].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f );
- v[2].Color[0].setA8R8G8B8 ( colorRightUp.color );
+}
- v[4].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f ,1.f );
- v[4].Color[0].setA8R8G8B8 ( colorRightDown.color );
- v[6].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f, 1.f );
- v[6].Color[0].setA8R8G8B8 ( colorLeftDown.color );
+#endif // SOFTWARE_DRIVER_2_2D_AS_3D
- s32 i;
- u32 g;
- for ( i = 0; i!= 8; i += 2 )
- {
- v[i + 0].flag = clipToFrustumTest ( v + i );
- v[i + 1].flag = 0;
- if ( (v[i].flag & VERTEX4D_INSIDE ) == VERTEX4D_INSIDE )
- {
- ndc_2_dc_and_project ( v + i + 1, v + i, 2 );
- }
- }
- IBurningShader * render;
- render = BurningShader [ ETR_GOURAUD_ALPHA_NOZ ];
- render->setRenderTarget(RenderTargetSurface, ViewPort);
+//! Draws a 2d line.
+void CBurningVideoDriver::draw2DLine(const core::position2d<s32>& start,
+ const core::position2d<s32>& end,
+ SColor color)
+{
+ drawLine(RenderTargetSurface, start, end, color );
+}
- static const s16 indexList[6] = {0,1,2,0,2,3};
- s4DVertex * face[3];
+//! Draws a pixel
+void CBurningVideoDriver::drawPixel(u32 x, u32 y, const SColor & color)
+{
+ RenderTargetSurface->setPixel(x, y, color, true);
+}
- for ( i = 0; i!= 6; i += 3 )
- {
- face[0] = VertexCache_getVertex ( indexList [ i + 0 ] );
- face[1] = VertexCache_getVertex ( indexList [ i + 1 ] );
- face[2] = VertexCache_getVertex ( indexList [ i + 2 ] );
- // test clipping
- u32 test = face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_INSIDE;
+//! Only used by the internal engine. Used to notify the driver that
+//! the window was resized.
+void CBurningVideoDriver::OnResize(const core::dimension2d<u32>& size)
+{
+ // make sure width and height are multiples of 2
+ core::dimension2d<u32> realSize(size);
+/*
+ if (realSize.Width % 2)
+ realSize.Width += 1;
- if ( test == VERTEX4D_INSIDE )
+ if (realSize.Height % 2)
+ realSize.Height += 1;
+*/
+ if (ScreenSize != realSize)
+ {
+ if (ViewPort.getWidth() == (s32)ScreenSize.Width &&
+ ViewPort.getHeight() == (s32)ScreenSize.Height)
{
- render->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 );
- continue;
+ ViewPort.UpperLeftCorner.X = 0;
+ ViewPort.UpperLeftCorner.Y = 0;
+ ViewPort.LowerRightCorner.X = realSize.Width;
+ ViewPort.LowerRightCorner.X = realSize.Height;
}
- // Todo: all vertices are clipped in 2d..
- // is this true ?
- u32 vOut = 6;
- memcpy ( CurrentOut.data + 0, face[0], sizeof ( s4DVertex ) * 2 );
- memcpy ( CurrentOut.data + 2, face[1], sizeof ( s4DVertex ) * 2 );
- memcpy ( CurrentOut.data + 4, face[2], sizeof ( s4DVertex ) * 2 );
-
- vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 );
- if ( vOut < 3 )
- continue;
- vOut <<= 1;
- // to DC Space, project homogenous vertex
- ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );
+ ScreenSize = realSize;
- // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )
- for ( g = 0; g <= vOut - 6; g += 2 )
- {
- // rasterize
- render->drawTriangle ( CurrentOut.data + 1, &CurrentOut.data[g + 3], &CurrentOut.data[g + 5] );
- }
+ bool resetRT = (RenderTargetSurface == BackBuffer);
+ if (BackBuffer)
+ BackBuffer->drop();
+ BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, realSize);
+
+ if (resetRT)
+ setRenderTargetImage(BackBuffer);
}
-#else
- draw2DRectangle ( colorLeftUp, position, clip );
-#endif
+}
+
+
+//! returns the current render target size
+const core::dimension2d<u32>& CBurningVideoDriver::getCurrentRenderTargetSize() const
+{
+ return RenderTargetSize;
}
//! Draws a 3d line.
void CBurningVideoDriver::draw3DLine(const core::vector3df& start,
- const core::vector3df& end, SColor color)
+ const core::vector3df& end, SColor color_start)
{
- Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[0].Pos.x, start );
- Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[2].Pos.x, end );
+ SColor color_end = color_start;
+
+ VertexCache.primitiveHasVertex = 2;
+ VertexCache.vType = E4VT_LINE;
+
+ s4DVertex* v = Clipper.data;
- u32 g;
- u32 vOut;
+ transform_calc(ETS_PROJ_MODEL_VIEW);
+ const core::matrix4* matrix = Transformation[TransformationStack];
+ matrix[ETS_PROJ_MODEL_VIEW].transformVect ( &v[0].Pos.x, start );
+ matrix[ETS_PROJ_MODEL_VIEW].transformVect ( &v[2].Pos.x, end );
+
+#if BURNING_MATERIAL_MAX_COLORS > 0
+ v[0].Color[0].setA8R8G8B8 ( color_start.color );
+ v[2].Color[0].setA8R8G8B8 ( color_end.color );
+#endif
- // no clipping flags
- for ( g = 0; g != CurrentOut.ElementSize; ++g )
+ u32 i;
+ for (i = 0; i < 4; i += sizeof_s4DVertexPairRel)
{
- CurrentOut.data[g].flag = 0;
- Temp.data[g].flag = 0;
+ v[i + 0].flag = (u32)(VertexCache.vSize[VertexCache.vType].Format);
+ v[i + 1].flag = v[i + 0].flag;
}
+
+ size_t g;
+ size_t vOut;
+
// vertices count per line
- vOut = clipToFrustum ( CurrentOut.data, Temp.data, 2 );
- if ( vOut < 2 )
+ vOut = clipToFrustum (VertexCache.primitiveHasVertex);
+ if ( vOut < VertexCache.primitiveHasVertex)
return;
- vOut <<= 1;
-
- IBurningShader * line;
- line = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ];
- line->setRenderTarget(RenderTargetSurface, ViewPort);
+ vOut *= sizeof_s4DVertexPairRel;
// to DC Space, project homogenous vertex
- ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );
+ ndc_2_dc_and_project ( v + 1, v, vOut );
// unproject vertex color
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if 0
+#if BURNING_MATERIAL_MAX_COLORS > 0
for ( g = 0; g != vOut; g+= 2 )
{
- CurrentOut.data[ g + 1].Color[0].setA8R8G8B8 ( color.color );
+ v[ g + 1].Color[0].setA8R8G8B8 ( color.color );
}
#endif
+#endif
+
+ IBurningShader * shader = 0;
+ if ( CurrentShader && CurrentShader->canWireFrame() ) shader = CurrentShader;
+ else shader = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ];
+ shader = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ];
+ shader->pushEdgeTest(1,0,1);
+ shader->setRenderTarget(RenderTargetSurface, ViewPort);
- for ( g = 0; g <= vOut - 4; g += 2 )
+ for ( g = 0; g <= vOut - 4; g += sizeof_s4DVertexPairRel)
{
- // rasterize
- line->drawLine ( CurrentOut.data + 1, CurrentOut.data + g + 3 );
+ shader->drawLine ( v + 1 + g, v + 1 + g + sizeof_s4DVertexPairRel);
}
+
+ shader->popEdgeTest();
+
}
@@ -2178,20 +3561,22 @@ void CBurningVideoDriver::draw3DLine(const core::vector3df& start,
const wchar_t* CBurningVideoDriver::getName() const
{
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
- return L"Burning's Video 0.49 beautiful";
+ return L"Burning's Video 0.51 beautiful";
#elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST )
- return L"Burning's Video 0.49 ultra fast";
+ return L"Burning's Video 0.51 ultra fast";
#elif defined ( BURNINGVIDEO_RENDERER_FAST )
- return L"Burning's Video 0.49 fast";
+ return L"Burning's Video 0.51 fast";
+#elif defined ( BURNINGVIDEO_RENDERER_CE )
+ return L"Burning's Video 0.51 CE";
#else
- return L"Burning's Video 0.49";
+ return L"Burning's Video 0.51";
#endif
}
//! Returns the graphics card vendor name.
core::stringc CBurningVideoDriver::getVendorInfo()
{
- return "Burning's Video: Ing. Thomas Alten (c) 2006-2015";
+ return "Burning's Video: Ing. Thomas Alten (c) 2006-2020";
}
@@ -2209,19 +3594,12 @@ ECOLOR_FORMAT CBurningVideoDriver::getColorFormat() const
}
-//! Returns the transformation set by setTransform
-const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const
-{
- return Transformation[state];
-}
-
-
//! Creates a render target texture.
ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format)
{
IImage* img = createImage(BURNINGSHADER_COLOR_FORMAT, size);
- ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET );
+ ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET,this);
img->drop();
addTexture(tex);
tex->drop();
@@ -2234,12 +3612,31 @@ void CBurningVideoDriver::clearBuffers(u16 flag, SColor color, f32 depth, u8 ste
RenderTargetSurface->fill(color);
if ((flag & ECBF_DEPTH) && DepthBuffer)
- DepthBuffer->clear();
+ DepthBuffer->clear(depth);
if ((flag & ECBF_STENCIL) && StencilBuffer)
- StencilBuffer->clear();
+ StencilBuffer->clear(stencil);
}
+#if 0
+void CBurningVideoDriver::saveBuffer()
+{
+ static int shotCount = 0;
+ char buf[256];
+ if (BackBuffer)
+ {
+ sprintf(buf, "shot/%04d_b.png", shotCount);
+ writeImageToFile(BackBuffer, buf);
+ }
+ if (StencilBuffer)
+ {
+ CImage stencil(ECF_A8R8G8B8, StencilBuffer->getSize(), StencilBuffer->lock(), true, false);
+ sprintf(buf, "shot/%04d_s.ppm", shotCount);
+ writeImageToFile(&stencil, buf);
+ }
+ shotCount += 1;
+}
+#endif
//! Returns an image created from the last rendered frame.
IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
@@ -2259,9 +3656,17 @@ IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video
ITexture* CBurningVideoDriver::createDeviceDependentTexture(const io::path& name, IImage* image)
{
- CSoftwareTexture2* texture = new CSoftwareTexture2(image, name, (getTextureCreationFlag(ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0) |
- (getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2) ? 0 : CSoftwareTexture2::NP2_SIZE));
+ u32 flags =
+ ((TextureCreationFlags & ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0)
+ | ((TextureCreationFlags & ETCF_AUTO_GENERATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP_AUTO : 0)
+ | ((TextureCreationFlags & ETCF_ALLOW_NON_POWER_2) ? CSoftwareTexture2::ALLOW_NPOT : 0)
+#if defined(IRRLICHT_sRGB)
+ | ((TextureCreationFlags & ETCF_IMAGE_IS_LINEAR) ? CSoftwareTexture2::IMAGE_IS_LINEAR : 0)
+ | ((TextureCreationFlags & ETCF_TEXTURE_IS_LINEAR) ? CSoftwareTexture2::TEXTURE_IS_LINEAR : 0)
+#endif
+ ;
+ CSoftwareTexture2* texture = new CSoftwareTexture2(image, name, flags, this);
return texture;
}
@@ -2275,7 +3680,7 @@ ITexture* CBurningVideoDriver::createDeviceDependentTextureCubemap(const io::pat
//! call.
u32 CBurningVideoDriver::getMaximalPrimitiveCount() const
{
- return 0xFFFFFFFF;
+ return 0x7FFFFFFF;
}
@@ -2285,58 +3690,61 @@ u32 CBurningVideoDriver::getMaximalPrimitiveCount() const
void CBurningVideoDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)
{
const u32 count = triangles.size();
- IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ];
-
- CurrentShader = shader;
- shader->setRenderTarget(RenderTargetSurface, ViewPort);
+ if (!StencilBuffer || !count)
+ return;
Material.org.MaterialType = video::EMT_SOLID;
Material.org.Lighting = false;
Material.org.ZWriteEnable = video::EZW_OFF;
- Material.org.ZBuffer = ECFN_LESSEQUAL;
- LightSpace.Flags &= ~VERTEXTRANSFORM;
+ Material.org.ZBuffer = ECFN_LESS;
+
+ CurrentShader = BurningShader[ETR_STENCIL_SHADOW];
+ CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);
+ CurrentShader->pushEdgeTest(Material.org.Wireframe, 0,0);
+
+ //setMaterial
+ EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP);
+ CurrentShader->setTLFlag(EyeSpace.TL_Flag);
//glStencilMask(~0);
//glStencilFunc(GL_ALWAYS, 0, ~0);
- if (true)// zpass does not work yet
+ //glEnable(GL_DEPTH_CLAMP);
+
+ if (zfail)
{
+ Material.org.BackfaceCulling = false;
+ Material.org.FrontfaceCulling = true;
+ Material.CullFlag = CULL_FRONT | CULL_INVISIBLE;
+
+ CurrentShader->setStencilOp( StencilOp_KEEP, StencilOp_INCR, StencilOp_KEEP);
+ drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);
+
Material.org.BackfaceCulling = true;
Material.org.FrontfaceCulling = false;
- shader->setParam ( 0, 0 );
- shader->setParam ( 1, 1 );
- shader->setParam ( 2, 0 );
- drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 );
- //glStencilOp(GL_KEEP, incr, GL_KEEP);
- //glDrawArrays(GL_TRIANGLES,0,count);
+ Material.CullFlag = CULL_BACK | CULL_INVISIBLE;
- Material.org.BackfaceCulling = false;
- Material.org.FrontfaceCulling = true;
- shader->setParam ( 0, 0 );
- shader->setParam ( 1, 2 );
- shader->setParam ( 2, 0 );
- drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 );
- //glStencilOp(GL_KEEP, decr, GL_KEEP);
- //glDrawArrays(GL_TRIANGLES,0,count);
+ CurrentShader->setStencilOp( StencilOp_KEEP, StencilOp_DECR, StencilOp_KEEP);
+ drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);
}
else // zpass
{
Material.org.BackfaceCulling = true;
Material.org.FrontfaceCulling = false;
- shader->setParam ( 0, 0 );
- shader->setParam ( 1, 0 );
- shader->setParam ( 2, 1 );
- //glStencilOp(GL_KEEP, GL_KEEP, incr);
- //glDrawArrays(GL_TRIANGLES,0,count);
+ Material.CullFlag = CULL_BACK | CULL_INVISIBLE;
+
+ CurrentShader->setStencilOp( StencilOp_KEEP, StencilOp_KEEP, StencilOp_INCR);
+ drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);
Material.org.BackfaceCulling = false;
Material.org.FrontfaceCulling = true;
- shader->setParam ( 0, 0 );
- shader->setParam ( 1, 0 );
- shader->setParam ( 2, 2 );
- //glStencilOp(GL_KEEP, GL_KEEP, decr);
- //glDrawArrays(GL_TRIANGLES,0,count);
+ Material.CullFlag = CULL_FRONT | CULL_INVISIBLE;
+
+ CurrentShader->setStencilOp(StencilOp_KEEP, StencilOp_KEEP, StencilOp_DECR);
+ drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);
}
+ //glDisable(GL_DEPTH_CLAMP);
+
}
//! Fills the stencil shadow with color. After the shadow volume has been drawn
@@ -2351,30 +3759,44 @@ void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SCol
const u32 h = RenderTargetSurface->getDimension().Height;
const u32 w = RenderTargetSurface->getDimension().Width;
tVideoSample *dst;
- u32 *stencil;
- u32* const stencilBase=(u32*) StencilBuffer->lock();
+ const tStencilSample* stencil;
+
+#if defined(SOFTWARE_DRIVER_2_32BIT)
+ const u32 alpha = extractAlpha(leftUpEdge.color);
+ const u32 src = leftUpEdge.color;
+#else
+ const u16 alpha = extractAlpha( leftUpEdge.color ) >> 3;
+ const u32 src = video::A8R8G8B8toA1R5G5B5( leftUpEdge.color );
+#endif
+
for ( u32 y = 0; y < h; ++y )
{
dst = (tVideoSample*)RenderTargetSurface->getData() + ( y * w );
- stencil = stencilBase + ( y * w );
+ stencil = (tStencilSample*)StencilBuffer->lock() + (y * w);
for ( u32 x = 0; x < w; ++x )
{
- if ( stencil[x] > 1 )
+ if ( stencil[x] )
{
- dst[x] = PixelBlend32 ( dst[x], leftUpEdge.color );
+#if defined(SOFTWARE_DRIVER_2_32BIT)
+ dst[x] = PixelBlend32 ( dst[x], src,alpha );
+#else
+ dst[x] = PixelBlend16( dst[x], src, alpha );
+#endif
}
}
}
- StencilBuffer->clear();
+ if ( clearStencilBuffer )
+ StencilBuffer->clear(0);
}
core::dimension2du CBurningVideoDriver::getMaxTextureSize() const
{
- return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE);
+ return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1 << 20,
+ SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1 << 20);
}
bool CBurningVideoDriver::queryTextureFormat(ECOLOR_FORMAT format) const
@@ -2384,50 +3806,140 @@ bool CBurningVideoDriver::queryTextureFormat(ECOLOR_FORMAT format) const
bool CBurningVideoDriver::needsTransparentRenderPass(const irr::video::SMaterial& material) const
{
- return CNullDriver::needsTransparentRenderPass(material) || material.isTransparent();
+ return CNullDriver::needsTransparentRenderPass(material) || material.isAlphaBlendOperation(); // || material.isTransparent();
}
+s32 CBurningVideoDriver::addShaderMaterial(const c8* vertexShaderProgram,
+ const c8* pixelShaderProgram,
+ IShaderConstantSetCallBack* callback,
+ E_MATERIAL_TYPE baseMaterial,
+ s32 userData)
+{
+ s32 materialID = -1;
-} // end namespace video
-} // end namespace irr
+ IBurningShader* shader = new IBurningShader(
+ this, materialID,
+ vertexShaderProgram, 0, video::EVST_VS_1_1,
+ pixelShaderProgram, 0, video::EPST_PS_1_1,
+ 0, 0, EGST_GS_4_0,
+ scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,
+ callback, baseMaterial, userData);
-#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
+ shader->drop();
+ return materialID;
+}
+
+//! Adds a new material renderer to the VideoDriver, based on a high level shading language.
+s32 CBurningVideoDriver::addHighLevelShaderMaterial(
+ const c8* vertexShaderProgram,
+ const c8* vertexShaderEntryPointName,
+ E_VERTEX_SHADER_TYPE vsCompileTarget,
+ const c8* pixelShaderProgram,
+ const c8* pixelShaderEntryPointName,
+ E_PIXEL_SHADER_TYPE psCompileTarget,
+ const c8* geometryShaderProgram,
+ const c8* geometryShaderEntryPointName,
+ E_GEOMETRY_SHADER_TYPE gsCompileTarget,
+ scene::E_PRIMITIVE_TYPE inType,
+ scene::E_PRIMITIVE_TYPE outType,
+ u32 verticesOut,
+ IShaderConstantSetCallBack* callback,
+ E_MATERIAL_TYPE baseMaterial,
+ s32 userData
+ )
+{
+ s32 materialID = -1;
+
+ IBurningShader* shader = new IBurningShader(
+ this, materialID,
+ vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,
+ pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
+ geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
+ inType, outType, verticesOut,
+ callback, baseMaterial, userData);
+
+ shader->drop();
+
+ return materialID;
+}
-#if defined(_IRR_WINDOWS_) && defined(_IRR_COMPILE_WITH_BURNINGSVIDEO_)
- #include <windows.h>
-struct dreadglobal
+void CBurningVideoDriver::setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType)
{
- DWORD dreadid;
- HANDLE dread;
- irr::video::CBurningVideoDriver *driver;
- HANDLE sync;
+ //this should be in material....
+ Material.Fallback_MaterialType = fallback_MaterialType;
+}
- const irr::SIrrlichtCreationParameters* params;
- irr::io::IFileSystem* io;
- irr::video::IImagePresenter* presenter;
-};
+void CBurningVideoDriver::setBasicRenderStates(const SMaterial& material,
+ const SMaterial& lastMaterial,
+ bool resetAllRenderstates)
+{
-namespace
+}
+
+//! Return an index constant for the vertex shader based on a name.
+s32 CBurningVideoDriver::getVertexShaderConstantID(const c8* name)
{
- dreadglobal burning_dread;
+ return -1;
}
-DWORD WINAPI dreadFun( void *p)
+bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const f32* floats, int count)
{
- printf("Hi This is burning dread\n");
- burning_dread.driver = new irr::video::CBurningVideoDriver(*burning_dread.params, burning_dread.io, burning_dread.presenter);
+ return true;
+}
- SetEvent (burning_dread.sync );
- while ( 1 )
- {
- Sleep ( 1000 );
- }
- return 0;
+bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const s32* ints, int count)
+{
+ return true;
}
-#endif
+bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const u32* ints, int count)
+{
+ return true;
+}
+
+void CBurningVideoDriver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
+{
+}
+
+//! Return an index constant for the pixel shader based on a name.
+s32 CBurningVideoDriver::getPixelShaderConstantID(const c8* name)
+{
+ return -1;
+}
+
+bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const f32* floats, int count)
+{
+ return false;
+}
+
+bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const s32* ints, int count)
+{
+ return false;
+}
+
+bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const u32* ints, int count)
+{
+ return false;
+}
+
+void CBurningVideoDriver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1)
+{
+}
+
+//! Get pointer to the IVideoDriver interface
+/** \return Pointer to the IVideoDriver interface */
+IVideoDriver* CBurningVideoDriver::getVideoDriver()
+{
+ return this;
+}
+
+} // end namespace video
+} // end namespace irr
+
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
+
namespace irr
{
@@ -2438,21 +3950,9 @@ namespace video
IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
-
- #ifdef _IRR_WINDOWS_
- burning_dread.sync = CreateEventA ( 0, 0, 0, "burnevent0" );
- burning_dread.params = &params;
- burning_dread.io = io;
- burning_dread.presenter = presenter;
- burning_dread.dread = CreateThread ( 0, 0, dreadFun, 0, 0, &burning_dread.dreadid );
- WaitForSingleObject (burning_dread.sync, INFINITE );
- return burning_dread.driver;
+ return new CBurningVideoDriver(params, io, presenter);
#else
- return new CBurningVideoDriver(params, io, presenter);
- #endif
-
- #else
- return 0;
+ return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
diff --git a/source/Irrlicht/CSoftwareDriver2.h b/source/Irrlicht/CSoftwareDriver2.h
index 3e9d2aa..803deae 100644
--- a/source/Irrlicht/CSoftwareDriver2.h
+++ b/source/Irrlicht/CSoftwareDriver2.h
@@ -13,11 +13,12 @@
#include "irrString.h"
#include "SIrrCreationParameters.h"
+
namespace irr
{
namespace video
{
- class CBurningVideoDriver : public CNullDriver
+ class CBurningVideoDriver : public CNullDriver, public IMaterialRendererServices
{
public:
@@ -39,14 +40,15 @@ namespace video
//! sets a material
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
- virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
- f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
+ virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor,
+ f32 clearDepth, u8 clearStencil) _IRR_OVERRIDE_;
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
+ virtual void setScissor(int x, int y, int width, int height);
- virtual bool beginScene(u16 clearFlag, SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0,
- const SExposedVideoData& videoData = SExposedVideoData(), core::rect<s32>* sourceRect = 0) _IRR_OVERRIDE_;
+ virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil,
+ const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_;
virtual bool endScene() _IRR_OVERRIDE_;
@@ -83,23 +85,44 @@ namespace video
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;
+ //! draws a vertex primitive list in 2d
+ virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,
+ const void* indexList, u32 primitiveCount,
+ E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;
+
+
+ //! draws an 2d image
+ //virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, bool useAlphaChannelOfTexture) _IRR_OVERRIDE_;
+
+ /* NullDriver calls
+ draw2DImage(texture, destPos,
+ core::rect<s32>(core::position2d<s32>(0, 0), core::dimension2di(texture->getOriginalSize())),
+ 0,
+ SColor(255, 255, 255, 255),
+ useAlphaChannelOfTexture
+ */
+
//! 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.
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
- //! Draws a part of the texture into the rectangle.
+ //! Draws a part of the texture into the rectangle.
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
//! Draws a 3d line.
virtual void draw3DLine(const core::vector3df& start,
- const core::vector3df& end, SColor color = SColor(255,255,255,255)) _IRR_OVERRIDE_;
+ const core::vector3df& end, SColor color_start) _IRR_OVERRIDE_;
//! draw an 2d rectangle
- virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
- const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;
+ //virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
+ // const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;
+
+ /* NullDriver calls
+ draw2DRectangle(pos, color, color, color, color, clip);
+ */
//!Draws an 2d rectangle with a gradient.
virtual void draw2DRectangle(const core::rect<s32>& pos,
@@ -131,7 +154,7 @@ namespace video
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;
- virtual void clearBuffers(u16 flag, SColor color = SColor(255,0,0,0), f32 depth = 1.f, u8 stencil = 0) _IRR_OVERRIDE_;
+ virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_;
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) _IRR_OVERRIDE_;
@@ -155,6 +178,9 @@ namespace video
video::SColor leftDownEdge = video::SColor(0,0,0,0),
video::SColor rightDownEdge = video::SColor(0,0,0,0)) _IRR_OVERRIDE_;
+ //! Enable the 2d override material
+ virtual void enableMaterial2D(bool enable = true) _IRR_OVERRIDE_;
+
//! Returns the graphics card vendor name.
virtual core::stringc getVendorInfo() _IRR_OVERRIDE_;
@@ -170,8 +196,70 @@ namespace video
IDepthBuffer * getDepthBuffer () { return DepthBuffer; }
IStencilBuffer * getStencilBuffer () { return StencilBuffer; }
+ //#define Tweak_Burning
+#if defined(Tweak_Burning)
+ virtual void postEventFromUser(const void* sevent) _IRR_OVERRIDE_;
+#endif
+
+ //! Adds a new material renderer to the VideoDriver, using pixel and/or
+ //! vertex shaders to render geometry.
+ virtual s32 addShaderMaterial(const c8* vertexShaderProgram,
+ const c8* pixelShaderProgram,
+ IShaderConstantSetCallBack* callback,
+ E_MATERIAL_TYPE baseMaterial,
+ s32 userData) _IRR_OVERRIDE_;
+
+ //! Adds a new material renderer to the VideoDriver, based on a high level shading
+ //! language. Currently only HLSL in D3D9 is supported.
+ virtual s32 addHighLevelShaderMaterial(
+ const c8* vertexShaderProgram,
+ const c8* vertexShaderEntryPointName = 0,
+ E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
+ const c8* pixelShaderProgram = 0,
+ const c8* pixelShaderEntryPointName = 0,
+ E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
+ const c8* geometryShaderProgram = 0,
+ const c8* geometryShaderEntryPointName = "main",
+ E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
+ scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
+ scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
+ u32 verticesOut = 0,
+ IShaderConstantSetCallBack* callback = 0,
+ E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
+ s32 userData = 0) _IRR_OVERRIDE_;
+
+ //IMaterialRendererService
+
+ virtual void setBasicRenderStates(const SMaterial& material,
+ const SMaterial& lastMaterial,
+ bool resetAllRenderstates) _IRR_OVERRIDE_;
+
+ //pass BaseMaterialID
+ void setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType);
+
+ //! Return an index constant for the vertex shader based on a name.
+ virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;
+ virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
+ virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
+ virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
+ virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;
+
+ //! Return an index constant for the pixel shader based on a name.
+ virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;
+ virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
+ virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
+ virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
+
+ virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;
+
+ //! Get pointer to the IVideoDriver interface
+ /** \return Pointer to the IVideoDriver interface */
+ virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
+
protected:
+ void saveBuffer();
+
//! sets a render target
void setRenderTargetImage(video::CImage* image);
@@ -191,9 +279,6 @@ namespace video
video::IImage* RenderTargetSurface;
core::dimension2d<u32> RenderTargetSize;
- //! selects the right triangle renderer based on the render states.
- void setCurrentShader();
-
IBurningShader* CurrentShader;
IBurningShader* BurningShader[ETR2_COUNT];
@@ -210,78 +295,89 @@ namespace video
enum E_TRANSFORMATION_STATE_BURNING_VIDEO
{
ETS_VIEW_PROJECTION = ETS_COUNT,
- ETS_CURRENT,
- ETS_CLIPSCALE,
- ETS_VIEW_INVERSE,
- ETS_WORLD_INVERSE,
+ ETS_PROJ_MODEL_VIEW,
+ ETS_MODEL_VIEW,
+ ETS_NORMAL, //3x3 ModelView Tansposed Inverse
- ETS_COUNT_BURNING
+ ETS_COUNT_BURNING = 16
};
enum E_TRANSFORMATION_FLAG
{
- ETF_IDENTITY = 1,
- ETF_TEXGEN_CAMERA_NORMAL = 2,
- ETF_TEXGEN_CAMERA_REFLECTION = 4,
+ ETF_VALID = 1,
+ ETF_IDENTITY = 2,
+ ETF_TEXGEN_CAMERA_SPHERE = 4,
+ ETF_TEXGEN_CAMERA_REFLECTION = 8,
+ ETF_TEXGEN_WRAP = 16,
+ ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP
};
- u32 TransformationFlag[ETS_COUNT_BURNING];
- core::matrix4 Transformation[ETS_COUNT_BURNING];
+ core::matrix4 Transformation[2][ETS_COUNT_BURNING];
+ size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG
- void getCameraPosWorldSpace ();
- void getLightPosObjectSpace ();
+ size_t TransformationStack; // 0 .. 3D , 1 .. 2D
+ void setRenderStates2DMode(const video::SColor& color,video::ITexture* texture,bool useAlphaChannelOfTexture);
+ void setRenderStates3DMode();
- // Vertex Cache
- static const SVSize vSize[];
+ //ETS_CLIPSCALE, // moved outside to stay at 16 matrices
+ f32 Transformation_ETS_CLIPSCALE[2][4];
+ void transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state);
+
+ //core::recti ViewPort;
+ AbsRectangle Scissor;
+ // Vertex Cache
SVertexCache VertexCache;
- void VertexCache_reset (const void* vertices, u32 vertexCount,
+ int VertexCache_reset (const void* vertices, u32 vertexCount,
const void* indices, u32 indexCount,
E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType);
- void VertexCache_get ( const s4DVertex ** face );
- void VertexCache_getbypass ( s4DVertex ** face );
+ void VertexCache_get (s4DVertexPair* face[4] );
+ void VertexCache_map_source_format();
void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex );
- s4DVertex * VertexCache_getVertex ( const u32 sourceIndex );
+ s4DVertexPair* VertexCache_getVertex ( const u32 sourceIndex ) const;
// culling & clipping
- u32 clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane );
- u32 clipToFrustumTest ( const s4DVertex * v ) const;
- u32 clipToFrustum ( s4DVertex *source, s4DVertex * temp, const u32 vIn );
+ //size_t inline clipToHyperPlane (s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, const size_t inCount, const sVec4 &plane );
+ //size_t inline clipToFrustumTest ( const s4DVertex * v ) const;
+ public:
+ size_t clipToFrustum( const size_t vIn /*, const size_t clipmask_for_face*/ );
+ protected:
+
+ // holds transformed, clipped vertices for a triangle. triangle expands on clipping
+ // Buffer is in in pairs of 4DVertex (0 ... ndc, 1 .. dc and projected)
+ SAligned4DVertex Clipper;
+ SAligned4DVertex Clipper_temp;
#ifdef SOFTWARE_DRIVER_2_LIGHTING
+ void lightVertex_eye ( s4DVertex *dest, u32 vertexargb );
+#endif
- void lightVertex ( s4DVertex *dest, u32 vertexargb );
//! Sets the fog mode.
virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start,
f32 end, f32 density, bool pixelFog, bool rangeFog) _IRR_OVERRIDE_;
-#endif
- // holds transformed, clipped vertices
- SAlignedVertex CurrentOut;
- SAlignedVertex Temp;
+ void ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair* source, const size_t vIn ) const;
- void ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const;
- f32 screenarea ( const s4DVertex *v0 ) const;
- void select_polygon_mipmap ( s4DVertex *source, u32 vIn, u32 tex, const core::dimension2du& texSize ) const;
- f32 texelarea ( const s4DVertex *v0, int tex ) const;
+ //const is misleading. **v is const that true, but not *v..
+ f32 screenarea_inside (const s4DVertexPair* burning_restrict const face[] ) const;
+ s32 lodFactor_inside ( const s4DVertexPair* burning_restrict const face[], const size_t tex, f32 dc_area, f32 lod_bias ) const;
+ void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const;
+ void getCameraPosWorldSpace();
+ SBurningShaderEyeSpace EyeSpace;
+ SBurningShaderMaterial Material;
- void ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const;
- f32 screenarea2 ( const s4DVertex **v ) const;
- f32 texelarea2 ( const s4DVertex **v, int tex ) const;
- void select_polygon_mipmap2 ( s4DVertex **source, u32 tex, const core::dimension2du& texSize ) const;
-
+ static const sVec4 NDCPlane[6+2];
- SBurningShaderLightSpace LightSpace;
- SBurningShaderMaterial Material;
+ //! Built-in 2D quad for 2D rendering.
+ S3DVertex Quad2DVertices[4];
- static const sVec4 NDCPlane[6];
};
} // end namespace video
diff --git a/source/Irrlicht/CSoftwareTexture2.cpp b/source/Irrlicht/CSoftwareTexture2.cpp
index 44a7e6b..b17e462 100644
--- a/source/Irrlicht/CSoftwareTexture2.cpp
+++ b/source/Irrlicht/CSoftwareTexture2.cpp
@@ -9,6 +9,7 @@
#include "SoftwareDriver2_helper.h"
#include "CSoftwareTexture2.h"
#include "CSoftwareDriver2.h"
+#include "CBlit.h"
#include "os.h"
namespace irr
@@ -16,125 +17,204 @@ namespace irr
namespace video
{
+//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)
+void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, const video::IImage* src, const core::rect<s32>* srcRect, size_t flags);
+
//! constructor
-CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags)
- : ITexture(name, ETT_2D), MipMapLOD(0), Flags ( flags ), OriginalFormat(video::ECF_UNKNOWN)
+CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver)
+ : ITexture(name
+#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
+ , ETT_2D
+#endif
+ )
+ ,MipMapLOD(0), Flags(flags), Driver(driver)
{
#ifdef _DEBUG
setDebugName("CSoftwareTexture2");
#endif
#ifndef SOFTWARE_DRIVER_2_MIPMAPPING
- Flags &= ~GEN_MIPMAP;
+ Flags &= ~(GEN_MIPMAP| GEN_MIPMAP_AUTO);
#endif
-
+ //set baseclass properties
DriverType = EDT_BURNINGSVIDEO;
ColorFormat = BURNINGSHADER_COLOR_FORMAT;
IsRenderTarget = (Flags & IS_RENDERTARGET) != 0;
-
- memset32 ( MipMap, 0, sizeof ( MipMap ) );
-
- if (image)
+ HasMipMaps = (Flags & GEN_MIPMAP) != 0;
+ MipMap0_Area[0] = 1;
+ MipMap0_Area[1] = 1;
+ LodBIAS = 0.75f;
+ for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) MipMap[i] = 0;
+ if (!image) return;
+
+ OriginalSize = image->getDimension();
+ OriginalColorFormat = image->getColorFormat();
+
+
+#if defined(IRRLICHT_sRGB)
+ if ( Flags & IMAGE_IS_LINEAR ) image->set_sRGB(0);
+#else
+ //guessing linear image
+ if (name.find("light") >= 0 ||
+ name.find("bump") >= 0 ||
+ name.find("height") >= 0
+ )
{
- bool IsCompressed = false;
-
- if (IImage::isCompressedFormat(image->getColorFormat()))
- {
- os::Printer::log("Texture compression not available.", ELL_ERROR);
- IsCompressed = true;
- }
-
- OriginalSize = image->getDimension();
- OriginalFormat = image->getColorFormat();
-
- core::dimension2d<u32> optSize(
- OriginalSize.getOptimalSize(0 != (Flags & NP2_SIZE),
- false, true,
- SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE)
- );
+ Flags |= TEXTURE_IS_LINEAR | IMAGE_IS_LINEAR;
+ }
+#endif
- if (OriginalSize == optSize)
- {
- MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());
+ bool isCompressed = IImage::isCompressedFormat(OriginalColorFormat);
+ if (isCompressed)
+ {
+ os::Printer::log("Texture compression not available.", ELL_ERROR);
+ }
- if (!IsCompressed)
- image->copyTo(MipMap[0]);
- }
- else
+ //visual studio code warning
+ u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE;
+ core::dimension2d<u32> optSize( OriginalSize.getOptimalSize(
+ (Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo
+ false, // requireSquare
+ (Flags & ALLOW_NPOT) ? 1 : maxTexSize == 0, // larger
+ (Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue
+ )
+ );
+
+ if (OriginalSize == optSize)
+ {
+ MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());
+#if defined(IRRLICHT_sRGB)
+ MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() );
+#endif
+ if (!isCompressed)
+ image->copyTo(MipMap[0]);
+ }
+ else
+ {
+ char buf[256];
+ core::stringw showName ( name );
+ snprintf_irr ( buf, sizeof(buf), "Burningvideo: Warning Texture %ls reformat %ux%u,%d -> %ux%u,%d",
+ showName.c_str(),
+ OriginalSize.Width, OriginalSize.Height, OriginalColorFormat,
+ optSize.Width, optSize.Height,BURNINGSHADER_COLOR_FORMAT
+ );
+
+ os::Printer::log ( buf, ELL_WARNING );
+ MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);
+#if defined(IRRLICHT_sRGB)
+ MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() );
+#endif
+ if (!isCompressed)
{
- char buf[256];
- core::stringw showName ( name );
- snprintf_irr ( buf, 256, "Burningvideo: Warning Texture %ls reformat %dx%d -> %dx%d,%d",
- showName.c_str(),
- OriginalSize.Width, OriginalSize.Height, optSize.Width, optSize.Height,
- BURNINGSHADER_COLOR_FORMAT
- );
-
- OriginalSize = optSize;
- os::Printer::log ( buf, ELL_WARNING );
- MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);
-
- if (!IsCompressed)
- image->copyToScalingBoxFilter ( MipMap[0],0, false );
+ //image->copyToScalingBoxFilter ( MipMap[0],0, false );
+ Resample_subSampling(BLITTER_TEXTURE,MipMap[0],0,image,0, Flags);
}
-
- Size = MipMap[MipMapLOD]->getDimension();
- Pitch = MipMap[MipMapLOD]->getPitch();
-
- OrigImageDataSizeInPixels = (f32) 0.3f * MipMap[0]->getImageDataSizeInPixels();
-
- HasMipMaps = (Flags & GEN_MIPMAP) != 0;
-
- regenerateMipMapLevels(image->getMipMapsData());
+ // if Original Size is used for calculation ( 2D position, font) it will be wrong
+ //OriginalSize = optSize;
}
+
+ //select highest mipmap 0
+ regenerateMipMapLevels(image->getMipMapsData());
}
//! destructor
CSoftwareTexture2::~CSoftwareTexture2()
{
- for ( s32 i = 0; i!= SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
+ for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
{
if ( MipMap[i] )
+ {
MipMap[i]->drop();
+ MipMap[i] = 0;
+ }
}
}
+
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
+#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
+#else
+void CSoftwareTexture2::regenerateMipMapLevels(void* data)
+#endif
{
- if (!hasMipMaps())
- return;
-
- s32 i;
+ int i;
// release
for ( i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
{
if ( MipMap[i] )
+ {
MipMap[i]->drop();
+ MipMap[i] = 0;
+ }
}
core::dimension2d<u32> newSize;
- core::dimension2d<u32> origSize = Size;
- for (i=1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
+ if (HasMipMaps && ( (Flags & GEN_MIPMAP_AUTO) || 0 == data ) )
{
- newSize = MipMap[i-1]->getDimension();
- newSize.Width = core::s32_max ( 1, newSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
- newSize.Height = core::s32_max ( 1, newSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
- origSize.Width = core::s32_max(1, origSize.Width >> 1);
- origSize.Height = core::s32_max(1, origSize.Height >> 1);
+ //need memory also if autogen mipmap disabled
+ for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
+ {
+ const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
+ //isotropic
+ newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);
+ newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);
+ if (upperDim == newSize)
+ break;
- if (data)
+ MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
+#if defined(IRRLICHT_sRGB)
+ MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB());
+#endif
+ //MipMap[i]->fill ( 0xFFFF4040 );
+ //MipMap[i-1]->copyToScalingBoxFilter( MipMap[i], 0, false );
+ Resample_subSampling(BLITTER_TEXTURE, MipMap[i], 0, MipMap[0], 0, Flags);
+ }
+ }
+ else if (HasMipMaps && data)
+ {
+ //deactivated outside mipdata until TA knows how to handle this.
+
+ //query mipmap dimension
+ u8* mip_current = (u8*)data;
+ const u8* mip_end = (u8*)data;
+
+ core::dimension2d<u32> origSize = OriginalSize;
+ i = 1;
+ do
{
- if (OriginalFormat != BURNINGSHADER_COLOR_FORMAT)
+ if (origSize.Width > 1) origSize.Width >>= 1;
+ if (origSize.Height > 1) origSize.Height >>= 1;
+ mip_end += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);
+ i += 1;
+ } while ((origSize.Width != 1 || origSize.Height != 1) && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX);
+
+ //TODO: this is not true
+ LodBIAS = i*0.75f;
+
+ origSize = OriginalSize;
+ for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX && mip_current < mip_end; ++i)
+ {
+ const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
+ //isotropic
+ newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);
+ newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);
+ if (upperDim == newSize)
+ break;
+
+ if (origSize.Width > 1) origSize.Width >>= 1;
+ if (origSize.Height > 1) origSize.Height >>= 1;
+
+ if (OriginalColorFormat != BURNINGSHADER_COLOR_FORMAT)
{
- IImage* tmpImage = new CImage(OriginalFormat, origSize, data, true, false);
+ IImage* tmpImage = new CImage(OriginalColorFormat, origSize, mip_current, true, false);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
- if (origSize==newSize)
+ if (origSize == newSize)
tmpImage->copyTo(MipMap[i]);
else
tmpImage->copyToScalingBoxFilter(MipMap[i]);
@@ -142,33 +222,121 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
}
else
{
- if (origSize==newSize)
- MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, data, false);
+ if (origSize == newSize)
+ MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mip_current, false);
else
{
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
- IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, data, true, false);
+ IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mip_current, true, false);
tmpImage->copyToScalingBoxFilter(MipMap[i]);
tmpImage->drop();
}
}
- data = (u8*)data +origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8;
+ mip_current += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);
}
- else
+ }
+
+
+ //visualize mipmap
+ for (i=1; i < 0 && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
+ {
+/*
+ static u32 color[] = {
+ 0x30bf7f00,0x3040bf00,0x30bf00bf,0x3000bf00,
+ 0x300080bf,0x30bf4000,0x300040bf,0x307f00bf,
+ 0x30bf0000,0x3000bfbf,0x304000bf,0x307fbf00,
+ 0x8000bf7f,0x80bf0040,0x80bfbf00,0x800000bf
+ };
+*/
+ static u32 color[] = {
+ 0xFFFFFFFF,0xFFFF0000,0xFF00FF00,0xFF0000FF,
+ 0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,0xFF0000FF,
+ 0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFF0000FF,
+ 0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFFFF00FF
+ };
+
+ if ( MipMap[i] )
{
- MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
+ core::rect<s32> p (core::position2di(0,0),MipMap[i]->getDimension());
+ SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000);
+ Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], 0, 0, MipMap[i], &p, c.color);
+ }
+ }
- //static u32 color[] = { 0, 0xFFFF0000, 0xFF00FF00,0xFF0000FF,0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0xFF0F0F0F };
- MipMap[i]->fill ( 0 );
- MipMap[0]->copyToScalingBoxFilter( MipMap[i], 0, false );
+ //save mipmap chain
+ if ( 0 )
+ {
+ char buf[256];
+ const char* name = getName().getPath().c_str();
+ int filename = 0;
+ //int ext = -1;
+ i = 0;
+ while (name[i])
+ {
+ if (name[i] == '/' || name[i] == '\\') filename = i + 1;
+ //if (name[i] == '.') ext = i;
+ i += 1;
+ }
+ for (i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
+ {
+ if (MipMap[i])
+ {
+ snprintf_irr(buf, sizeof(buf),"mip/%s_%02d.png", name + filename,i);
+ Driver->writeImageToFile(MipMap[i], buf);
+ }
}
}
+
+ calcDerivative();
+}
+
+void CSoftwareTexture2::calcDerivative()
+{
+ //reset current MipMap
+ MipMapLOD = 0;
+ if (MipMap[0])
+ {
+ const core::dimension2du& dim = MipMap[0]->getDimension();
+ MipMap0_Area[0] = dim.Width;
+ MipMap0_Area[1] = dim.Height; // screensize of a triangle
+
+ Size = dim; // MipMap[MipMapLOD]->getDimension();
+ Pitch = MipMap[MipMapLOD]->getPitch();
+ }
+
+ //preCalc mipmap texel center boundaries
+ for ( s32 i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
+ {
+ CSoftwareTexture2_Bound& b = TexBound[i];
+ if (MipMap[i])
+ {
+ const core::dimension2du& dim = MipMap[i]->getDimension();
+ //f32 u = 1.f / dim.Width;
+ //f32 v = 1.f / dim.Height;
+
+ b.w = dim.Width - 1.f;
+ b.h = dim.Height - 1.f;
+ b.cx = 0.f; //u*0.005f;
+ b.cy = 0.f; //v*0.005f;
+ }
+ else
+ {
+ b.w = 0.f;
+ b.h = 0.f;
+ b.cx = 0.f;
+ b.cy = 0.f;
+ }
+ }
+
}
/* Software Render Target 2 */
CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver)
+#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
+, IRenderTarget(0)
+#endif
{
DriverType = EDT_BURNINGSVIDEO;
@@ -216,6 +384,290 @@ ITexture* CSoftwareRenderTarget2::getTexture() const
}
+
+static const float srgb_8bit_to_linear_float[1 << 8] = {
+ 0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f,
+ 0.001214108f, 0.001517635f, 0.001821162f, 0.0021246888f,
+ 0.002428216f, 0.002731743f, 0.00303527f, 0.0033465358f,
+ 0.0036765074f, 0.004024717f, 0.004391442f, 0.0047769537f,
+ 0.005181517f, 0.005605392f, 0.0060488335f, 0.006512091f,
+ 0.0069954107f, 0.007499032f, 0.008023193f, 0.008568126f,
+ 0.009134059f, 0.009721218f, 0.010329823f, 0.010960095f,
+ 0.011612245f, 0.012286489f, 0.0129830325f, 0.013702083f,
+ 0.014443845f, 0.015208516f, 0.015996294f, 0.016807377f,
+ 0.017641956f, 0.018500222f, 0.019382363f, 0.020288564f,
+ 0.021219011f, 0.022173885f, 0.023153368f, 0.024157634f,
+ 0.025186861f, 0.026241222f, 0.027320893f, 0.02842604f,
+ 0.029556835f, 0.030713445f, 0.031896032f, 0.033104766f,
+ 0.034339808f, 0.035601314f, 0.036889452f, 0.038204372f,
+ 0.039546236f, 0.0409152f, 0.04231141f, 0.04373503f,
+ 0.045186203f, 0.046665087f, 0.048171826f, 0.049706567f,
+ 0.051269464f, 0.05286065f, 0.05448028f, 0.056128494f,
+ 0.057805438f, 0.059511244f, 0.06124606f, 0.06301002f,
+ 0.06480327f, 0.066625945f, 0.068478175f, 0.0703601f,
+ 0.07227185f, 0.07421357f, 0.07618539f, 0.07818743f,
+ 0.08021983f, 0.082282715f, 0.084376216f, 0.086500466f,
+ 0.08865559f, 0.09084172f, 0.093058966f, 0.09530747f,
+ 0.097587354f, 0.09989873f, 0.10224174f, 0.10461649f,
+ 0.107023105f, 0.10946172f, 0.111932434f, 0.11443538f,
+ 0.11697067f, 0.119538434f, 0.122138776f, 0.12477182f,
+ 0.12743768f, 0.13013647f, 0.13286832f, 0.13563333f,
+ 0.13843162f, 0.14126329f, 0.14412847f, 0.14702727f,
+ 0.14995979f, 0.15292616f, 0.15592647f, 0.15896083f,
+ 0.16202939f, 0.1651322f, 0.1682694f, 0.17144111f,
+ 0.1746474f, 0.17788842f, 0.18116425f, 0.18447499f,
+ 0.18782078f, 0.19120169f, 0.19461784f, 0.19806932f,
+ 0.20155625f, 0.20507874f, 0.20863687f, 0.21223076f,
+ 0.21586053f, 0.21952623f, 0.22322798f, 0.2269659f,
+ 0.23074007f, 0.23455061f, 0.2383976f, 0.24228115f,
+ 0.24620135f, 0.2501583f, 0.25415212f, 0.25818288f,
+ 0.2622507f, 0.26635563f, 0.27049783f, 0.27467734f,
+ 0.2788943f, 0.28314877f, 0.28744087f, 0.29177067f,
+ 0.2961383f, 0.3005438f, 0.30498734f, 0.30946895f,
+ 0.31398875f, 0.3185468f, 0.32314324f, 0.32777813f,
+ 0.33245155f, 0.33716366f, 0.34191445f, 0.3467041f,
+ 0.35153264f, 0.35640016f, 0.36130682f, 0.36625263f,
+ 0.3712377f, 0.37626216f, 0.38132605f, 0.38642946f,
+ 0.3915725f, 0.39675525f, 0.4019778f, 0.40724024f,
+ 0.41254264f, 0.4178851f, 0.4232677f, 0.42869052f,
+ 0.43415368f, 0.4396572f, 0.44520122f, 0.45078582f,
+ 0.45641103f, 0.46207702f, 0.4677838f, 0.4735315f,
+ 0.4793202f, 0.48514995f, 0.4910209f, 0.496933f,
+ 0.5028865f, 0.50888133f, 0.5149177f, 0.5209956f,
+ 0.52711517f, 0.53327644f, 0.5394795f, 0.5457245f,
+ 0.55201143f, 0.55834043f, 0.5647115f, 0.57112485f,
+ 0.57758045f, 0.58407843f, 0.59061885f, 0.5972018f,
+ 0.60382736f, 0.61049557f, 0.6172066f, 0.62396044f,
+ 0.63075715f, 0.6375969f, 0.6444797f, 0.65140563f,
+ 0.65837485f, 0.66538733f, 0.67244315f, 0.6795425f,
+ 0.6866853f, 0.6938718f, 0.7011019f, 0.7083758f,
+ 0.71569353f, 0.7230551f, 0.73046076f, 0.73791045f,
+ 0.74540424f, 0.7529422f, 0.7605245f, 0.76815116f,
+ 0.7758222f, 0.7835378f, 0.791298f, 0.7991027f,
+ 0.8069523f, 0.8148466f, 0.82278574f, 0.8307699f,
+ 0.838799f, 0.8468732f, 0.8549926f, 0.8631572f,
+ 0.8713671f, 0.8796224f, 0.8879231f, 0.8962694f,
+ 0.9046612f, 0.91309863f, 0.92158186f, 0.9301109f,
+ 0.9386857f, 0.9473065f, 0.9559733f, 0.9646863f,
+ 0.9734453f, 0.9822506f, 0.9911021f, 1.0f,
+};
+/*
+int linear_to_srgb_8bit(const float x) {
+ if (x <= 0.f) return 0;
+ if (x >= 1.f) return 255;
+ const float *table = SRGB_8BIT_TO_LINEAR_FLOAT;
+ int y = 0;
+ for (int i = 128; i != 0; i >>= 1) {
+ if (table[y + i] <= x)
+ y += i;
+ }
+ if (x - table[y] <= table[y + 1] - x)
+ return y;
+ else
+ return y + 1;
+}
+*/
+
+
+u32 linear_to_srgb_8bit(const float v)
+{
+ ieee754 c;
+ c.f = v;
+ const register size_t x = c.u;
+ const u32 *table = (u32*)srgb_8bit_to_linear_float;
+ register u32 y = 0;
+ y += table[y + 128] <= x ? 128 : 0;
+ y += table[y + 64] <= x ? 64 : 0;
+ y += table[y + 32] <= x ? 32 : 0;
+ y += table[y + 16] <= x ? 16 : 0;
+ y += table[y + 8] <= x ? 8 : 0;
+ y += table[y + 4] <= x ? 4 : 0;
+ y += table[y + 2] <= x ? 2 : 0;
+ y += table[y + 1] <= x ? 1 : 0;
+
+ return y;
+}
+
+// 2D Region half open [x0;x1[
+struct absrect2
+{
+ s32 x0;
+ s32 y0;
+ s32 x1;
+ s32 y1;
+};
+
+static inline int clipTest(absrect2 &o, const core::rect<s32>* a, const absrect2& b)
+{
+ if (a == 0)
+ {
+ o.x0 = b.x0;
+ o.y0 = b.y0;
+ o.x1 = b.x1;
+ o.y1 = b.y1;
+ }
+ else
+ {
+ o.x0 = core::s32_max(a->UpperLeftCorner.X, b.x0);
+ o.x1 = core::s32_min(a->LowerRightCorner.X, b.x1);
+ o.y0 = core::s32_max(a->UpperLeftCorner.Y, b.y0);
+ o.y1 = core::s32_min(a->LowerRightCorner.Y, b.y1);
+ }
+ int clipTest = 0;
+ clipTest |= o.x0 >= o.x1 ? 1 : 0;
+ clipTest |= o.y0 >= o.y1 ? 2 : 0;
+ return clipTest;
+}
+
+//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)
+// todo: texture jumps (mip selection problem)
+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)
+{
+ const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height };
+ absrect2 dc;
+ if (clipTest(dc, dstRect, dst_clip)) return;
+ const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat();
+ u8* dstData = (u8*)dst->getData();
+
+ const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height };
+ absrect2 sc;
+ if (clipTest(sc, srcRect, src_clip)) return;
+ const video::ECOLOR_FORMAT srcFormat = src->getColorFormat();
+ const u8* srcData = (u8*)src->getData();
+
+#if defined(IRRLICHT_sRGB)
+ const int dst_sRGB = dst->get_sRGB();
+ const int src_sRGB = src->get_sRGB();
+#else
+ const int dst_sRGB = (flags & CSoftwareTexture2::TEXTURE_IS_LINEAR) ? 0 : 1;
+ const int src_sRGB = (flags & CSoftwareTexture2::IMAGE_IS_LINEAR) ? 0 : 1;
+#endif
+
+
+
+ float scale[2];
+ scale[0] = (float)(sc.x1 - sc.x0) / (float)(dc.x1 - dc.x0);
+ scale[1] = (float)(sc.y1 - sc.y0) / (float)(dc.y1 - dc.y0);
+ const float rs = 1.f / (scale[0] * scale[1]);
+
+ float sum[4];
+ u32 sbgra = 0;
+
+ float f[4];
+ int fi[4];
+ f[3] = (float)sc.y0;
+ for (int dy = dc.y0; dy < dc.y1; ++dy)
+ {
+ f[1] = f[3];
+ f[3] = sc.y0 + (dy + 1 - dc.y0)*scale[1];
+ if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough
+
+ f[2] = (float)sc.x0;
+ for (int dx = dc.x0; dx < dc.x1; ++dx)
+ {
+ f[0] = f[2];
+ f[2] = sc.x0 + (dx + 1 - dc.x0)*scale[0];
+ if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f;
+
+ //accumulate linear color
+ sum[0] = 0.f;
+ sum[1] = 0.f;
+ sum[2] = 0.f;
+ sum[3] = 0.f;
+
+ //sample border
+ fi[0] = (int)(f[0]);
+ fi[1] = (int)(f[1]);
+ fi[2] = (int)(f[2]);
+ fi[3] = (int)(f[3]);
+
+ float w[2];
+ for (int fy = fi[1]; fy <= fi[3]; ++fy)
+ {
+ w[1] = 1.f;
+ if (fy == fi[1]) w[1] -= f[1] - fy;
+ if (fy == fi[3]) w[1] -= fy + 1 - f[3];
+
+ for (int fx = fi[0]; fx <= fi[2]; ++fx)
+ {
+ w[0] = 1.f;
+ if (fx == fi[0]) w[0] -= f[0] - fx;
+ if (fx == fi[2]) w[0] -= fx + 1 - f[2];
+
+ const float ws = w[1] * w[0] * rs;
+
+ switch (srcFormat)
+ {
+ case video::ECF_A1R5G5B5: sbgra = video::A1R5G5B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break;
+ case video::ECF_R5G6B5: sbgra = video::R5G6B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break;
+ case video::ECF_A8R8G8B8: sbgra = *(u32*)(srcData + (fy*src_clip.x1) * 4 + (fx * 4)); break;
+ case video::ECF_R8G8B8:
+ {
+ const u8* p = srcData + (fy*src_clip.x1) * 3 + (fx * 3);
+ sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2];
+ } break;
+ default: break;
+ }
+ if (src_sRGB)
+ {
+ sum[0] += srgb_8bit_to_linear_float[(sbgra) & 0xFF] * ws;
+ sum[1] += srgb_8bit_to_linear_float[(sbgra >> 8) & 0xFF] * ws;
+ sum[2] += srgb_8bit_to_linear_float[(sbgra >> 16) & 0xFF] * ws;
+ sum[3] += ((sbgra >> 24) & 0xFF) * ws;
+ }
+ else
+ {
+ sum[0] += ((sbgra) & 0xFF) * ws;
+ sum[1] += ((sbgra >> 8) & 0xFF) * ws;
+ sum[2] += ((sbgra >> 16) & 0xFF) * ws;
+ sum[3] += ((sbgra >> 24) & 0xFF) * ws;
+ }
+
+ }
+ }
+ switch (op)
+ {
+ case BLITTER_TEXTURE_ALPHA_BLEND:
+ case BLITTER_TEXTURE_ALPHA_COLOR_BLEND:
+ break;
+ default:
+ break;
+ }
+ if (dst_sRGB)
+ {
+ sbgra = linear_to_srgb_8bit(sum[0]) |
+ linear_to_srgb_8bit(sum[1]) << 8 |
+ linear_to_srgb_8bit(sum[2]) << 16 |
+ (u32)(sum[3]) << 24;
+ }
+ else
+ {
+ sbgra = (u32)(sum[0]) |
+ (u32)(sum[1]) << 8 |
+ (u32)(sum[2]) << 16 |
+ (u32)(sum[3]) << 24;
+ }
+ switch (dstFormat)
+ {
+ case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy*dst_clip.x1) * 4 + (dx * 4)) = sbgra; break;
+ case video::ECF_R8G8B8:
+ {
+ u8* p = dstData + (dy*dst_clip.x1) * 3 + (dx * 3);
+ p[2] = (sbgra) & 0xFF;
+ p[1] = (sbgra >> 8) & 0xFF;
+ p[0] = (sbgra >> 16) & 0xFF;
+ } break;
+ case video::ECF_A1R5G5B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toA1R5G5B5(sbgra); break;
+ case video::ECF_R5G6B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toR5G6B5(sbgra); break;
+ default:
+ break;
+ }
+ }
+ }
+
+}
+
} // end namespace video
} // end namespace irr
diff --git a/source/Irrlicht/CSoftwareTexture2.h b/source/Irrlicht/CSoftwareTexture2.h
index ac3c1fc..4f6be48 100644
--- a/source/Irrlicht/CSoftwareTexture2.h
+++ b/source/Irrlicht/CSoftwareTexture2.h
@@ -21,6 +21,14 @@ class CBurningVideoDriver;
/*!
interface for a Video Driver dependent Texture.
*/
+struct CSoftwareTexture2_Bound
+{
+ f32 w; // width - 0.5f;
+ f32 h; // height- 0.5f;
+ f32 cx; // texelcenter x 1.f/width*0.5f
+ f32 cy; // texelcenter y 1.f/height*0.5f
+};
+
class CSoftwareTexture2 : public ITexture
{
public:
@@ -28,21 +36,34 @@ public:
//! constructor
enum eTex2Flags
{
- GEN_MIPMAP = 1,
- IS_RENDERTARGET = 2,
- NP2_SIZE = 4,
+ GEN_MIPMAP = 1, // has mipmaps
+ GEN_MIPMAP_AUTO = 2, // automatic mipmap generation
+ IS_RENDERTARGET = 4,
+ ALLOW_NPOT = 8, //allow non power of two
+ IMAGE_IS_LINEAR = 16,
+ TEXTURE_IS_LINEAR = 32,
};
- CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags);
+ CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags /*eTex2Flags*/, CBurningVideoDriver* driver);
//! destructor
virtual ~CSoftwareTexture2();
+ u32 getMipmapLevel(s32 newLevel) const
+ {
+ if ( newLevel < 0 ) newLevel = 0;
+ else if ( newLevel >= SOFTWARE_DRIVER_2_MIPMAPPING_MAX ) newLevel = SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1;
+
+ while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1;
+ return newLevel;
+ }
+
//! lock function
virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_
{
if (Flags & GEN_MIPMAP)
{
- MipMapLOD = mipmapLevel;
+ //called from outside. must test
+ MipMapLOD = getMipmapLevel(mipmapLevel);
Size = MipMap[MipMapLOD]->getDimension();
Pitch = MipMap[MipMapLOD]->getPitch();
}
@@ -55,14 +76,19 @@ public:
{
}
- //! Returns the size of the largest mipmap.
+ //! compare the area drawn with the area of the texture
f32 getLODFactor( const f32 texArea ) const
{
- return OrigImageDataSizeInPixels * texArea;
+ return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea;
//return MipMap[0]->getImageDataSizeInPixels () * texArea;
}
- //! returns unoptimized surface
+ const u32* getMipMap0_Area() const
+ {
+ return MipMap0_Area;
+ }
+
+ //! returns unoptimized surface (misleading name. burning can scale down originalimage)
virtual CImage* getImage() const
{
return MipMap[0];
@@ -74,16 +100,27 @@ public:
return MipMap[MipMapLOD];
}
+ //precalculated dimx-1/dimx*0.5f
+ const CSoftwareTexture2_Bound& getTexBound() const
+ {
+ return TexBound[MipMapLOD];
+ }
+
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;
+ f32 get_lod_bias() const { return LodBIAS; }
private:
- f32 OrigImageDataSizeInPixels;
+ void calcDerivative();
- CImage * MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
+ //! controls MipmapSelection. relation between drawn area and image size
+ u32 MipMapLOD; // 0 .. original Texture pot -SOFTWARE_DRIVER_2_MIPMAPPING_MAX
+ u32 Flags; //eTex2Flags
+ CBurningVideoDriver* Driver;
- u32 MipMapLOD;
- u32 Flags;
- ECOLOR_FORMAT OriginalFormat;
+ CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
+ CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
+ u32 MipMap0_Area[2];
+ f32 LodBIAS;
};
/*!
@@ -103,9 +140,9 @@ protected:
CBurningVideoDriver* Driver;
};
-
} // end namespace video
} // end namespace irr
-#endif
+#endif // __C_SOFTWARE_2_TEXTURE_H_INCLUDED__
+
diff --git a/source/Irrlicht/CTRGouraud2.cpp b/source/Irrlicht/CTRGouraud2.cpp
index 194cc68..d0488b5 100644
--- a/source/Irrlicht/CTRGouraud2.cpp
+++ b/source/Irrlicht/CTRGouraud2.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -83,13 +83,11 @@ public:
CTRGouraud2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle (const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ //virtual bool canWireFrame () { return true; }
-
-private:
- void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
+protected:
+ virtual void scanline_bilinear ();
};
@@ -136,8 +134,8 @@ void CTRGouraud2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -145,7 +143,7 @@ void CTRGouraud2::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -182,6 +180,7 @@ void CTRGouraud2::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -193,34 +192,31 @@ void CTRGouraud2::scanline_bilinear ()
#ifdef IPOL_C0
tFixPoint r0, g0, b0;
-#ifdef INVERSE_W
- f32 inversew;
-#endif
+ f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
+ //if test active only first pixel
+ if ( (0 == EdgeTestPass) & i ) break;
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
- if ( line.w[0] >= z[i] )
+ if (line.w[0] >= z[i] )
#endif
{
#ifdef IPOL_C0
-#ifdef INVERSE_W
- inversew = core::reciprocal ( line.w[0] );
- getSample_color ( r0, g0, b0, line.c[0][0] * inversew );
-#else
- getSample_color ( r0, g0, b0, line.c[0][0] );
+#ifdef INVERSE_W
+ inversew = fix_inverse32_color(line.w[0]);
#endif
-
- dst[i] = fix_to_color ( r0, g0, b0 );
+ vec4_to_fix( r0, g0, b0, line.c[0][0],inversew );
+ dst[i] = fix_to_sample( r0, g0, b0 );
#else
- dst[i] = COLOR_BRIGHT_WHITE;
+ dst[i] = PrimitiveColor;
#endif
#ifdef WRITE_Z
@@ -251,7 +247,7 @@ void CTRGouraud2::scanline_bilinear ()
}
-void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
@@ -262,10 +258,10 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_edge( ca );
+ scan.invDeltaY[1] = reciprocal_edge( ba );
+ scan.invDeltaY[2] = reciprocal_edge( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -351,8 +347,8 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -421,6 +417,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
// render a scanline
scanline_bilinear ();
+ if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -454,7 +451,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
}
// rasterize lower sub-triangle
- if ( (f32) 0.0 != scan.invDeltaY[2] )
+ if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
@@ -510,8 +507,8 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -581,6 +578,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
// render a scanline
scanline_bilinear ();
+ if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -630,6 +628,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver)
{
+ // ETR_GOURAUD . no texture
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraud2(driver);
#else
diff --git a/source/Irrlicht/CTRGouraudAlpha2.cpp b/source/Irrlicht/CTRGouraudAlpha2.cpp
index 837ab3e..dd425f8 100644
--- a/source/Irrlicht/CTRGouraudAlpha2.cpp
+++ b/source/Irrlicht/CTRGouraudAlpha2.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -84,15 +84,12 @@ public:
CTRGouraudAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c ) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
-
};
//! constructor
@@ -142,8 +139,8 @@ void CTRGouraudAlpha2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -151,7 +148,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -188,6 +185,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -198,9 +196,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
#ifdef IPOL_C0
-#ifdef INVERSE_W
- f32 inversew;
-#endif
+ f32 inversew = FIX_POINT_F32_MUL;
tFixPoint a0;
tFixPoint r0, g0, b0;
@@ -220,22 +216,20 @@ void CTRGouraudAlpha2::scanline_bilinear ()
{
#ifdef IPOL_C0
#ifdef INVERSE_W
- inversew = core::reciprocal ( line.w[0] );
-
- getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );
-#else
- getSample_color ( a0, r0, g0, b0, line.c[0][0] );
+ inversew = reciprocal_zero_no ( line.w[0] );
#endif
+ vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );
color_to_fix ( r1, g1, b1, dst[i] );
+ fix_color_norm(a0);
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
- dst[i] = fix_to_color ( r2, g2, b2 );
+ dst[i] = fix4_to_sample( a0,r2, g2, b2 );
#else
- dst[i] = COLOR_BRIGHT_WHITE;
+ dst[i] = PrimitiveColor;
#endif
#ifdef WRITE_Z
z[i] = line.z[0];
@@ -265,7 +259,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
}
-void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -276,9 +270,9 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -365,8 +359,8 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -524,8 +518,8 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -642,6 +636,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver)
{
+ // ETR_GOURAUD_ALPHA unused
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudAlpha2(driver);
#else
diff --git a/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp b/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp
index b5453df..d921cb0 100644
--- a/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp
+++ b/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -84,14 +84,11 @@ public:
CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle (const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
-
};
//! constructor
@@ -138,8 +135,8 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -147,7 +144,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -184,6 +181,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -192,11 +190,10 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
+ f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;
+
#ifdef IPOL_C0
-#ifdef INVERSE_W
- f32 inversew;
-#endif
tFixPoint a0;
tFixPoint r0, g0, b0;
@@ -224,22 +221,21 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
#ifdef IPOL_C0
#ifdef IPOL_W
- inversew = core::reciprocal ( line.w[0] );
-
- getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );
-#else
- getSample_color ( a0, r0, g0, b0, line.c[0][0] );
+ inversew = fix_inverse32_color(line.w[0]);
#endif
+ vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );
+
color_to_fix ( r1, g1, b1, dst[i] );
+ fix_color_norm(a0);
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
- dst[i] = fix_to_color ( r2, g2, b2 );
+ dst[i] = fix_to_sample( r2, g2, b2 );
#else
- dst[i] = COLOR_BRIGHT_WHITE;
+ dst[i] = PrimitiveColor;
#endif
@@ -264,7 +260,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
}
-void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -275,9 +271,9 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -363,8 +359,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -522,8 +518,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -640,6 +636,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)
{
+ //ETR_GOURAUD_ALPHA_NOZ - draw2DRectangle Gradient
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudAlphaNoZ2(driver);
#else
diff --git a/source/Irrlicht/CTRGouraudNoZ2.cpp b/source/Irrlicht/CTRGouraudNoZ2.cpp
new file mode 100644
index 0000000..2e0bc39
--- /dev/null
+++ b/source/Irrlicht/CTRGouraudNoZ2.cpp
@@ -0,0 +1,641 @@
+// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#include "IrrCompileConfig.h"
+#include "IBurningShader.h"
+
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
+
+// compile flag for this file
+#undef USE_ZBUFFER
+#undef IPOL_Z
+#undef CMP_Z
+#undef WRITE_Z
+
+#undef IPOL_W
+#undef CMP_W
+#undef WRITE_W
+
+#undef SUBTEXEL
+#undef INVERSE_W
+
+#undef IPOL_C0
+#undef IPOL_T0
+#undef IPOL_T1
+
+// define render case
+#define SUBTEXEL
+#define INVERSE_W
+
+#define USE_ZBUFFER
+#define IPOL_W
+//#define CMP_W
+//#define WRITE_W
+
+#define IPOL_C0
+//#define IPOL_T0
+//#define IPOL_T1
+
+// apply global override
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+ #undef INVERSE_W
+#endif
+
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
+ #undef SUBTEXEL
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS < 1
+ #undef IPOL_C0
+#endif
+
+#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
+ #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+ #undef IPOL_W
+ #endif
+ #define IPOL_Z
+
+ #ifdef CMP_W
+ #undef CMP_W
+ #define CMP_Z
+ #endif
+
+ #ifdef WRITE_W
+ #undef WRITE_W
+ #define WRITE_Z
+ #endif
+
+#endif
+
+
+namespace irr
+{
+
+namespace video
+{
+
+class CTRGouraudNoZ2 : public IBurningShader
+{
+public:
+
+ //! constructor
+ CTRGouraudNoZ2(CBurningVideoDriver* driver);
+
+ //! draws an indexed triangle list
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual bool canWireFrame () { return true; }
+
+protected:
+ virtual void scanline_bilinear ();
+};
+
+//! constructor
+CTRGouraudNoZ2::CTRGouraudNoZ2(CBurningVideoDriver* driver)
+: IBurningShader(driver)
+{
+ #ifdef _DEBUG
+ setDebugName("CTRGouraudNoZ2");
+ #endif
+}
+
+
+
+/*!
+*/
+void CTRGouraudNoZ2::scanline_bilinear ()
+{
+ tVideoSample *dst;
+
+#ifdef USE_ZBUFFER
+ //fp24 *z;
+#endif
+
+ s32 xStart;
+ s32 xEnd;
+ s32 dx;
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+#ifdef IPOL_Z
+ f32 slopeZ;
+#endif
+#ifdef IPOL_W
+ fp24 slopeW;
+#endif
+#ifdef IPOL_C0
+ sVec4 slopeC;
+#endif
+#ifdef IPOL_T0
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
+#endif
+
+ // apply top-left fill-convention, left
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
+
+ dx = xEnd - xStart;
+
+ if ( dx < 0 )
+ return;
+
+ // slopes
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
+
+#ifdef IPOL_Z
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
+#endif
+#ifdef IPOL_W
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;
+#endif
+#ifdef IPOL_C0
+ slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T0
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T1
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
+#endif
+
+#ifdef SUBTEXEL
+ subPixel = ( (f32) xStart ) - line.x[0];
+#ifdef IPOL_Z
+ line.z[0] += slopeZ * subPixel;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW * subPixel;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC * subPixel;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0] * subPixel;
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1] * subPixel;
+#endif
+#endif
+
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+ dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
+
+#ifdef USE_ZBUFFER
+ //z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
+#endif
+
+
+
+#ifdef IPOL_C0
+ tFixPoint r0, g0, b0;
+
+ f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;
+
+#endif
+
+ for ( s32 i = 0; i <= dx; ++i )
+ {
+ if ( (0 == EdgeTestPass) & i ) break;
+
+#ifdef CMP_Z
+ if ( line.z[0] < z[i] )
+#endif
+#ifdef CMP_W
+ if (line.w[0] >= z[i] )
+#endif
+
+ {
+#ifdef IPOL_C0
+#ifdef INVERSE_W
+ inversew = fix_inverse32_color(line.w[0]);
+#endif
+ vec4_to_fix(r0, g0, b0, line.c[0][0], inversew);
+ dst[i] = fix_to_sample(r0, g0, b0);
+#else
+ dst[i] = PrimitiveColor;
+#endif
+
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ z[i] = line.w[0];
+#endif
+
+ }
+
+#ifdef IPOL_Z
+ line.z[0] += slopeZ;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0];
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1];
+#endif
+ }
+
+}
+
+void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
+{
+ // sort on height, y
+ if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
+ if ( a->Pos.y > c->Pos.y ) swapVertexPointer(&a, &c);
+ if ( b->Pos.y > c->Pos.y ) swapVertexPointer(&b, &c);
+
+ const f32 ca = c->Pos.y - a->Pos.y;
+ const f32 ba = b->Pos.y - a->Pos.y;
+ const f32 cb = c->Pos.y - b->Pos.y;
+
+ // calculate delta y of the edges
+ scan.invDeltaY[0] = reciprocal_edge( ca );
+ scan.invDeltaY[1] = reciprocal_edge( ba );
+ scan.invDeltaY[2] = reciprocal_edge( cb );
+
+ if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
+ return;
+
+ // find if the major edge is left or right aligned
+ f32 temp[4];
+
+ temp[0] = a->Pos.x - c->Pos.x;
+ temp[1] = -ca;
+ temp[2] = b->Pos.x - a->Pos.x;
+ temp[3] = ba;
+
+ scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
+ scan.right = 1 - scan.left;
+
+ // calculate slopes for the major edge
+ scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
+ scan.x[0] = a->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
+ scan.z[0] = a->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
+ scan.w[0] = a->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
+ scan.c[0][0] = a->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
+ scan.t[0][0] = a->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
+ scan.t[1][0] = a->Tex[1];
+#endif
+
+ // top left fill convention y run
+ s32 yStart;
+ s32 yEnd;
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+
+ // rasterize upper sub-triangle
+ if ( (f32) 0.0 != scan.invDeltaY[1] )
+ {
+ // calculate slopes for top edge
+ scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
+ scan.x[1] = a->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
+ scan.z[1] = a->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
+ scan.w[1] = a->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
+ scan.c[0][1] = a->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
+ scan.t[0][1] = a->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
+ scan.t[1][1] = a->Tex[1];
+#endif
+
+ // apply top-left fill convention, top part
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
+
+#ifdef SUBTEXEL
+ subPixel = ( (f32) yStart ) - a->Pos.y;
+
+ // correct to pixel center
+ scan.x[0] += scan.slopeX[0] * subPixel;
+ scan.x[1] += scan.slopeX[1] * subPixel;
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0] * subPixel;
+ scan.z[1] += scan.slopeZ[1] * subPixel;
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0] * subPixel;
+ scan.w[1] += scan.slopeW[1] * subPixel;
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;
+#endif
+
+#endif
+
+ // rasterize the edge scanlines
+ for( line.y = yStart; line.y <= yEnd; ++line.y)
+ {
+ line.x[scan.left] = scan.x[0];
+ line.x[scan.right] = scan.x[1];
+
+#ifdef IPOL_Z
+ line.z[scan.left] = scan.z[0];
+ line.z[scan.right] = scan.z[1];
+#endif
+
+#ifdef IPOL_W
+ line.w[scan.left] = scan.w[0];
+ line.w[scan.right] = scan.w[1];
+#endif
+
+#ifdef IPOL_C0
+ line.c[0][scan.left] = scan.c[0][0];
+ line.c[0][scan.right] = scan.c[0][1];
+#endif
+
+#ifdef IPOL_T0
+ line.t[0][scan.left] = scan.t[0][0];
+ line.t[0][scan.right] = scan.t[0][1];
+#endif
+
+#ifdef IPOL_T1
+ line.t[1][scan.left] = scan.t[1][0];
+ line.t[1][scan.right] = scan.t[1][1];
+#endif
+
+ // render a scanline
+ scanline_bilinear ();
+ if ( EdgeTestPass & edge_test_first_line ) break;
+
+ scan.x[0] += scan.slopeX[0];
+ scan.x[1] += scan.slopeX[1];
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0];
+ scan.z[1] += scan.slopeZ[1];
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0];
+ scan.w[1] += scan.slopeW[1];
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0];
+ scan.c[0][1] += scan.slopeC[0][1];
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0];
+ scan.t[0][1] += scan.slopeT[0][1];
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0];
+ scan.t[1][1] += scan.slopeT[1][1];
+#endif
+ }
+ }
+
+ // rasterize lower sub-triangle
+ if ( (f32) 0.0 != scan.invDeltaY[2] )
+ {
+ // advance to middle point
+ if( (f32) 0.0 != scan.invDeltaY[1] )
+ {
+ temp[0] = b->Pos.y - a->Pos.y; // dy
+
+ scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
+#ifdef IPOL_Z
+ scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
+#endif
+#ifdef IPOL_W
+ scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
+#endif
+#ifdef IPOL_C0
+ scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
+#endif
+#ifdef IPOL_T0
+ scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
+#endif
+#ifdef IPOL_T1
+ scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
+#endif
+
+ }
+
+ // calculate slopes for bottom edge
+ scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
+ scan.x[1] = b->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
+ scan.z[1] = b->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
+ scan.w[1] = b->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
+ scan.c[0][1] = b->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
+ scan.t[0][1] = b->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
+ scan.t[1][1] = b->Tex[1];
+#endif
+
+ // apply top-left fill convention, top part
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
+
+#ifdef SUBTEXEL
+
+ subPixel = ( (f32) yStart ) - b->Pos.y;
+
+ // correct to pixel center
+ scan.x[0] += scan.slopeX[0] * subPixel;
+ scan.x[1] += scan.slopeX[1] * subPixel;
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0] * subPixel;
+ scan.z[1] += scan.slopeZ[1] * subPixel;
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0] * subPixel;
+ scan.w[1] += scan.slopeW[1] * subPixel;
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;
+#endif
+
+#endif
+
+ // rasterize the edge scanlines
+ for( line.y = yStart; line.y <= yEnd; ++line.y)
+ {
+ line.x[scan.left] = scan.x[0];
+ line.x[scan.right] = scan.x[1];
+
+#ifdef IPOL_Z
+ line.z[scan.left] = scan.z[0];
+ line.z[scan.right] = scan.z[1];
+#endif
+
+#ifdef IPOL_W
+ line.w[scan.left] = scan.w[0];
+ line.w[scan.right] = scan.w[1];
+#endif
+
+#ifdef IPOL_C0
+ line.c[0][scan.left] = scan.c[0][0];
+ line.c[0][scan.right] = scan.c[0][1];
+#endif
+
+#ifdef IPOL_T0
+ line.t[0][scan.left] = scan.t[0][0];
+ line.t[0][scan.right] = scan.t[0][1];
+#endif
+
+#ifdef IPOL_T1
+ line.t[1][scan.left] = scan.t[1][0];
+ line.t[1][scan.right] = scan.t[1][1];
+#endif
+
+ // render a scanline
+ scanline_bilinear ();
+ if ( EdgeTestPass & edge_test_first_line ) break;
+
+ scan.x[0] += scan.slopeX[0];
+ scan.x[1] += scan.slopeX[1];
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0];
+ scan.z[1] += scan.slopeZ[1];
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0];
+ scan.w[1] += scan.slopeW[1];
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0];
+ scan.c[0][1] += scan.slopeC[0][1];
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0];
+ scan.t[0][1] += scan.slopeT[0][1];
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0];
+ scan.t[1][1] += scan.slopeT[1][1];
+#endif
+
+ }
+ }
+
+}
+
+
+} // end namespace video
+} // end namespace irr
+
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
+
+namespace irr
+{
+namespace video
+{
+
+//! creates a flat triangle renderer
+IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver)
+{
+ //ETR_GOURAUD_NOZ - no texture no depth test no depth write
+ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
+ return new CTRGouraudNoZ2(driver);
+ #else
+ return 0;
+ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
+}
+
+
+} // end namespace video
+} // end namespace irr
+
+
+
diff --git a/source/Irrlicht/CTRNormalMap.cpp b/source/Irrlicht/CTRNormalMap.cpp
index bc72b75..5df81c7 100644
--- a/source/Irrlicht/CTRNormalMap.cpp
+++ b/source/Irrlicht/CTRNormalMap.cpp
@@ -21,6 +21,7 @@
#undef INVERSE_W
#undef IPOL_C0
+#undef IPOL_C1
#undef IPOL_T0
#undef IPOL_T1
#undef IPOL_T2
@@ -36,6 +37,7 @@
#define WRITE_W
#define IPOL_C0
+#define IPOL_C1
#define IPOL_T0
#define IPOL_T1
#define IPOL_L0
@@ -49,10 +51,18 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
+#if BURNING_MATERIAL_MAX_COLORS < 2
+ #undef IPOL_C1
+#endif
+
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
+ #undef IPOL_L0
+#endif
+
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@@ -87,14 +97,11 @@ public:
CTRNormalMap(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
-
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private:
- void scanline_bilinear ();
-
- sScanConvertData scan;
- sScanLineData line;
+ void fragmentShader();
};
@@ -108,10 +115,13 @@ CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver)
}
+void CTRNormalMap::OnSetMaterial(const SBurningShaderMaterial& material)
+{
+}
/*!
*/
-void CTRNormalMap::scanline_bilinear ()
+void CTRNormalMap::fragmentShader()
{
tVideoSample *dst;
@@ -135,18 +145,18 @@ void CTRNormalMap::scanline_bilinear ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#ifdef IPOL_L0
- sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
+ sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -154,7 +164,7 @@ void CTRNormalMap::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -165,6 +175,9 @@ void CTRNormalMap::scanline_bilinear ()
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
+#ifdef IPOL_C1
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
+#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
@@ -189,6 +202,9 @@ void CTRNormalMap::scanline_bilinear ()
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1] * subPixel;
+#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
@@ -203,6 +219,7 @@ void CTRNormalMap::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -210,25 +227,33 @@ void CTRNormalMap::scanline_bilinear ()
#endif
- f32 inversew;
+ f32 inversew = FIX_POINT_F32_MUL;
- tFixPoint tx0, tx1;
- tFixPoint ty0, ty1;
+ tFixPoint tx0, ty0;
+
+#ifdef IPOL_T1
+ tFixPoint tx1, ty1;
+#endif
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
+#ifdef IPOL_L0
tFixPoint lx, ly, lz;
- tFixPoint ndotl;
-
- sVec3 light;
+#endif
+ tFixPoint ndotl = FIX_POINT_ONE;
#ifdef IPOL_C0
- tFixPoint r3, g3, b3;
+ tFixPoint a3,r3, g3, b3;
+#endif
+
+#ifdef IPOL_C1
+ tFixPoint aFog = FIX_POINT_ONE;
#endif
+
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
@@ -240,94 +265,100 @@ void CTRNormalMap::scanline_bilinear ()
{
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
-
- tx0 = tofix ( line.t[0][0].x,inversew);
- ty0 = tofix ( line.t[0][0].y,inversew);
- tx1 = tofix ( line.t[1][0].x,inversew);
- ty1 = tofix ( line.t[1][0].y,inversew);
-
-
-#ifdef IPOL_C0
- r3 = tofix ( line.c[0][0].y ,inversew );
- g3 = tofix ( line.c[0][0].z ,inversew );
- b3 = tofix ( line.c[0][0].w ,inversew );
#endif
-#else
- inversew = FIX_POINT_F32_MUL;
- tx0 = tofix(line.t[0][0].x, inversew);
- ty0 = tofix(line.t[0][0].y, inversew);
- tx1 = tofix(line.t[1][0].x, inversew);
- ty1 = tofix(line.t[1][0].y, inversew);
-
#ifdef IPOL_C0
- r3 = tofix ( line.c[0][0].y );
- g3 = tofix ( line.c[0][0].z );
- b3 = tofix ( line.c[0][0].w );
+ //vertex alpha blend ( and omit depthwrite ,hacky..)
+ a3 = tofix(line.c[0][0].x, inversew);
+ if (a3 + 2 >= FIX_POINT_ONE)
+ {
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ z[i] = line.w[0];
+#endif
+ }
#endif
+#ifdef IPOL_C1
+ //complete inside fog
+ if (TL_Flag & TL_FOG)
+ {
+ aFog = tofix(line.c[1][0].a, inversew);
+ if (aFog <= 0)
+ {
+ dst[i] = fog_color_sample;
+ continue;
+ }
+ }
#endif
+
+ tx0 = tofix ( line.t[0][0].x,inversew);
+ ty0 = tofix ( line.t[0][0].y,inversew);
+ tx1 = tofix ( line.t[1][0].x,inversew);
+ ty1 = tofix ( line.t[1][0].y,inversew);
+
+ // diffuse map
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
- // normal map
+ // normal map ( same texcoord0 but different mipmapping)
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );
r1 = ( r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
g1 = ( g1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
b1 = ( b1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
-/*
- sVec3 l = line.l[0][0] * inversew;
- l.setLength( 2.f );
-
- lx = tofix ( l.x - 0.5f );
- ly = tofix ( l.y - 0.5f );
- lz = tofix ( l.z - 0.5f );
-*/
-
+#ifdef IPOL_L0
lx = tofix ( line.l[0][0].x, inversew );
ly = tofix ( line.l[0][0].y, inversew );
lz = tofix ( line.l[0][0].z, inversew );
// DOT 3 Normal Map light in tangent space
- ndotl = saturateFix ( FIX_POINT_HALF_COLOR + (( imulFix ( r1, lx ) + imulFix ( g1, ly ) + imulFix ( b1, lz ) ) << (COLOR_MAX_LOG2-1)) );
+ //max(dot(LightVector, Normal), 0.0);
+ ndotl = clampfix_mincolor( (imulFix_simple(r1,lx) + imulFix_simple(g1,ly) + imulFix_simple(b1,lz) ) );
+#endif
#ifdef IPOL_C0
- // N . L
- r2 = imulFix ( imulFix_tex1 ( r0, ndotl ), r3 );
- g2 = imulFix ( imulFix_tex1 ( g0, ndotl ), g3 );
- b2 = imulFix ( imulFix_tex1 ( b0, ndotl ), b3 );
-
-/*
- // heightmap: (1 - neu ) + alt - 0.5, on_minus_srcalpha + add signed
- // emboss bump map
- a4 -= a1;
- r2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( r0 + a4, r3 ) ) );
- g2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( g0 + a4, g3 ) ) );
- b2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( b0 + a4, b3 ) ) );
-*/
+ //LightColor[0]
+ r3 = tofix(line.c[0][0].y, inversew);
+ g3 = tofix(line.c[0][0].z, inversew);
+ b3 = tofix(line.c[0][0].w, inversew);
+
+ // Lambert * LightColor[0] * Diffuse Texture;
+ r2 = imulFix (imulFix_simple( r3, ndotl ), r0 );
+ g2 = imulFix (imulFix_simple( g3, ndotl ), g0 );
+ b2 = imulFix (imulFix_simple( b3, ndotl ), b0 );
+
+ //vertex alpha blend ( and omit depthwrite ,hacky..)
+ if (a3 + 2 < FIX_POINT_ONE)
+ {
+ color_to_fix(r1, g1, b1, dst[i]);
+ r2 = r1 + imulFix(a3, r2 - r1);
+ g2 = g1 + imulFix(a3, g2 - g1);
+ b2 = b1 + imulFix(a3, b2 - b1);
+ }
+
+#ifdef IPOL_C1
+ //mix with distance
+ if (aFog < FIX_POINT_ONE)
+ {
+ r2 = fog_color[1] + imulFix(aFog, r2 - fog_color[1]);
+ g2 = fog_color[2] + imulFix(aFog, g2 - fog_color[2]);
+ b2 = fog_color[3] + imulFix(aFog, b2 - fog_color[3]);
+ }
+#endif
+ dst[i] = fix_to_sample(r2, g2, b2);
+
-/*
- r2 = clampfix_maxcolor ( imulFix_tex1 ( r2, r1 ) );
- g2 = clampfix_maxcolor ( imulFix_tex1 ( g2, g1 ) );
- b2 = clampfix_maxcolor ( imulFix_tex1 ( b2, b1 ) );
-*/
#else
- r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );
- g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );
- b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );
+ r2 = imulFix_tex4 ( r0, r1 );
+ g2 = imulFix_tex4 ( g0, g1 );
+ b2 = imulFix_tex4 ( b0, b1 );
+ dst[i] = fix_to_sample(r2, g2, b2);
#endif
-
- dst[i] = fix_to_color ( r2, g2, b2 );
-
-#ifdef WRITE_Z
- z[i] = line.z[0];
-#endif
-#ifdef WRITE_W
- z[i] = line.w[0];
-#endif
}
#ifdef IPOL_Z
@@ -339,6 +370,9 @@ void CTRNormalMap::scanline_bilinear ()
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1];
+#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
@@ -355,7 +389,7 @@ void CTRNormalMap::scanline_bilinear ()
}
-void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -366,9 +400,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -403,6 +437,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][0] = a->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
+ scan.c[1][0] = a->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@@ -433,7 +472,6 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
// rasterize upper sub-triangle
- //if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
@@ -455,6 +493,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] = a->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
+ scan.c[1][1] = a->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@@ -476,8 +519,8 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -501,6 +544,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@@ -544,6 +592,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
line.c[0][scan.right] = scan.c[0][1];
#endif
+#ifdef IPOL_C1
+ line.c[1][scan.left] = scan.c[1][0];
+ line.c[1][scan.right] = scan.c[1][1];
+#endif
+
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@@ -565,7 +618,7 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#endif
// render a scanline
- scanline_bilinear ();
+ fragmentShader ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -585,6 +638,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] += scan.slopeC[0][1];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0];
+ scan.c[1][1] += scan.slopeC[1][1];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@@ -609,11 +667,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
}
// rasterize lower sub-triangle
- //if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
- //if( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
@@ -628,6 +684,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
+#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@@ -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];
#endif
#ifdef IPOL_L0
- scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0];
+ scan.l[0][0] = sVec3Pack_unpack(a->LightTangent[0]) + scan.slopeL[0][0] * temp[0];
#endif
}
@@ -662,6 +721,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] = b->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
+ scan.c[1][1] = b->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@@ -683,8 +747,8 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -709,6 +773,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@@ -752,6 +821,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
line.c[0][scan.right] = scan.c[0][1];
#endif
+#ifdef IPOL_C1
+ line.c[1][scan.left] = scan.c[1][0];
+ line.c[1][scan.right] = scan.c[1][1];
+#endif
+
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@@ -773,7 +847,7 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#endif
// render a scanline
- scanline_bilinear ();
+ fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -793,6 +867,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] += scan.slopeC[0][1];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0];
+ scan.c[1][1] += scan.slopeC[1][1];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
diff --git a/source/Irrlicht/CTRStencilShadow.cpp b/source/Irrlicht/CTRStencilShadow.cpp
index 02ed525..82b5ed3 100644
--- a/source/Irrlicht/CTRStencilShadow.cpp
+++ b/source/Irrlicht/CTRStencilShadow.cpp
@@ -47,7 +47,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -84,19 +84,10 @@ public:
CTRStencilShadow(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
- virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
- // fragment shader
- typedef void (CTRStencilShadow::*tFragmentShader) ();
- void fragment_zfail_decr ();
- void fragment_zfail_incr ();
-
- tFragmentShader fragmentShader;
-
- sScanConvertData scan;
- sScanLineData line;
+ void fragmentShader();
};
@@ -112,36 +103,14 @@ CTRStencilShadow::CTRStencilShadow(CBurningVideoDriver* driver)
/*!
*/
-void CTRStencilShadow::setParam ( u32 index, f32 value)
-{
- u32 val = (u32) value;
-
- // glStencilOp (fail,zfail,zpass
- if ( index == 1 && val == 1 )
- {
- fragmentShader = &CTRStencilShadow::fragment_zfail_incr;
- }
- else
- if ( index == 1 && val == 2 )
- {
- fragmentShader = &CTRStencilShadow::fragment_zfail_decr;
- }
-}
-
-/*!
-*/
-void CTRStencilShadow::fragment_zfail_decr ()
+void CTRStencilShadow::fragmentShader()
{
- if (!Stencil)
- return;
- //tVideoSample *dst;
-
#ifdef USE_ZBUFFER
fp24 *z;
#endif
#ifdef USE_SBUFFER
- u32 *stencil;
+ tStencilSample *stencil;
#endif
s32 xStart;
@@ -158,27 +127,19 @@ void CTRStencilShadow::fragment_zfail_decr ()
#ifdef IPOL_W
fp24 slopeW;
#endif
-#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
-#endif
-#ifdef IPOL_T0
- sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
-#endif
-#ifdef IPOL_L0
- sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
-#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
-
if ( dx < 0 )
return;
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -186,21 +147,6 @@ void CTRStencilShadow::fragment_zfail_decr ()
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
-#ifdef IPOL_C0
- slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
-#endif
-#ifdef IPOL_T0
- slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
-#endif
-#ifdef IPOL_T1
- slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
-#endif
-#ifdef IPOL_T2
- slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;
-#endif
-#ifdef IPOL_L0
- slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
-#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
@@ -210,23 +156,8 @@ void CTRStencilShadow::fragment_zfail_decr ()
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
-#ifdef IPOL_C0
- line.c[0][0] += slopeC[0] * subPixel;
-#endif
-#ifdef IPOL_T0
- line.t[0][0] += slopeT[0] * subPixel;
-#endif
-#ifdef IPOL_T1
- line.t[1][0] += slopeT[1] * subPixel;
#endif
-#ifdef IPOL_T2
- line.t[2][0] += slopeT[2] * subPixel;
-#endif
-#ifdef IPOL_L0
- line.l[0][0] += slopeL[0] * subPixel;
-#endif
-#endif
-
+ SOFTWARE_DRIVER_2_CLIPCHECK;
//dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -234,185 +165,43 @@ void CTRStencilShadow::fragment_zfail_decr ()
#endif
#ifdef USE_SBUFFER
- stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
+ stencil = (tStencilSample*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
- f32 inversew;
-#endif
-
-
-#ifdef IPOL_C0
- tFixPoint r3, g3, b3;
+ f32 inversew = FIX_POINT_F32_MUL;
#endif
- for ( s32 i = 0; i <= dx; i++ )
+ s32 i;
+ for (i = 0; i <= dx; i++)
{
#ifdef CMP_Z
- if ( line.z[0] < z[i] )
+ if (line.z[0] < z[i])
#endif
#ifdef CMP_W
- if ( line.w[0] < z[i] )
+ if (line.w[0] > z[i])
#endif
{
- // zfail
- stencil[i] -= 1;
+ // zpass
+ switch (stencilOp[2])
+ {
+ case StencilOp_INCR: stencil[i] += 1; break;
+ case StencilOp_DECR: stencil[i] -= 1; break;// core::s32_max(0, stencil[i] - 1); break;
+ default:
+ case StencilOp_KEEP: break;
+ }
}
-
-#ifdef IPOL_Z
- line.z[0] += slopeZ;
-#endif
-#ifdef IPOL_W
- line.w[0] += slopeW;
-#endif
-#ifdef IPOL_C0
- line.c[0][0] += slopeC[0];
-#endif
-#ifdef IPOL_T0
- line.t[0][0] += slopeT[0];
-#endif
-#ifdef IPOL_T1
- line.t[1][0] += slopeT[1];
-#endif
-#ifdef IPOL_T2
- line.t[2][0] += slopeT[2];
-#endif
-#ifdef IPOL_L0
- line.l[0][0] += slopeL[0];
-#endif
- }
-}
-
-/*!
-*/
-void CTRStencilShadow::fragment_zfail_incr()
-{
- if (!Stencil)
- return;
- //tVideoSample *dst;
-
-#ifdef USE_ZBUFFER
- fp24 *z;
-#endif
-
-#ifdef USE_SBUFFER
- u32 *stencil;
-#endif
-
- s32 xStart;
- s32 xEnd;
- s32 dx;
-
-
-#ifdef SUBTEXEL
- f32 subPixel;
-#endif
-
-#ifdef IPOL_Z
- f32 slopeZ;
-#endif
-#ifdef IPOL_W
- fp24 slopeW;
-#endif
-#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
-#endif
-#ifdef IPOL_T0
- sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
-#endif
-#ifdef IPOL_L0
- sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
-#endif
-
- // apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
-
- dx = xEnd - xStart;
-
- if ( dx < 0 )
- return;
-
- // slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
-
-#ifdef IPOL_Z
- slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
-#endif
-#ifdef IPOL_W
- slopeW = (line.w[1] - line.w[0]) * invDeltaX;
-#endif
-#ifdef IPOL_C0
- slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
-#endif
-#ifdef IPOL_T0
- slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
-#endif
-#ifdef IPOL_T1
- slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
-#endif
-#ifdef IPOL_T2
- slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;
-#endif
-#ifdef IPOL_L0
- slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
-#endif
-
-#ifdef SUBTEXEL
- subPixel = ( (f32) xStart ) - line.x[0];
-#ifdef IPOL_Z
- line.z[0] += slopeZ * subPixel;
-#endif
-#ifdef IPOL_W
- line.w[0] += slopeW * subPixel;
-#endif
-#ifdef IPOL_C0
- line.c[0][0] += slopeC[0] * subPixel;
-#endif
-#ifdef IPOL_T0
- line.t[0][0] += slopeT[0] * subPixel;
-#endif
-#ifdef IPOL_T1
- line.t[1][0] += slopeT[1] * subPixel;
-#endif
-#ifdef IPOL_T2
- line.t[2][0] += slopeT[2] * subPixel;
-#endif
-#ifdef IPOL_L0
- line.l[0][0] += slopeL[0] * subPixel;
-#endif
-#endif
-
- //dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
-
-#ifdef USE_ZBUFFER
- z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
-#endif
-
-#ifdef USE_SBUFFER
- stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
-#endif
-
-#ifdef INVERSE_W
- f32 inversew;
-#endif
-
-#ifdef IPOL_C0
- tFixPoint r3, g3, b3;
-#endif
-
- for ( s32 i = 0; i <= dx; i++ )
- {
-#ifdef CMP_Z
- if ( line.z[0] < z[i] )
-#endif
-#ifdef CMP_W
- if ( line.w[0] < z[i] )
-#endif
+ else
{
// zfail
- stencil[i] += 1;
+ switch (stencilOp[1])
+ {
+ case StencilOp_INCR: stencil[i] += 1; break;
+ case StencilOp_DECR: stencil[i] -= 1; break;// core::s32_max(0, stencil[i] - 1); break;
+ default:
+ case StencilOp_KEEP: break;
+ }
}
#ifdef IPOL_Z
@@ -421,25 +210,12 @@ void CTRStencilShadow::fragment_zfail_incr()
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
-#ifdef IPOL_C0
- line.c[0][0] += slopeC[0];
-#endif
-#ifdef IPOL_T0
- line.t[0][0] += slopeT[0];
-#endif
-#ifdef IPOL_T1
- line.t[1][0] += slopeT[1];
-#endif
-#ifdef IPOL_T2
- line.t[2][0] += slopeT[2];
-#endif
-#ifdef IPOL_L0
- line.l[0][0] += slopeL[0];
-#endif
}
+
}
-void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+
+void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -450,9 +226,9 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -516,7 +292,6 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// rasterize upper sub-triangle
- //if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
@@ -559,8 +334,8 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -648,7 +423,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// render a scanline
- (this->*fragmentShader) ();
+ fragmentShader ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -766,8 +541,8 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -856,7 +631,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// render a scanline
- (this->*fragmentShader) ();
+ fragmentShader ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -915,6 +690,7 @@ namespace video
//! creates a triangle renderer
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver)
{
+ //ETR_STENCIL_SHADOW
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRStencilShadow(driver);
#else
diff --git a/source/Irrlicht/CTRTextureBlend.cpp b/source/Irrlicht/CTRTextureBlend.cpp
index e3ba079..da178eb 100644
--- a/source/Irrlicht/CTRTextureBlend.cpp
+++ b/source/Irrlicht/CTRTextureBlend.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -76,19 +76,32 @@ namespace irr
namespace video
{
-class CTRTextureBlend : public IBurningShader
-{
-public:
+ class CTRTextureBlend : public IBurningShader
+ {
+ public:
- //! constructor
- CTRTextureBlend(CBurningVideoDriver* driver);
+ //! constructor
+ CTRTextureBlend(CBurningVideoDriver* driver);
- //! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ //! draws an indexed triangle list
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
- virtual void setZCompareFunc ( u32 func) _IRR_OVERRIDE_;
- virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;
+#if defined(PATCH_SUPERTUX_8_0_1)
+ virtual void setZCompareFunc(u32 func)
+ {
+ depth_func = (E_COMPARISON_FUNC)func;
+ }
+ virtual void setParam(u32 index, f32 value)
+ {
+ SBurningShaderMaterial material;
+ material.org.ZBuffer = depth_func;
+ material.org.MaterialTypeParam = value;
+ OnSetMaterial(material);
+ }
+
+#endif
private:
// fragment shader
@@ -102,12 +115,11 @@ private:
void fragment_one_one_minus_src_alpha ();
void fragment_one_minus_dst_alpha_one();
void fragment_src_alpha_one();
+ void fragment_src_alpha_one_minus_src_alpha();
tFragmentShader fragmentShader;
- sScanConvertData scan;
- sScanLineData line;
- u32 ZCompare;
+ E_COMPARISON_FUNC depth_func;
};
//! constructor
@@ -118,26 +130,23 @@ CTRTextureBlend::CTRTextureBlend(CBurningVideoDriver* driver)
setDebugName("CTRTextureBlend");
#endif
- ZCompare = 1;
+ depth_func = ECFN_LESSEQUAL;
+ fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;
}
/*!
*/
-void CTRTextureBlend::setZCompareFunc ( u32 func)
+void CTRTextureBlend::OnSetMaterial(const SBurningShaderMaterial& material)
{
- ZCompare = func;
-}
+ int showname = 0;
-/*!
-*/
-void CTRTextureBlend::setParam ( u32 index, f32 value)
-{
- u8 showname = 0;
+ depth_func = (E_COMPARISON_FUNC)material.org.ZBuffer;
+ AlphaRef = 0; // tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
E_BLEND_FACTOR srcFact,dstFact;
E_MODULATE_FUNC modulate;
u32 alphaSrc;
- unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSrc, value );
+ unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSrc, material.org.MaterialTypeParam);
fragmentShader = 0;
@@ -145,43 +154,39 @@ void CTRTextureBlend::setParam ( u32 index, f32 value)
{
fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;
}
- else
- if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE )
+ else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE )
{
fragmentShader = &CTRTextureBlend::fragment_dst_color_one;
}
- else
- if ( srcFact == EBF_DST_COLOR && dstFact == EBF_SRC_ALPHA)
+ else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_SRC_ALPHA)
{
fragmentShader = &CTRTextureBlend::fragment_dst_color_src_alpha;
}
- else
- if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE_MINUS_DST_ALPHA)
+ else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE_MINUS_DST_ALPHA)
{
fragmentShader = &CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha;
}
- else
- if ( srcFact == EBF_ZERO && dstFact == EBF_ONE_MINUS_SRC_COLOR )
+ else if ( srcFact == EBF_ZERO && dstFact == EBF_ONE_MINUS_SRC_COLOR )
{
fragmentShader = &CTRTextureBlend::fragment_zero_one_minus_scr_color;
}
- else
- if ( srcFact == EBF_ONE && dstFact == EBF_ONE_MINUS_SRC_ALPHA)
+ else if ( srcFact == EBF_ONE && dstFact == EBF_ONE_MINUS_SRC_ALPHA)
{
fragmentShader = &CTRTextureBlend::fragment_one_one_minus_src_alpha;
}
- else
- if ( srcFact == EBF_ONE_MINUS_DST_ALPHA && dstFact == EBF_ONE )
+ else if ( srcFact == EBF_ONE_MINUS_DST_ALPHA && dstFact == EBF_ONE )
{
fragmentShader = &CTRTextureBlend::fragment_one_minus_dst_alpha_one;
}
- else
- if ( srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE )
+ else if ( srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE )
{
fragmentShader = &CTRTextureBlend::fragment_src_alpha_one;
}
- else
- if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA )
+ else if (srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE_MINUS_SRC_ALPHA)
+ {
+ fragmentShader = &CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha;
+ }
+ else if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA )
{
fragmentShader = &CTRTextureBlend::fragment_src_color_src_alpha;
}
@@ -213,7 +218,7 @@ void CTRTextureBlend::setParam ( u32 index, f32 value)
{
char buf[128];
snprintf_irr ( buf, 128, "missing shader: %s %s",n[srcFact], n[dstFact] );
- os::Printer::log( buf, ELL_INFORMATION );
+ os::Printer::log( buf, ELL_WARNING);
lsrcFact = srcFact;
ldstFact = dstFact;
@@ -248,15 +253,15 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -264,7 +269,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -301,6 +306,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -315,9 +321,10 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -342,7 +349,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
color_to_fix ( r1, g1, b1, dst[i] );
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
@@ -385,7 +392,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
color_to_fix ( r1, g1, b1, dst[i] );
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
@@ -432,23 +439,22 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
-
if ( dx < 0 )
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -485,6 +491,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -497,11 +504,16 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
tFixPoint a0, r0, g0, b0;
tFixPoint r1, g1, b1;
+#ifdef IPOL_C0
+ tFixPoint a2,r2, g2, b2;
+#endif
+
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -509,9 +521,9 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
#endif
{
-
+ //solves example 08. todo: depth_write.
#ifdef WRITE_W
- z[i] = line.w[0];
+ //z[i] = line.w[0];
#endif
#ifdef INVERSE_W
@@ -519,13 +531,21 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
#endif
getSample_texture ( a0, r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,iw), tofix ( line.t[0][0].y,iw) );
- color_to_fix ( r1, g1, b1, dst[i] );
-// u32 check = imulFix_tex1( r0, r1 );
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1( r0, r1 ) + imulFix_tex1( r1, a0 ) ),
- clampfix_maxcolor ( imulFix_tex1( g0, g1 ) + imulFix_tex1( g1, a0 ) ),
- clampfix_maxcolor ( imulFix_tex1( b0, b1 ) + imulFix_tex1( b1, a0 ) )
+#ifdef IPOL_C0
+ vec4_to_fix(a2,r2, g2, b2, line.c[0][0], iw);
+ //a0 = imulFix(a0, a2); why is vertex color enabled and not vertex_alpha?
+ r0 = imulFix_simple(r0, r2);
+ g0 = imulFix_simple(g0, g2);
+ b0 = imulFix_simple(b0, b2);
+#endif
+
+ color_to_fix ( r1, g1, b1, dst[i] );
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1( r0, r0 ) + imulFix_tex1( r1, a0 ) ),
+ clampfix_maxcolor ( imulFix_tex1( g0, g0 ) + imulFix_tex1( g1, a0 ) ),
+ clampfix_maxcolor ( imulFix_tex1( b0, b0 ) + imulFix_tex1( b1, a0 ) )
);
+
}
#ifdef IPOL_W
@@ -565,7 +585,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
color_to_fix ( r1, g1, b1, dst[i] );
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
@@ -582,6 +602,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
line.c[0][0] += slopeC[0];
#endif
}break;
+
} // zcompare
}
@@ -612,15 +633,15 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -628,7 +649,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2 ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -665,6 +686,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -676,13 +698,15 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
tFixPoint a0,r0, g0, b0;
tFixPoint r1, g1, b1;
+#ifdef IPOL_C0
tFixPoint r2, g2, b2;
-
+#endif
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -704,16 +728,16 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
color_to_fix1 ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix_to_color ( imulFix ( r0 + imulFix ( r1, a0 ), r2 ),
- imulFix ( g0 + imulFix ( g1, a0 ), g2 ),
- imulFix ( b0 + imulFix ( b1, a0 ), b2 )
+ dst[i] = fix_to_sample( imulFix ( r0 + imulFix_simple( r1, a0 ), r2 ),
+ imulFix ( g0 + imulFix_simple( g1, a0 ), g2 ),
+ imulFix ( b0 + imulFix_simple( b1, a0 ), b2 )
);
#else
- dst[i] = fix_to_color ( r0 + imulFix ( r1, a0 ),
- g0 + imulFix ( g1, a0 ),
- b0 + imulFix ( b1, a0 )
+ dst[i] = fix_to_sample( r0 + imulFix_simple( r1, a0 ),
+ g0 + imulFix_simple( g1, a0 ),
+ b0 + imulFix_simple( b1, a0 )
);
#endif
@@ -753,16 +777,16 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
color_to_fix1 ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix_to_color ( imulFix ( r0 + imulFix ( r1, a0 ), r2 ),
- imulFix ( g0 + imulFix ( g1, a0 ), g2 ),
- imulFix ( b0 + imulFix ( b1, a0 ), b2 )
+ dst[i] = fix_to_sample( imulFix ( r0 + imulFix_simple( r1, a0 ), r2 ),
+ imulFix ( g0 + imulFix_simple( g1, a0 ), g2 ),
+ imulFix ( b0 + imulFix_simple( b1, a0 ), b2 )
);
#else
- dst[i] = fix_to_color ( r0 + imulFix ( r1, a0 ),
- g0 + imulFix ( g1, a0 ),
- b0 + imulFix ( b1, a0 )
+ dst[i] = fix_to_sample( r0 + imulFix_simple( r1, a0 ),
+ g0 + imulFix_simple( g1, a0 ),
+ b0 + imulFix_simple( b1, a0 )
);
#endif
@@ -779,6 +803,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
line.c[0][0] += slopeC[0];
#endif
}break;
+
} // zcompare
}
@@ -809,15 +834,15 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -825,7 +850,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -862,6 +887,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -873,13 +899,15 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
tFixPoint r0, g0, b0;
tFixPoint a1, r1, g1, b1;
+#ifdef IPOL_C0
tFixPoint r2, g2, b2;
-
+#endif
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -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) );
color_to_fix1 ( a1, r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
a1 = FIX_POINT_ONE - a1;
- dst[i] = fix_to_color ( imulFix ( imulFix ( r0, a1 ) + r1, r2 ),
- imulFix ( imulFix ( g0, a1 ) + g1, g2 ),
- imulFix ( imulFix ( b0, a1 ) + b1, b2 )
+ dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, a1 ) + r1, r2 ),
+ imulFix (imulFix_simple( g0, a1 ) + g1, g2 ),
+ imulFix (imulFix_simple( b0, a1 ) + b1, b2 )
);
#else
- dst[i] = fix_to_color ( imulFix ( r0, a1) + r0,
- imulFix ( g0, a1) + g0,
- imulFix ( b0, a1) + b0
+ dst[i] = fix_to_sample(imulFix_simple( r0, a1) + r0,
+ imulFix_simple( g0, a1) + g0,
+ imulFix_simple( b0, a1) + b0
);
#endif
@@ -948,17 +976,17 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
color_to_fix1 ( a1, r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
a1 = FIX_POINT_ONE - a1;
- dst[i] = fix_to_color ( imulFix ( imulFix ( r0, a1 ) + r1, r2 ),
- imulFix ( imulFix ( g0, a1 ) + g1, g2 ),
- imulFix ( imulFix ( b0, a1 ) + b1, b2 )
+ dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, a1 ) + r1, r2 ),
+ imulFix (imulFix_simple( g0, a1 ) + g1, g2 ),
+ imulFix (imulFix_simple( b0, a1 ) + b1, b2 )
);
#else
- dst[i] = fix_to_color ( imulFix ( r0, a1) + r0,
- imulFix ( g0, a1) + g0,
- imulFix ( b0, a1) + b0
+ dst[i] = fix_to_sample(imulFix_simple( r0, a1) + r0,
+ imulFix_simple( g0, a1) + g0,
+ imulFix_simple( b0, a1) + b0
);
#endif
@@ -975,6 +1003,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
line.c[0][0] += slopeC[0];
#endif
}break;
+
} // zcompare
}
@@ -1005,15 +1034,15 @@ void CTRTextureBlend::fragment_src_alpha_one ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -1021,7 +1050,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -1058,6 +1087,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -1069,13 +1099,15 @@ void CTRTextureBlend::fragment_src_alpha_one ()
tFixPoint a0, r0, g0, b0;
tFixPoint r1, g1, b1;
+#ifdef IPOL_C0
tFixPoint r2, g2, b2;
-
+#endif
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -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) );
if ( a0 > 0 )
{
- a0 >>= 8;
+ fix_color_norm(a0);
color_to_fix ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix4_to_color ( a0,
- clampfix_maxcolor ( imulFix (r0,a0 ) + r1),
- clampfix_maxcolor ( imulFix (g0,a0 ) + g1),
- clampfix_maxcolor ( imulFix (b0,a0 ) + b1)
+ dst[i] = fix4_to_sample( a0,
+ clampfix_maxcolor (imulFix_simple(r0,a0) + r1),
+ clampfix_maxcolor (imulFix_simple(g0,a0) + g1),
+ clampfix_maxcolor (imulFix_simple(b0,a0) + b1)
);
/*
- a0 >>= 8;
- dst[i] = fix4_to_color ( a0,
- imulFix ( imulFix ( r0, a0 ) + r1, r2 ),
- imulFix ( imulFix ( g0, a0 ) + g1, g2 ),
- imulFix ( imulFix ( b0, a0 ) + b1, b2 )
+ fix_color_norm(a0);
+ dst[i] = fix4_to_sample ( a0,
+ imulFix ( imulFix_simple ( r0, a0 ) + r1, r2 ),
+ imulFix ( imulFix_simple ( g0, a0 ) + g1, g2 ),
+ imulFix ( imulFix_simple ( b0, a0 ) + b1, b2 )
);
*/
#else
- dst[i] = fix4_to_color ( a0,
- clampfix_maxcolor ( imulFix (r0,a0 ) + r1 ),
- clampfix_maxcolor ( imulFix (g0,a0 ) + g1 ),
- clampfix_maxcolor ( imulFix (b0,a0 ) + b1 )
+ dst[i] = fix4_to_sample( a0,
+ clampfix_maxcolor (imulFix_simple(r0,a0 ) + r1 ),
+ clampfix_maxcolor (imulFix_simple(g0,a0 ) + g1 ),
+ clampfix_maxcolor (imulFix_simple(b0,a0 ) + b1 )
);
#endif
@@ -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) );
if ( a0 > 0 )
{
- a0 >>= 8;
+ fix_color_norm(a0);
color_to_fix ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix4_to_color ( a0,
- clampfix_maxcolor ( imulFix ( imulFix (r0,a0 ) + r1, r2 ) ),
- clampfix_maxcolor ( imulFix ( imulFix (g0,a0 ) + g1, g2 ) ),
- clampfix_maxcolor ( imulFix ( imulFix (b0,a0 ) + b1, b2 ) )
+ dst[i] = fix4_to_sample( a0,
+ clampfix_maxcolor ( imulFix (imulFix_simple(r0,a0 ) + r1, r2 ) ),
+ clampfix_maxcolor ( imulFix (imulFix_simple(g0,a0 ) + g1, g2 ) ),
+ clampfix_maxcolor ( imulFix (imulFix_simple(b0,a0 ) + b1, b2 ) )
);
/*
- a0 >>= 8;
- dst[i] = fix4_to_color ( a0,
- imulFix ( imulFix ( r0, a0 ) + r1, r2 ),
- imulFix ( imulFix ( g0, a0 ) + g1, g2 ),
- imulFix ( imulFix ( b0, a0 ) + b1, b2 )
+ fix_color_norm(a0);
+ dst[i] = fix4_to_sample ( a0,
+ imulFix ( imulFix_simple ( r0, a0 ) + r1, r2 ),
+ imulFix ( imulFix_simple ( g0, a0 ) + g1, g2 ),
+ imulFix ( imulFix_simple ( b0, a0 ) + b1, b2 )
);
*/
#else
- dst[i] = fix4_to_color ( a0,
- clampfix_maxcolor ( imulFix (r0,a0 ) + r1 ),
- clampfix_maxcolor ( imulFix (g0,a0 ) + g1 ),
- clampfix_maxcolor ( imulFix (b0,a0 ) + b1 )
+ dst[i] = fix4_to_sample( a0,
+ clampfix_maxcolor (imulFix_simple(r0,a0 ) + r1 ),
+ clampfix_maxcolor (imulFix_simple(g0,a0 ) + g1 ),
+ clampfix_maxcolor (imulFix_simple(b0,a0 ) + b1 )
);
#endif
@@ -1201,6 +1233,160 @@ void CTRTextureBlend::fragment_src_alpha_one ()
line.c[0][0] += slopeC[0];
#endif
}break;
+
+ } // zcompare
+
+}
+
+
+/*!
+*/
+void CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha()
+{
+ tVideoSample *dst;
+
+#ifdef USE_ZBUFFER
+ fp24 *z;
+#endif
+
+ s32 xStart;
+ s32 xEnd;
+ s32 dx;
+
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+#ifdef IPOL_Z
+ f32 slopeZ;
+#endif
+#ifdef IPOL_W
+ fp24 slopeW;
+#endif
+#ifdef IPOL_C0
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
+#endif
+#ifdef IPOL_T0
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
+#endif
+
+ // apply top-left fill-convention, left
+ xStart = fill_convention_left(line.x[0]);
+ xEnd = fill_convention_right(line.x[1]);
+
+ dx = xEnd - xStart;
+ if (dx < 0)
+ return;
+
+ // slopes
+ const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);
+
+#ifdef IPOL_Z
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
+#endif
+#ifdef IPOL_W
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;
+#endif
+#ifdef IPOL_C0
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T0
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T1
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
+#endif
+
+#ifdef SUBTEXEL
+ subPixel = ((f32)xStart) - line.x[0];
+#ifdef IPOL_Z
+ line.z[0] += slopeZ * subPixel;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW * subPixel;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC[0] * subPixel;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0] * subPixel;
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1] * subPixel;
+#endif
+#endif
+
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
+
+#ifdef USE_ZBUFFER
+ z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
+#endif
+
+
+ f32 iw = FIX_POINT_F32_MUL;
+
+ tFixPoint a0, r0, g0, b0;
+ tFixPoint r1, g1, b1;
+ tFixPoint a2, r2, g2, b2;
+
+ s32 i;
+
+ switch (depth_func)
+ {
+ default:
+ case ECFN_LESSEQUAL:
+ for (i = 0; i <= dx; ++i)
+ {
+#ifdef CMP_W
+ if (line.w[0] >= z[i])
+#endif
+
+ {
+#ifdef WRITE_W
+ //z[i] = line.w[0];
+#endif
+
+#ifdef INVERSE_W
+ iw = fix_inverse32(line.w[0]);
+#endif
+
+ getSample_texture(a0, r0, g0, b0, &IT[0], tofix(line.t[0][0].x, iw), tofix(line.t[0][0].y, iw));
+ if (a0 > AlphaRef)
+ {
+#ifdef IPOL_C0
+ vec4_to_fix(a2, r2, g2, b2, line.c[0][0], iw);
+ //a0 = imulFix(a0, a2); why is vertex color enabled and not vertex_alpha?
+ r0 = imulFix_simple(r0, r2);
+ g0 = imulFix_simple(g0, g2);
+ b0 = imulFix_simple(b0, b2);
+#endif
+
+ color_to_fix(r1, g1, b1, dst[i]);
+
+ fix_color_norm(a0);
+
+ r2 = r1 + imulFix(a0, r0 - r1);
+ g2 = g1 + imulFix(a0, g0 - g1);
+ b2 = b1 + imulFix(a0, b0 - b1);
+ dst[i] = fix4_to_sample(a0, r2, g2, b2);
+ }
+
+ }
+
+#ifdef IPOL_W
+ line.w[0] += slopeW;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0];
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC[0];
+#endif
+ }
+ break;
+
} // zcompare
}
@@ -1232,15 +1418,15 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -1248,7 +1434,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -1285,6 +1471,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -1296,13 +1483,15 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
tFixPoint r0, g0, b0;
tFixPoint a1, r1, g1, b1;
+#ifdef IPOL_C0
tFixPoint r2, g2, b2;
-
+#endif
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -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) );
color_to_fix1 ( a1, r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
a1 = FIX_POINT_ONE - a1;
- dst[i] = fix_to_color ( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),
+ dst[i] = fix_to_sample( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),
imulFix ( imulFix ( g1, g0 + a1 ), g2 ),
imulFix ( imulFix ( b1, b0 + a1 ), b2 )
);
#else
- dst[i] = fix_to_color ( imulFix ( r1, r0 + a1 ),
+ dst[i] = fix_to_sample( imulFix ( r1, r0 + a1 ),
imulFix ( g1, g0 + a1 ),
imulFix ( b1, b0 + a1 )
);
@@ -1371,15 +1560,15 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
color_to_fix1 ( a1, r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
a1 = FIX_POINT_ONE - a1;
- dst[i] = fix_to_color ( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),
+ dst[i] = fix_to_sample( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),
imulFix ( imulFix ( g1, g0 + a1 ), g2 ),
imulFix ( imulFix ( b1, b0 + a1 ), b2 )
);
#else
- dst[i] = fix_to_color ( imulFix ( r1, r0 + a1 ),
+ dst[i] = fix_to_sample( imulFix ( r1, r0 + a1 ),
imulFix ( g1, g0 + a1 ),
imulFix ( b1, b0 + a1 )
);
@@ -1428,15 +1617,15 @@ void CTRTextureBlend::fragment_dst_color_zero ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -1444,7 +1633,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -1481,6 +1670,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -1492,13 +1682,15 @@ void CTRTextureBlend::fragment_dst_color_zero ()
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
+#ifdef IPOL_C0
tFixPoint r2, g2, b2;
-
+#endif
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -1519,15 +1711,15 @@ void CTRTextureBlend::fragment_dst_color_zero ()
color_to_fix1 ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix_to_color ( imulFix ( imulFix ( r0, r1 ), r2 ),
- imulFix ( imulFix ( g0, g1 ), g2 ),
- imulFix ( imulFix ( b0, b1 ), b2 ) );
+ dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, r1 ), r2 ),
+ imulFix (imulFix_simple( g0, g1 ), g2 ),
+ imulFix (imulFix_simple( b0, b1 ), b2 ) );
#else
- dst[i] = fix_to_color ( imulFix ( r0, r1 ),
- imulFix ( g0, g1 ),
- imulFix ( b0, b1 )
+ dst[i] = fix_to_sample(imulFix_simple( r0, r1 ),
+ imulFix_simple( g0, g1 ),
+ imulFix_simple( b0, b1 )
);
#endif
@@ -1566,16 +1758,16 @@ void CTRTextureBlend::fragment_dst_color_zero ()
color_to_fix1 ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix_to_color ( imulFix ( imulFix ( r0, r1 ), r2 ),
- imulFix ( imulFix ( g0, g1 ), g2 ),
- imulFix ( imulFix ( b0, b1 ), b2 )
+ dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, r1 ), r2 ),
+ imulFix (imulFix_simple( g0, g1 ), g2 ),
+ imulFix (imulFix_simple( b0, b1 ), b2 )
);
#else
- dst[i] = fix_to_color ( imulFix ( r0, r1 ),
- imulFix ( g0, g1 ),
- imulFix ( b0, b1 )
+ dst[i] = fix_to_sample(imulFix_simple( r0, r1 ),
+ imulFix_simple( g0, g1 ),
+ imulFix_simple( b0, b1 )
);
#endif
@@ -1622,15 +1814,15 @@ void CTRTextureBlend::fragment_dst_color_one ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -1638,7 +1830,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -1675,6 +1867,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -1686,13 +1879,15 @@ void CTRTextureBlend::fragment_dst_color_one ()
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
+#ifdef IPOL_C0
tFixPoint r2, g2, b2;
-
+#endif
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -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) );
color_to_fix ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),
clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )
);
#else
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),
clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )
);
@@ -1761,15 +1956,15 @@ void CTRTextureBlend::fragment_dst_color_one ()
color_to_fix ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),
clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )
);
#else
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),
clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),
clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )
);
@@ -1819,15 +2014,15 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -1835,7 +2030,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -1872,6 +2067,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -1883,13 +2079,15 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
+#ifdef IPOL_C0
tFixPoint r2, g2, b2;
-
+#endif
s32 i;
- switch ( ZCompare )
+ switch (depth_func)
{
- case 1:
+ default:
+ case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i )
{
#ifdef CMP_W
@@ -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) );
color_to_fix1 ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),
- imulFix ( FIX_POINT_ONE - g0, g1 ),
- imulFix ( FIX_POINT_ONE - b0, b1 )
+ dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),
+ imulFix( FIX_POINT_ONE - g0, g1 ),
+ imulFix( FIX_POINT_ONE - b0, b1 )
);
#else
- dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),
- imulFix ( FIX_POINT_ONE - g0, g1 ),
- imulFix ( FIX_POINT_ONE - b0, b1 )
+ dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),
+ imulFix( FIX_POINT_ONE - g0, g1 ),
+ imulFix( FIX_POINT_ONE - b0, b1 )
);
#endif
@@ -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) );
color_to_fix1 ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- getSample_color ( r2, g2, b2, line.c[0][0],iw );
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );
- dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),
- imulFix ( FIX_POINT_ONE - g0, g1 ),
- imulFix ( FIX_POINT_ONE - b0, b1 )
+ dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),
+ imulFix( FIX_POINT_ONE - g0, g1 ),
+ imulFix( FIX_POINT_ONE - b0, b1 )
);
#else
- dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),
- imulFix ( FIX_POINT_ONE - g0, g1 ),
- imulFix ( FIX_POINT_ONE - b0, b1 )
+ dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),
+ imulFix( FIX_POINT_ONE - g0, g1 ),
+ imulFix( FIX_POINT_ONE - b0, b1 )
);
#endif
@@ -1990,7 +2188,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
-void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
if ( 0 == fragmentShader )
return;
@@ -2004,9 +2202,9 @@ void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -2092,8 +2290,8 @@ void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -2251,8 +2449,8 @@ void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -2371,6 +2569,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver)
{
+ // EMT_ONETEXTURE_BLEND
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureBlend(driver);
#else
diff --git a/source/Irrlicht/CTRTextureDetailMap2.cpp b/source/Irrlicht/CTRTextureDetailMap2.cpp
index f5653ab..3e75c2d 100644
--- a/source/Irrlicht/CTRTextureDetailMap2.cpp
+++ b/source/Irrlicht/CTRTextureDetailMap2.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -84,13 +84,11 @@ public:
CTRTextureDetailMap2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual bool canWireFrame () { return true; }
-
-private:
- void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
+protected:
+ virtual void scanline_bilinear ();
};
@@ -138,8 +136,8 @@ void CTRTextureDetailMap2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -147,7 +145,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -184,6 +182,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -203,6 +202,8 @@ void CTRTextureDetailMap2::scanline_bilinear ()
for ( s32 i = 0; i <= dx; ++i )
{
+ if ( (0 == EdgeTestPass) & i ) break;
+
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
@@ -222,16 +223,13 @@ void CTRTextureDetailMap2::scanline_bilinear ()
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
getSample_texture ( r1, g1, b1, &IT[1], tx1,ty1 );
- // bias half color
- r1 += -FIX_POINT_HALF_COLOR;
- g1 += -FIX_POINT_HALF_COLOR;
- b1 += -FIX_POINT_HALF_COLOR;
+ // add signed
- r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 ) );
- g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 ) );
- b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 ) );
+ r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 - FIX_POINT_HALF_COLOR ) );
+ g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 - FIX_POINT_HALF_COLOR ) );
+ b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 - FIX_POINT_HALF_COLOR ) );
- dst[i] = fix_to_color ( r2, g2, b2 );
+ dst[i] = fix_to_sample( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
@@ -261,7 +259,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
}
-void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -272,9 +270,9 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_edge( ca );
+ scan.invDeltaY[1] = reciprocal_edge( ba );
+ scan.invDeltaY[2] = reciprocal_edge( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -360,8 +358,8 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -519,8 +517,8 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
diff --git a/source/Irrlicht/CTRTextureGouraud2.cpp b/source/Irrlicht/CTRTextureGouraud2.cpp
index 7bcc512..ef86460 100644
--- a/source/Irrlicht/CTRTextureGouraud2.cpp
+++ b/source/Irrlicht/CTRTextureGouraud2.cpp
@@ -21,8 +21,11 @@
#undef INVERSE_W
#undef IPOL_C0
+#undef IPOL_C1
+#undef IPOL_C2
#undef IPOL_T0
#undef IPOL_T1
+#undef IPOL_L0
// define render case
#define SUBTEXEL
@@ -34,8 +37,11 @@
#define WRITE_W
#define IPOL_C0
+#define IPOL_C1
+//#define IPOL_C2
#define IPOL_T0
//#define IPOL_T1
+//#define IPOL_L0
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
@@ -46,10 +52,23 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
+#if BURNING_MATERIAL_MAX_COLORS < 2
+ #undef IPOL_C1
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS < 3
+#undef IPOL_C2
+#endif
+
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
+ #undef IPOL_L0
+#endif
+
+
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@@ -83,14 +102,12 @@ public:
CTRTextureGouraud2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual bool canWireFrame () { return true; }
private:
- void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
-
+ void fragmentShader ();
};
//! constructor
@@ -106,7 +123,7 @@ CTRTextureGouraud2::CTRTextureGouraud2(CBurningVideoDriver* driver)
/*!
*/
-void CTRTextureGouraud2::scanline_bilinear ()
+void CTRTextureGouraud2::fragmentShader ()
{
tVideoSample *dst;
@@ -130,15 +147,19 @@ void CTRTextureGouraud2::scanline_bilinear ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC;
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
+#ifdef IPOL_L0
+ sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
+#endif
+
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -146,7 +167,7 @@ void CTRTextureGouraud2::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -155,7 +176,13 @@ void CTRTextureGouraud2::scanline_bilinear ()
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
- slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_C1
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
+#endif
+#ifdef IPOL_C2
+ slopeC[2] = (line.c[2][1] - line.c[2][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@@ -163,6 +190,10 @@ void CTRTextureGouraud2::scanline_bilinear ()
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
+#ifdef IPOL_L0
+ slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
+#endif
+
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
@@ -173,7 +204,13 @@ void CTRTextureGouraud2::scanline_bilinear ()
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
- line.c[0][0] += slopeC * subPixel;
+ line.c[0][0] += slopeC[0] * subPixel;
+#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1] * subPixel;
+#endif
+#ifdef IPOL_C2
+ line.c[2][0] += slopeC[2] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
@@ -181,8 +218,12 @@ void CTRTextureGouraud2::scanline_bilinear ()
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
+#ifdef IPOL_L0
+ line.l[0][0] += slopeL[0] * subPixel;
+#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -195,18 +236,29 @@ void CTRTextureGouraud2::scanline_bilinear ()
tFixPoint tx0;
tFixPoint ty0;
- tFixPoint r0, g0, b0;
-
#ifdef IPOL_C0
+ tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#endif
-#ifdef BURNINGVIDEO_RENDERER_FAST
+#ifdef IPOL_C1
+ tFixPoint aFog = FIX_POINT_ONE;
+#endif
+
+
+#ifdef IPOL_C2
+ tFixPoint r3, g3, b3;
+#endif
+
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = ( line.y & 3 ) << 2;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
+ //if test active only first pixel
+ if ( (0 == EdgeTestPass) & i ) break;
+
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
@@ -221,41 +273,70 @@ void CTRTextureGouraud2::scanline_bilinear ()
z[i] = line.w[0];
#endif
-
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
+#endif
+
+#ifdef IPOL_C1
+ //complete inside fog
+ if (TL_Flag & TL_FOG)
+ {
+ aFog = tofix(line.c[1][0].a, inversew);
+ if (aFog <= 0)
+ {
+ dst[i] = fog_color_sample;
+ continue;
+ }
+ }
+#endif
tx0 = tofix ( line.t[0][0].x, inversew);
ty0 = tofix ( line.t[0][0].y, inversew);
+
#ifdef IPOL_C0
- r1 = tofix ( line.c[0][0].y ,inversew );
- g1 = tofix ( line.c[0][0].z ,inversew );
- b1 = tofix ( line.c[0][0].w ,inversew );
-#endif
+
+ getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);
+ vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);
+
+ r0 = imulFix_simple(r0, r1);
+ g0 = imulFix_simple(g0, g1);
+ b0 = imulFix_simple(b0, b1);
+
+#ifdef IPOL_C1
+
+ //specular highlight
+ if (TL_Flag & TL_SPECULAR)
+ {
+ vec4_to_fix(r1, g1, b1, line.c[1][0], inversew*COLOR_MAX);
+ r0 = clampfix_maxcolor(r1 + r0);
+ g0 = clampfix_maxcolor(g1 + g0);
+ b0 = clampfix_maxcolor(b1 + b0);
+ }
+ //mix with distance
+ if (aFog < FIX_POINT_ONE)
+ {
+ r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);
+ g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);
+ b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);
+ }
+ dst[i] = fix_to_sample(r0, g0, b0);
#else
- tx0 = tofix(line.t[0][0].x, inversew);
- ty0 = tofix(line.t[0][0].y, inversew);
-#ifdef IPOL_C0
- getTexel_plain2 ( r1, g1, b1, line.c[0][0] );
-#endif
+ dst[i] = fix_to_sample(
+ imulFix_simple(r0, r1),
+ imulFix_simple(g0, g1),
+ imulFix_simple(b0, b1)
+ );
#endif
-#ifdef IPOL_C0
- getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
-
- dst[i] = fix_to_color ( imulFix ( r0, r1 ),
- imulFix ( g0, g1 ),
- imulFix ( b0, b1 )
- );
#else
-#ifdef BURNINGVIDEO_RENDERER_FAST
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
dst[i] = getTexel_plain ( &IT[0], d + tx0, d + ty0 );
#else
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
- dst[i] = fix_to_color ( r0, g0, b0 );
+ dst[i] = fix_to_sample( r0, g0, b0 );
#endif
#endif
@@ -269,7 +350,13 @@ void CTRTextureGouraud2::scanline_bilinear ()
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
- line.c[0][0] += slopeC;
+ line.c[0][0] += slopeC[0];
+#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1];
+#endif
+#ifdef IPOL_C2
+ line.c[2][0] += slopeC[2];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
@@ -277,11 +364,14 @@ void CTRTextureGouraud2::scanline_bilinear ()
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
+#ifdef IPOL_L0
+ line.l[0][0] += slopeL[0];
+#endif
}
}
-void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -292,9 +382,9 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -329,6 +419,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][0] = a->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
+ scan.c[1][0] = a->Color[1];
+#endif
+
+#ifdef IPOL_C2
+ scan.slopeC[2][0] = (c->Color[2] - a->Color[2]) * scan.invDeltaY[0];
+ scan.c[2][0] = a->Color[2];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@@ -339,6 +439,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][0] = a->Tex[1];
#endif
+#ifdef IPOL_L0
+ scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0];
+ scan.l[0][0] = a->LightTangent[0];
+#endif
+
// top left fill convention y run
s32 yStart;
s32 yEnd;
@@ -348,7 +453,7 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
#endif
// rasterize upper sub-triangle
- if ( (f32) 0.0 != scan.invDeltaY[1] )
+ if ( F32_GREATER_0(scan.invDeltaY[1]) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@@ -369,6 +474,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] = a->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
+ scan.c[1][1] = a->Color[1];
+#endif
+
+#ifdef IPOL_C2
+ scan.slopeC[2][1] = (b->Color[2] - a->Color[2]) * scan.invDeltaY[1];
+ scan.c[2][1] = a->Color[2];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@@ -379,9 +494,14 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] = a->Tex[1];
#endif
+#ifdef IPOL_L0
+ scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1];
+ scan.l[0][1] = a->LightTangent[0];
+#endif
+
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -405,6 +525,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;
+#endif
+
+#ifdef IPOL_C2
+ scan.c[2][0] += scan.slopeC[2][0] * subPixel;
+ scan.c[2][1] += scan.slopeC[2][1] * subPixel;
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@@ -415,6 +545,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
+#ifdef IPOL_L0
+ scan.l[0][0] += scan.slopeL[0][0] * subPixel;
+ scan.l[0][1] += scan.slopeL[0][1] * subPixel;
+#endif
+
#endif
// rasterize the edge scanlines
@@ -438,6 +573,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
line.c[0][scan.right] = scan.c[0][1];
#endif
+#ifdef IPOL_C1
+ line.c[1][scan.left] = scan.c[1][0];
+ line.c[1][scan.right] = scan.c[1][1];
+#endif
+
+#ifdef IPOL_C2
+ line.c[2][scan.left] = scan.c[2][0];
+ line.c[2][scan.right] = scan.c[2][1];
+#endif
+
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@@ -448,8 +593,15 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
line.t[1][scan.right] = scan.t[1][1];
#endif
+#ifdef IPOL_L0
+ line.l[0][scan.left] = scan.l[0][0];
+ line.l[0][scan.right] = scan.l[0][1];
+#endif
+
// render a scanline
- scanline_bilinear ();
+ fragmentShader ();
+ if ( EdgeTestPass & edge_test_first_line ) break;
+
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -469,6 +621,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] += scan.slopeC[0][1];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0];
+ scan.c[1][1] += scan.slopeC[1][1];
+#endif
+
+#ifdef IPOL_C2
+ scan.c[2][0] += scan.slopeC[2][0];
+ scan.c[2][1] += scan.slopeC[2][1];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@@ -479,14 +641,19 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] += scan.slopeT[1][1];
#endif
+#ifdef IPOL_L0
+ scan.l[0][0] += scan.slopeL[0][0];
+ scan.l[0][1] += scan.slopeL[0][1];
+#endif
+
}
}
// rasterize lower sub-triangle
- if ( (f32) 0.0 != scan.invDeltaY[2] )
+ if (F32_GREATER_0(scan.invDeltaY[2]) )
{
// advance to middle point
- if( (f32) 0.0 != scan.invDeltaY[1] )
+ if(F32_GREATER_0(scan.invDeltaY[1]) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
@@ -500,6 +667,12 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
+#endif
+#ifdef IPOL_C2
+ scan.c[2][0] = a->Color[2] + scan.slopeC[2][0] * temp[0];
+#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@@ -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];
#endif
+#ifdef IPOL_L0
+ scan.l[0][0] = sVec3Pack_unpack(a->LightTangent[0]) + scan.slopeL[0][0] * temp[0];
+#endif
}
// calculate slopes for bottom edge
@@ -528,6 +704,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] = b->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
+ scan.c[1][1] = b->Color[1];
+#endif
+
+#ifdef IPOL_C2
+ scan.slopeC[2][1] = (c->Color[2] - b->Color[2]) * scan.invDeltaY[2];
+ scan.c[2][1] = b->Color[2];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@@ -538,9 +724,14 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] = b->Tex[1];
#endif
+#ifdef IPOL_L0
+ scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2];
+ scan.l[0][1] = b->LightTangent[0];
+#endif
+
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -565,6 +756,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;
+#endif
+
+#ifdef IPOL_C1
+ scan.c[2][0] += scan.slopeC[2][0] * subPixel;
+ scan.c[2][1] += scan.slopeC[2][1] * subPixel;
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@@ -575,6 +776,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
+#ifdef IPOL_L0
+ scan.l[0][0] += scan.slopeL[0][0] * subPixel;
+ scan.l[0][1] += scan.slopeL[0][1] * subPixel;
+#endif
+
#endif
// rasterize the edge scanlines
@@ -598,6 +804,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
line.c[0][scan.right] = scan.c[0][1];
#endif
+#ifdef IPOL_C1
+ line.c[1][scan.left] = scan.c[1][0];
+ line.c[1][scan.right] = scan.c[1][1];
+#endif
+
+#ifdef IPOL_C2
+ line.c[2][scan.left] = scan.c[2][0];
+ line.c[2][scan.right] = scan.c[2][1];
+#endif
+
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@@ -608,8 +824,15 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
line.t[1][scan.right] = scan.t[1][1];
#endif
+#ifdef IPOL_L0
+ line.l[0][scan.left] = scan.l[0][0];
+ line.l[0][scan.right] = scan.l[0][1];
+#endif
+
// render a scanline
- scanline_bilinear ( );
+ fragmentShader ();
+ if ( EdgeTestPass & edge_test_first_line ) break;
+
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -629,6 +852,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] += scan.slopeC[0][1];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0];
+ scan.c[1][1] += scan.slopeC[1][1];
+#endif
+
+#ifdef IPOL_C2
+ scan.c[2][0] += scan.slopeC[2][0];
+ scan.c[2][1] += scan.slopeC[2][1];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@@ -639,6 +872,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] += scan.slopeT[1][1];
#endif
+#ifdef IPOL_L0
+ scan.l[0][0] += scan.slopeL[0][0];
+ scan.l[0][1] += scan.slopeL[0][1];
+#endif
+
}
}
@@ -657,6 +895,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver)
{
+ // ETR_TEXTURE_GOURAUD
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraud2(driver);
#else
diff --git a/source/Irrlicht/CTRTextureGouraudAdd2.cpp b/source/Irrlicht/CTRTextureGouraudAdd2.cpp
index 0f54928..040c83d 100644
--- a/source/Irrlicht/CTRTextureGouraudAdd2.cpp
+++ b/source/Irrlicht/CTRTextureGouraudAdd2.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -84,13 +84,11 @@ public:
CTRTextureGouraudAdd2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
- sScanLineData line;
-
};
//! constructor
@@ -137,8 +135,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -146,7 +144,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -183,6 +181,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -193,9 +192,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
f32 inversew = FIX_POINT_F32_MUL;
-#ifdef BURNINGVIDEO_RENDERER_FAST
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = ( line.y & 3 ) << 2;
-
#else
tFixPoint tx0;
tFixPoint ty0;
@@ -216,32 +214,28 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
{
+#ifdef INVERSE_W
+ inversew = fix_inverse32(line.w[0]);
+#endif
-#ifdef BURNINGVIDEO_RENDERER_FAST
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
-
-#ifdef INVERSE_W
- inversew = fix_inverse32 ( line.w[0] );
-#endif
- dst[i] = PixelAdd32 (
- dst[i],
- getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
- d + tofix ( line.t[0][0].y,inversew) )
- );
+ dst[i] = PixelAdd32 (
+ dst[i],
+ getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
+ d + tofix ( line.t[0][0].y,inversew) )
+ );
#else
-#ifdef INVERSE_W
- inversew = fix_inverse32 ( line.w[0] );
-#endif
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
color_to_fix ( r1, g1, b1, dst[i] );
- dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + r0 ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( r1 + r0 ),
clampfix_maxcolor ( g1 + g0 ),
clampfix_maxcolor ( b1 + b0 )
);
@@ -275,10 +269,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
}
-void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
- sScanConvertData scan;
-
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
@@ -288,9 +280,9 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
// find if the major edge is left or right aligned
f32 temp[4];
@@ -373,8 +365,8 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -532,8 +524,8 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -651,6 +643,8 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver)
{
+ //ETR_TEXTURE_GOURAUD_ADD
+
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAdd2(driver);
#else
diff --git a/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp b/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp
index 1c7f586..4a61953 100644
--- a/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp
+++ b/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp
@@ -33,38 +33,38 @@
#define CMP_W
//#define WRITE_W
-//#define IPOL_C0
+#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
- #undef INVERSE_W
- #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
- #undef IPOL_W
- #endif
+#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
- #undef SUBTEXEL
+#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
- #undef IPOL_C0
+#if BURNING_MATERIAL_MAX_COLORS < 1
+#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
- #define IPOL_Z
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+#undef IPOL_W
+#endif
+#define IPOL_Z
- #ifdef CMP_W
- #undef CMP_W
- #define CMP_Z
- #endif
+#ifdef CMP_W
+#undef CMP_W
+#define CMP_Z
+#endif
- #ifdef WRITE_W
- #undef WRITE_W
- #define WRITE_Z
- #endif
+#ifdef WRITE_W
+#undef WRITE_W
+#define WRITE_Z
+#endif
#endif
@@ -83,13 +83,11 @@ public:
CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
- void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
+ void fragmentShader();
};
@@ -106,7 +104,7 @@ CTRTextureGouraudAddNoZ2::CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)
/*!
*/
-void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
+void CTRTextureGouraudAddNoZ2::fragmentShader()
{
tVideoSample *dst;
@@ -137,16 +135,15 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
-
if ( dx < 0 )
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -155,7 +152,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
- slopeC = (line.c[1] - line.c[0]) * invDeltaX;
+ slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@@ -173,7 +170,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
- line.c[0] += slopeC * subPixel;
+ line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
@@ -183,6 +180,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -198,6 +196,10 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
+#ifdef IPOL_C0
+ tFixPoint r2, g2, b2;
+#endif
+
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
@@ -207,20 +209,30 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
if ( line.w[0] >= z[i] )
#endif
{
-#ifdef IPOL_W
+#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
- getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
-
- color_to_fix ( r1, g1, b1, dst[i] );
+ getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);
- dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + (r0 >> 1 ) ),
- clampfix_maxcolor ( g1 + (g0 >> 1 ) ),
- clampfix_maxcolor ( b1 + (b0 >> 1) )
- );
+#ifdef IPOL_C0
+ vec4_to_fix(r2, g2, b2, line.c[0][0], inversew);
+ r0 = imulFix(r2, r0);
+ g0 = imulFix(g2, g0);
+ b0 = imulFix(b2, b0);
+#endif
+
+ //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
+ if (r0 | g0 | b0)
+ {
+ color_to_fix(r1, g1, b1, dst[i]);
+ r1 = imulFix_tex1(r1, FIXPOINT_COLOR_MAX - r0);
+ g1 = imulFix_tex1(g1, FIXPOINT_COLOR_MAX - g0);
+ b1 = imulFix_tex1(b1, FIXPOINT_COLOR_MAX - b0);
+ dst[i] = fix_to_sample(r0+r1, g0+g1, b0+b1);
+ }
#ifdef WRITE_Z
z[i] = line.z[0];
@@ -237,7 +249,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
- line.c[0] += slopeC;
+ line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
@@ -249,8 +261,11 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
}
-void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
+ //billboard discard
+ //if (a->Color[0].r <= 0.f) return;
+
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
@@ -260,9 +275,9 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -293,8 +308,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
- scan.c[0] = a->Color[0];
+ scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
+ scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
@@ -316,7 +331,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// rasterize upper sub-triangle
- if ( (f32) 0.0 != scan.invDeltaY[1] )
+ if (F32_GREATER_0(scan.invDeltaY[1]) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@@ -333,8 +348,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
- scan.c[1] = a->Color[0];
+ scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
+ scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
@@ -348,8 +363,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -369,8 +384,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- scan.c[0] += scan.slopeC[0] * subPixel;
- scan.c[1] += scan.slopeC[1] * subPixel;
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
@@ -402,8 +417,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- line.c[scan.left] = scan.c[0];
- line.c[scan.right] = scan.c[1];
+ line.c[0][scan.left] = scan.c[0][0];
+ line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
@@ -417,7 +432,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// render a scanline
- scanline_bilinear ();
+ fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -433,8 +448,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- scan.c[0] += scan.slopeC[0];
- scan.c[1] += scan.slopeC[1];
+ scan.c[0][0] += scan.slopeC[0][0];
+ scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
@@ -451,10 +466,10 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
}
// rasterize lower sub-triangle
- if ( (f32) 0.0 != scan.invDeltaY[2] )
+ if (F32_GREATER_0(scan.invDeltaY[2]) )
{
// advance to middle point
- if( (f32) 0.0 != scan.invDeltaY[1] )
+ if(F32_GREATER_0(scan.invDeltaY[1]) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
@@ -466,7 +481,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
- scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
+ scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
@@ -492,8 +507,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
- scan.c[1] = b->Color[0];
+ scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
+ scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
@@ -507,8 +522,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -529,8 +544,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- scan.c[0] += scan.slopeC[0] * subPixel;
- scan.c[1] += scan.slopeC[1] * subPixel;
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
@@ -562,8 +577,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- line.c[scan.left] = scan.c[0];
- line.c[scan.right] = scan.c[1];
+ line.c[0][scan.left] = scan.c[0][0];
+ line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
@@ -577,7 +592,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// render a scanline
- scanline_bilinear ( );
+ fragmentShader( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -593,8 +608,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
- scan.c[0] += scan.slopeC[0];
- scan.c[1] += scan.slopeC[1];
+ scan.c[0][0] += scan.slopeC[0][0];
+ scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
@@ -625,6 +640,20 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)
{
+ /*
+ ETR_TEXTURE_GOURAUD_ADD_NO_Z
+
+ Irrlicht:
+ Material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;
+ Material.ZBuffer = ECFN_DISABLED;
+ -> need Material.ZWriteEnable off
+
+ OpenGL
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
+ */
+
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAddNoZ2(driver);
#else
diff --git a/source/Irrlicht/CTRTextureGouraudAlpha.cpp b/source/Irrlicht/CTRTextureGouraudAlpha.cpp
index 37bb477..6e92235 100644
--- a/source/Irrlicht/CTRTextureGouraudAlpha.cpp
+++ b/source/Irrlicht/CTRTextureGouraudAlpha.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -84,18 +84,12 @@ public:
CTRTextureGouraudAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
-
- virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;
-
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
-
- u32 AlphaRef;
};
//! constructor
@@ -105,19 +99,17 @@ CTRTextureGouraudAlpha2::CTRTextureGouraudAlpha2(CBurningVideoDriver* driver)
#ifdef _DEBUG
setDebugName("CTRTextureGouraudAlpha2");
#endif
-
- AlphaRef = 0;
}
/*!
*/
-void CTRTextureGouraudAlpha2::setParam ( u32 index, f32 value)
+void CTRTextureGouraudAlpha2::OnSetMaterial(const SBurningShaderMaterial& material)
{
-#ifdef BURNINGVIDEO_RENDERER_FAST
- AlphaRef = core::floor32_fast( value * 256.f );
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+ AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);
#else
- AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) );
+ AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
#endif
}
@@ -147,15 +139,15 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -163,7 +155,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -200,6 +192,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -209,18 +202,16 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
f32 inversew = FIX_POINT_F32_MUL;
-#ifdef BURNINGVIDEO_RENDERER_FAST
- u32 dIndex = ( line.y & 3 ) << 2;
-
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+ u32 dIndex = (line.y & 3) << 2;
#else
- tFixPoint a0;
- tFixPoint r0, g0, b0;
-#endif
+ tFixPoint a0, r0, g0, b0;
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#endif
+#endif
for ( s32 i = 0; i <= dx; ++i )
{
@@ -233,7 +224,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
{
-#ifdef BURNINGVIDEO_RENDERER_FAST
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
@@ -245,7 +236,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
d + tofix ( line.t[0][0].y,inversew)
);
- const u32 alpha = ( argb >> 24 );
+ const tFixPoint alpha = ( argb >> 24 );
if ( alpha > AlphaRef )
{
#ifdef WRITE_Z
@@ -263,19 +254,14 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
+#endif
getSample_texture ( a0,r0,g0,b0,
&IT[0],
tofix ( line.t[0][0].x,inversew),
tofix ( line.t[0][0].y,inversew)
);
-#else
- getSample_texture ( a0,r0,g0,b0,
- &IT[0],
- tofix ( line.t[0][0].x),
- tofix ( line.t[0][0].y)
- );
-#endif
- if ( (tFixPointu) a0 > AlphaRef )
+
+ if ( a0 > AlphaRef )
{
#ifdef WRITE_Z
z[i] = line.z[0];
@@ -284,40 +270,38 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
z[i] = line.w[0];
#endif
-#ifdef INVERSE_W
- getSample_color ( r2, g2, b2, line.c[0][0], inversew );
-#else
- getSample_color ( r2, g2, b2, line.c[0][0] );
-#endif
- r0 = imulFix ( r0, r2 );
- g0 = imulFix ( g0, g2 );
- b0 = imulFix ( b0, b2 );
+#ifdef IPOL_C0
+
+ vec4_to_fix( r2, g2, b2, line.c[0][0], inversew );
+
+ r0 = imulFix_simple( r0, r2 );
+ g0 = imulFix_simple( g0, g2 );
+ b0 = imulFix_simple( b0, b2 );
color_to_fix ( r1, g1, b1, dst[i] );
- a0 >>= 8;
+ fix_color_norm(a0);
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
- dst[i] = fix4_to_color ( a0, r2, g2, b2 );
+ dst[i] = fix4_to_sample( a0, r2, g2, b2 );
/*
- dst[i] = PixelBlend32 ( dst[i],
- fix_to_color ( r0,g0, b0 ),
- fixPointu_to_u32 ( a0 )
- );
-*/
-/*
getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );
color_to_fix ( r1, g1, b1, dst[i] );
r2 = r0 + imulFix ( a0, r1 - r0 );
g2 = g0 + imulFix ( a0, g1 - g0 );
b2 = b0 + imulFix ( a0, b1 - b0 );
- dst[i] = fix_to_color ( r2, g2, b2 );
+ dst[i] = fix_to_sample ( r2, g2, b2 );
*/
-
+#else
+ dst[i] = PixelBlend32 ( dst[i],
+ fix_to_sample( r0,g0, b0 ),
+ fixPointu_to_u32 ( a0 )
+ );
+#endif
}
#endif
@@ -342,7 +326,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
}
-void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -353,9 +337,9 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -441,8 +425,8 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -600,8 +584,8 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -720,6 +704,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver)
{
+ //ETR_TEXTURE_GOURAUD_ALPHA
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAlpha2(driver);
#else
diff --git a/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp b/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp
index 2830247..6a55033 100644
--- a/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp
+++ b/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp
@@ -21,6 +21,7 @@
#undef INVERSE_W
#undef IPOL_C0
+#undef IPOL_C1
#undef IPOL_T0
#undef IPOL_T1
@@ -34,6 +35,7 @@
//#define WRITE_W
#define IPOL_C0
+//#define IPOL_C1
#define IPOL_T0
//#define IPOL_T1
@@ -46,10 +48,14 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
+#if BURNING_MATERIAL_MAX_COLORS < 2
+ #undef IPOL_C1
+#endif
+
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@@ -84,18 +90,34 @@ public:
CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
+
+#if defined(PATCH_SUPERTUX_8_0_1)
+ SBurningShaderMaterial Material;
- virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;
+ virtual void setMaterial(const SBurningShaderMaterial &material)
+ {
+ Material = material;
+ }
+ virtual void setParam(u32 index, f32 value)
+ {
+ OnSetMaterial(Material);
+}
+#endif
private:
- void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
+ // fragment shader
+ typedef void (CTRTextureGouraudAlphaNoZ::*tFragmentShader) ();
+ void fragment_linear();
+ void fragment_linear_test();
+ void fragment_point_noz();
+
+ tFragmentShader fragmentShader;
+
- u32 AlphaRef;
};
//! constructor
@@ -106,24 +128,37 @@ CTRTextureGouraudAlphaNoZ::CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver
setDebugName("CTRTextureGouraudAlphaNoZ");
#endif
- AlphaRef = 0;
+ fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;
}
/*!
*/
-void CTRTextureGouraudAlphaNoZ::setParam ( u32 index, f32 value)
+void CTRTextureGouraudAlphaNoZ::OnSetMaterial(const SBurningShaderMaterial& material)
{
-#ifdef BURNINGVIDEO_RENDERER_FAST
- AlphaRef = core::floor32_fast( value * 256.f );
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+ AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);
#else
- AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) );
+ AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
#endif
+
+ //check triangle on w = 1.f instead..
+#ifdef SOFTWARE_DRIVER_2_BILINEAR
+ if (material.Fallback_MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
+ fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear_test;
+ else
+ if ( material.org.TextureLayer[0].BilinearFilter )
+ fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;
+ else
+
+#endif
+ fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_point_noz;
+
}
/*!
*/
-void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
+void CTRTextureGouraudAlphaNoZ::fragment_linear()
{
tVideoSample *dst;
@@ -147,15 +182,15 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC[MATERIAL_MAX_COLORS];
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -163,7 +198,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -174,6 +209,9 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
+#ifdef IPOL_C1
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
+#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
@@ -192,6 +230,9 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1] * subPixel;
+#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
@@ -200,6 +241,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -209,7 +251,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
f32 inversew = FIX_POINT_F32_MUL;
-#ifdef BURNINGVIDEO_RENDERER_FAST
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = ( line.y & 3 ) << 2;
#else
@@ -219,7 +261,11 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
- tFixPoint r2, g2, b2;
+ tFixPoint a2,r2, g2, b2;
+#endif
+
+#ifdef IPOL_C1
+ tFixPoint a3,r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; ++i )
@@ -233,7 +279,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
{
-#ifdef BURNINGVIDEO_RENDERER_FAST
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
@@ -244,7 +290,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
d + tofix ( line.t[0][0].y,inversew)
);
- const u32 alpha = ( argb >> 24 );
+ const tFixPoint alpha = ( argb >> 24 );
if ( alpha > AlphaRef )
{
#ifdef WRITE_Z
@@ -262,19 +308,14 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
+#endif
getSample_texture ( a0, r0, g0, b0,
&IT[0],
tofix ( line.t[0][0].x,inversew),
tofix ( line.t[0][0].y,inversew)
);
-#else
- getSample_texture ( a0, r0, g0,b0,
- &IT[0],
- tofix ( line.t[0][0].x),
- tofix ( line.t[0][0].y)
- );
-#endif
- if ( (tFixPointu) a0 > AlphaRef )
+
+ if ( a0 > AlphaRef )
{
#ifdef WRITE_Z
z[i] = line.z[0];
@@ -283,39 +324,30 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
z[i] = line.w[0];
#endif
-#ifdef INVERSE_W
- getSample_color ( r2, g2, b2, line.c[0][0], inversew );
-#else
- getSample_color ( r2, g2, b2, line.c[0][0] );
-#endif
- r0 = imulFix ( r0, r2 );
- g0 = imulFix ( g0, g2 );
- b0 = imulFix ( b0, b2 );
+#ifdef IPOL_C0
+
+ vec4_to_fix( a2,r2, g2, b2, line.c[0][0], inversew );
+
+ //a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha
+ r0 = imulFix_simple( r0, r2 );
+ g0 = imulFix_simple( g0, g2 );
+ b0 = imulFix_simple( b0, b2 );
color_to_fix ( r1, g1, b1, dst[i] );
- a0 >>= 8;
+ fix_color_norm(a0);
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
- dst[i] = fix4_to_color ( a0, r2, g2, b2 );
+ dst[i] = fix4_to_sample( a0, r2, g2, b2 );
-/*
+#else
dst[i] = PixelBlend32 ( dst[i],
- fix_to_color ( r0,g0, b0 ),
+ fix_to_sample( r0,g0, b0 ),
fixPointu_to_u32 ( a0 )
);
-*/
-/*
- getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );
- color_to_fix ( r1, g1, b1, dst[i] );
-
- r2 = r0 + imulFix ( a0, r1 - r0 );
- g2 = g0 + imulFix ( a0, g1 - g0 );
- b2 = b0 + imulFix ( a0, b1 - b0 );
- dst[i] = fix_to_color ( r2, g2, b2 );
-*/
+#endif
}
#endif
@@ -331,6 +363,229 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1];
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0];
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1];
+#endif
+ }
+
+}
+
+/*!
+*/
+void CTRTextureGouraudAlphaNoZ::fragment_linear_test()
+{
+ tVideoSample *dst;
+
+#ifdef USE_ZBUFFER
+ fp24 *z;
+#endif
+
+ s32 xStart;
+ s32 xEnd;
+ s32 dx;
+
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+#ifdef IPOL_Z
+ f32 slopeZ;
+#endif
+#ifdef IPOL_W
+ fp24 slopeW;
+#endif
+#ifdef IPOL_C0
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
+#endif
+#ifdef IPOL_T0
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
+#endif
+
+ // apply top-left fill-convention, left
+ xStart = fill_convention_left(line.x[0]);
+ xEnd = fill_convention_right(line.x[1]);
+
+ dx = xEnd - xStart;
+
+ if (dx < 0)
+ return;
+
+ // slopes
+ const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);
+
+#ifdef IPOL_Z
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
+#endif
+#ifdef IPOL_W
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;
+#endif
+#ifdef IPOL_C0
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_C1
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T0
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T1
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
+#endif
+
+#ifdef SUBTEXEL
+ subPixel = ((f32)xStart) - line.x[0];
+#ifdef IPOL_Z
+ line.z[0] += slopeZ * subPixel;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW * subPixel;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC[0] * subPixel;
+#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1] * subPixel;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0] * subPixel;
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1] * subPixel;
+#endif
+#endif
+
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
+
+#ifdef USE_ZBUFFER
+ z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
+#endif
+
+
+ f32 inversew = FIX_POINT_F32_MUL;
+
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+ u32 dIndex = (line.y & 3) << 2;
+
+#else
+ tFixPoint a0;
+ tFixPoint r0, g0, b0;
+#endif
+
+#ifdef IPOL_C0
+ tFixPoint r1, g1, b1;
+ tFixPoint a2, r2, g2, b2;
+#endif
+
+#ifdef IPOL_C1
+ tFixPoint a3, r3, g3, b3;
+#endif
+
+ for (s32 i = 0; i <= dx; ++i)
+ {
+#ifdef CMP_Z
+ if (line.z[0] < z[i])
+#endif
+#ifdef CMP_W
+ if (line.w[0] >= z[i])
+#endif
+
+ {
+
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+
+ const tFixPointu d = dithermask[dIndex | (i) & 3];
+
+#ifdef INVERSE_W
+ inversew = fix_inverse32(line.w[0]);
+#endif
+ u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),
+ d + tofix(line.t[0][0].y, inversew)
+ );
+
+ const tFixPoint alpha = (argb >> 24);
+ if (alpha > AlphaRef)
+ {
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ z[i] = line.w[0];
+#endif
+
+ dst[i] = PixelBlend32(dst[i], argb, alpha);
+ }
+
+
+#else
+
+#ifdef INVERSE_W
+ inversew = fix_inverse32(line.w[0]);
+#endif
+ getSample_texture(a0, r0, g0, b0,
+ &IT[0],
+ tofix(line.t[0][0].x, inversew),
+ tofix(line.t[0][0].y, inversew)
+ );
+
+ if (a0 > AlphaRef)
+ {
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ z[i] = line.w[0];
+#endif
+
+#ifdef IPOL_C0
+
+ vec4_to_fix(a2, r2, g2, b2, line.c[0][0], inversew);
+
+ a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha
+ r0 = imulFix(r0, r2);
+ g0 = imulFix(g0, g2);
+ b0 = imulFix(b0, b2);
+
+ color_to_fix(r1, g1, b1, dst[i]);
+
+ fix_color_norm(a0);
+
+ r2 = r1 + imulFix(a0, r0 - r1);
+ g2 = g1 + imulFix(a0, g0 - g1);
+ b2 = b1 + imulFix(a0, b0 - b1);
+ dst[i] = fix4_to_sample(a0, r2, g2, b2);
+
+#else
+ dst[i] = PixelBlend32(dst[i],
+ fix_to_sample(r0, g0, b0),
+ fixPointu_to_u32(a0)
+ );
+#endif
+
+ }
+#endif
+
+ }
+
+#ifdef IPOL_Z
+ line.z[0] += slopeZ;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC[0];
+#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1];
+#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
@@ -341,7 +596,227 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
}
-void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+
+/*!
+*/
+void CTRTextureGouraudAlphaNoZ::fragment_point_noz()
+{
+ tVideoSample *dst;
+
+#ifdef USE_ZBUFFER
+ //fp24 *z;
+#endif
+
+ s32 xStart;
+ s32 xEnd;
+ s32 dx;
+
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+#ifdef IPOL_Z
+ f32 slopeZ;
+#endif
+#ifdef IPOL_W
+ fp24 slopeW;
+#endif
+#ifdef IPOL_C0
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
+#endif
+#ifdef IPOL_T0
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
+#endif
+
+ // apply top-left fill-convention, left
+ xStart = fill_convention_left(line.x[0]);
+ xEnd = fill_convention_right(line.x[1]);
+
+ dx = xEnd - xStart;
+
+ if (dx < 0)
+ return;
+
+ // slopes
+ const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);
+
+#ifdef IPOL_Z
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
+#endif
+#ifdef IPOL_W
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;
+#endif
+#ifdef IPOL_C0
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_C1
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T0
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T1
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
+#endif
+
+#ifdef SUBTEXEL
+ subPixel = ((f32)xStart) - line.x[0];
+#ifdef IPOL_Z
+ line.z[0] += slopeZ * subPixel;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW * subPixel;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC[0] * subPixel;
+#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1] * subPixel;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0] * subPixel;
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1] * subPixel;
+#endif
+#endif
+
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
+
+#ifdef USE_ZBUFFER
+ //z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
+#endif
+
+
+ f32 inversew = FIX_POINT_F32_MUL;
+
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+ u32 dIndex = (line.y & 3) << 2;
+
+#else
+ tFixPoint a0;
+ tFixPoint r0, g0, b0;
+#endif
+
+#ifdef IPOL_C0
+ tFixPoint r1, g1, b1;
+ tFixPoint a2,r2, g2, b2;
+#endif
+
+#ifdef IPOL_C1
+ tFixPoint a3, r3, g3, b3;
+#endif
+ for (s32 i = 0; i <= dx; ++i)
+ {
+#ifdef CMP_Z
+ if (line.z[0] < z[i])
+#endif
+#ifdef CMP_W
+// if (line.w[0] >= z[i])
+#endif
+
+ {
+
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+
+ const tFixPointu d = dithermask[dIndex | (i) & 3];
+
+#ifdef INVERSE_W
+ inversew = fix_inverse32(line.w[0]);
+#endif
+ u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),
+ d + tofix(line.t[0][0].y, inversew)
+ );
+
+ const tFixPoint alpha = (argb >> 24);
+ if (alpha > AlphaRef)
+ {
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ z[i] = line.w[0];
+#endif
+
+ dst[i] = PixelBlend32(dst[i], argb, alpha);
+ }
+
+
+#else
+
+#ifdef INVERSE_W
+ //inversew = fix_inverse32(line.w[0]);
+#endif
+ getTexel_fix(a0, r0, g0, b0,
+ &IT[0],
+ tofix(line.t[0][0].x, inversew),
+ tofix(line.t[0][0].y, inversew)
+ );
+
+ if (a0 > AlphaRef)
+ {
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ //z[i] = line.w[0];
+#endif
+
+#ifdef IPOL_C0
+
+ vec4_to_fix(a2,r2, g2, b2, line.c[0][0], inversew);
+
+ a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha
+ r0 = imulFix(r0, r2);
+ g0 = imulFix(g0, g2);
+ b0 = imulFix(b0, b2);
+
+ color_to_fix(r1, g1, b1, dst[i]);
+
+ fix_color_norm(a0);
+
+ r2 = r1 + imulFix(a0, r0 - r1);
+ g2 = g1 + imulFix(a0, g0 - g1);
+ b2 = b1 + imulFix(a0, b0 - b1);
+ dst[i] = fix4_to_sample(a0, r2, g2, b2);
+
+#else
+ dst[i] = PixelBlend32(dst[i],
+ fix_to_sample(r0, g0, b0),
+ fixPointu_to_u32(a0)
+ );
+#endif
+
+ }
+#endif
+
+ }
+
+#ifdef IPOL_Z
+ line.z[0] += slopeZ;
+#endif
+#ifdef IPOL_W
+ //line.w[0] += slopeW;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC[0];
+#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1];
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0];
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1];
+#endif
+ }
+
+}
+
+void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -352,9 +827,9 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -389,6 +864,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][0] = a->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
+ scan.c[1][0] = a->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@@ -429,6 +909,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] = a->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
+ scan.c[1][1] = a->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@@ -440,8 +925,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -465,6 +950,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@@ -498,6 +988,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
line.c[0][scan.right] = scan.c[0][1];
#endif
+#ifdef IPOL_C1
+ line.c[1][scan.left] = scan.c[1][0];
+ line.c[1][scan.right] = scan.c[1][1];
+#endif
+
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@@ -509,7 +1004,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#endif
// render a scanline
- scanline_bilinear ( );
+ (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -529,6 +1024,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] += scan.slopeC[0][1];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0];
+ scan.c[1][1] += scan.slopeC[1][1];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@@ -560,6 +1060,10 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@@ -588,6 +1092,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] = b->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
+ scan.c[1][1] = b->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@@ -599,8 +1108,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -625,6 +1134,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@@ -658,6 +1172,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
line.c[0][scan.right] = scan.c[0][1];
#endif
+#ifdef IPOL_C1
+ line.c[1][scan.left] = scan.c[1][0];
+ line.c[1][scan.right] = scan.c[1][1];
+#endif
+
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@@ -669,7 +1188,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#endif
// render a scanline
- scanline_bilinear ( );
+ (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@@ -689,6 +1208,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] += scan.slopeC[0][1];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0];
+ scan.c[1][1] += scan.slopeC[1][1];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@@ -720,6 +1244,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
{
+ // ETR_TEXTURE_GOURAUD_ALPHA_NOZ
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAlphaNoZ(driver);
#else
@@ -728,6 +1253,7 @@ IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
}
+
} // end namespace video
} // end namespace irr
diff --git a/source/Irrlicht/CTRTextureGouraudNoZ2.cpp b/source/Irrlicht/CTRTextureGouraudNoZ2.cpp
index 6abc6e1..c2b4625 100644
--- a/source/Irrlicht/CTRTextureGouraudNoZ2.cpp
+++ b/source/Irrlicht/CTRTextureGouraudNoZ2.cpp
@@ -42,7 +42,7 @@
#define IPOL_T0
//#define IPOL_T1
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -88,13 +88,11 @@ public:
CTRTextureGouraudNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
};
@@ -142,8 +140,8 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -151,7 +149,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -188,6 +186,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -199,7 +198,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
tFixPoint tx0;
tFixPoint ty0;
-
+ tFixPoint r0, g0, b0;
for ( s32 i = 0; i <= dx; ++i )
{
@@ -216,12 +215,12 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#endif
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
- dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );
+ //skybox
+ //dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );
+
+ getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 );
+ dst[i] = fix_to_sample( r0, g0, b0 );
-/*
- getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
- dst[i] = fix_to_color ( r0, g0, b0 );
-*/
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
@@ -249,7 +248,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
}
-void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -260,9 +259,9 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -348,8 +347,8 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -507,8 +506,8 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -626,6 +625,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver)
{
+ // ETR_TEXTURE_GOURAUD_NOZ
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudNoZ2( driver );
#else
diff --git a/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp b/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp
index 8da8e87..4b9c4c2 100644
--- a/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp
+++ b/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp
@@ -21,6 +21,7 @@
#undef INVERSE_W
#undef IPOL_C0
+#undef IPOL_C1
#undef IPOL_T0
#undef IPOL_T1
@@ -34,6 +35,7 @@
//#define WRITE_W
#define IPOL_C0
+#define IPOL_C1
#define IPOL_T0
//#define IPOL_T1
@@ -46,10 +48,15 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
+#if BURNING_MATERIAL_MAX_COLORS < 2
+ #undef IPOL_C1
+#endif
+
+
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@@ -82,13 +89,11 @@ public:
CTRTextureVertexAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
};
@@ -129,15 +134,15 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
fp24 slopeW;
#endif
#ifdef IPOL_C0
- sVec4 slopeC;
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -145,7 +150,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -154,7 +159,10 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
- slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_C1
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@@ -172,8 +180,12 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
- line.c[0][0] += slopeC * subPixel;
+ line.c[0][0] += slopeC[0] * subPixel;
#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1] * subPixel;
+#endif
+
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
@@ -182,6 +194,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -191,22 +204,18 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
f32 inversew = FIX_POINT_F32_MUL;
-//#define __TEST_THIS
-
-#ifdef __TEST_THIS
-
-#else
tFixPoint tx0;
tFixPoint ty0;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
- tFixPoint r2, g2, b2;
-#endif
-
#ifdef IPOL_C0
- tFixPoint a3;
+ tFixPoint a2,r2, g2, b2;
+#endif
+
+#ifdef IPOL_C1
+ tFixPoint aFog = FIX_POINT_ONE;
#endif
@@ -220,50 +229,74 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
#endif
{
-#ifdef __TEST_THIS
-
- inversew = fix_inverse32 ( line.w[0] );
-
- dst[i] = PixelAdd32 (
- dst[i],
- getTexel_plain ( &IT[0], tofix ( line.t[0][0].x,inversew),
- tofix ( line.t[0][0].y,inversew) )
- );
-
-#else
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ z[i] = line.w[0];
+#endif
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
+#ifdef IPOL_C1
+ //complete inside fog
+ if (TL_Flag & TL_FOG)
+ {
+ aFog = tofix(line.c[1][0].a, inversew);
+ if (aFog <= 0)
+ {
+ dst[i] = fog_color_sample;
+ continue;
+ }
+ }
+#endif
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
-#ifdef IPOL_C0
- a3 = tofix ( line.c[0][0].y,inversew );
-#endif
-
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
color_to_fix ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
- r2 = clampfix_maxcolor ( r1 + imulFix ( r0, a3 ) );
- g2 = clampfix_maxcolor ( g1 + imulFix ( g0, a3 ) );
- b2 = clampfix_maxcolor ( b1 + imulFix ( b0, a3 ) );
+ vec4_to_fix(a2,r2, g2, b2, line.c[0][0], inversew);
+
+ r0 = imulFix_simple(r0, r2);
+ g0 = imulFix_simple(g0, g2);
+ b0 = imulFix_simple(b0, b2);
+
+#ifdef IPOL_C1
+ //specular highlight
+ if (TL_Flag & TL_SPECULAR)
+ {
+ vec4_to_fix(r2, g2, b2, line.c[1][0], inversew*COLOR_MAX);
+ r0 = clampfix_maxcolor(r2 + r0);
+ g0 = clampfix_maxcolor(g2 + g0);
+ b0 = clampfix_maxcolor(b2 + b0);
+ }
+#endif
+ //blend background
+ r0 = r1 + imulFix(a2, r0 - r1);
+ g0 = g1 + imulFix(a2, g0 - g1);
+ b0 = b1 + imulFix(a2, b0 - b1);
+
+#ifdef IPOL_C1
+ //mix with distance
+ if (aFog < FIX_POINT_ONE) //TL_Flag & TL_FOG)
+ {
+ r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);
+ g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);
+ b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);
+ }
+#endif
+
#else
- r2 = clampfix_maxcolor ( r1 + r0 );
- g2 = clampfix_maxcolor ( g1 + g0 );
- b2 = clampfix_maxcolor ( b1 + b0 );
+ r0 = clampfix_maxcolor ( r1 + r0 );
+ g0 = clampfix_maxcolor ( g1 + g0 );
+ b0 = clampfix_maxcolor ( b1 + b0 );
#endif
- dst[i] = fix_to_color ( r2, g2, b2 );
+ dst[i] = fix_to_sample( r0, g0, b0 );
-#ifdef WRITE_Z
- z[i] = line.z[0];
-#endif
-#ifdef WRITE_W
- z[i] = line.w[0];
-#endif
-#endif
}
#ifdef IPOL_Z
@@ -273,7 +306,10 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
- line.c[0][0] += slopeC;
+ line.c[0][0] += slopeC[0];
+#endif
+#ifdef IPOL_C1
+ line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
@@ -285,7 +321,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
}
-void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -296,9 +332,9 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -333,6 +369,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][0] = a->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
+ scan.c[1][0] = a->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@@ -373,6 +414,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] = a->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
+ scan.c[1][1] = a->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@@ -384,8 +430,8 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -409,6 +455,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@@ -442,6 +493,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
line.c[0][scan.right] = scan.c[0][1];
#endif
+#ifdef IPOL_C1
+ line.c[1][scan.left] = scan.c[1][0];
+ line.c[1][scan.right] = scan.c[1][1];
+#endif
+
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@@ -473,6 +529,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] += scan.slopeC[0][1];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0];
+ scan.c[1][1] += scan.slopeC[1][1];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@@ -504,6 +565,9 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
+#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@@ -532,6 +596,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] = b->Color[0];
#endif
+#ifdef IPOL_C1
+ scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
+ scan.c[1][1] = b->Color[1];
+#endif
+
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@@ -543,8 +612,8 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -569,6 +638,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@@ -602,6 +676,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
line.c[0][scan.right] = scan.c[0][1];
#endif
+#ifdef IPOL_C1
+ line.c[1][scan.left] = scan.c[1][0];
+ line.c[1][scan.right] = scan.c[1][1];
+#endif
+
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@@ -633,6 +712,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] += scan.slopeC[0][1];
#endif
+#ifdef IPOL_C1
+ scan.c[1][0] += scan.slopeC[1][0];
+ scan.c[1][1] += scan.slopeC[1][1];
+#endif
+
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@@ -662,6 +746,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver)
{
+ /* ETR_TEXTURE_GOURAUD_VERTEX_ALPHA */
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureVertexAlpha2(driver);
#else
diff --git a/source/Irrlicht/CTRTextureLightMap2_Add.cpp b/source/Irrlicht/CTRTextureLightMap2_Add.cpp
index db49d53..d5cc7e3 100644
--- a/source/Irrlicht/CTRTextureLightMap2_Add.cpp
+++ b/source/Irrlicht/CTRTextureLightMap2_Add.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -82,15 +82,12 @@ public:
CTRTextureLightMap2_Add(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
-
};
//! constructor
@@ -137,8 +134,8 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -146,7 +143,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -183,6 +180,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -190,11 +188,10 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
#endif
-#ifdef BURNINGVIDEO_RENDERER_FAST
f32 inversew = FIX_POINT_F32_MUL;
- u32 dIndex = ( line.y & 3 ) << 2;
-
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+ u32 dIndex = ( line.y & 3 ) << 2;
#else
//
tFixPoint r0, g0, b0;
@@ -219,11 +216,12 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
z[i] = line.w[0];
#endif
-#ifdef BURNINGVIDEO_RENDERER_FAST
-
#ifdef INVERSE_W
- inversew = fix_inverse32 ( line.w[0] );
+ inversew = fix_inverse32(line.w[0]);
#endif
+
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
+
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
dst[i] = PixelAdd32 (
@@ -234,12 +232,11 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
);
#else
- const f32 inversew = fix_inverse32 ( line.w[0] );
getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[0][1].x,inversew), tofix ( line.t[0][1].y,inversew) );
- dst[i] = fix_to_color ( clampfix_maxcolor ( r0 + r1 ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( r0 + r1 ),
clampfix_maxcolor ( g0 + g1 ),
clampfix_maxcolor ( b0 + b1 )
);
@@ -266,7 +263,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
}
-void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -277,9 +274,9 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -365,8 +362,8 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -524,8 +521,8 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
diff --git a/source/Irrlicht/CTRTextureLightMap2_M1.cpp b/source/Irrlicht/CTRTextureLightMap2_M1.cpp
index 7195274..1295d3c 100644
--- a/source/Irrlicht/CTRTextureLightMap2_M1.cpp
+++ b/source/Irrlicht/CTRTextureLightMap2_M1.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -82,14 +82,12 @@ public:
CTRTextureLightMap2_M1(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear2 ();
- sScanLineData line;
-
};
//! constructor
@@ -115,15 +113,15 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@@ -170,6 +168,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
line.z[0] = a;
line.z[1] = b;
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
a = (f32) i + subPixel;
@@ -226,7 +225,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
#endif
- dst[i] = fix_to_color ( imulFix_tex1 ( r0, r1 ),
+ dst[i] = fix_to_sample( imulFix_tex1 ( r0, r1 ),
imulFix_tex1 ( g0, g1 ),
imulFix_tex1 ( b0, b1 )
);
@@ -244,9 +243,8 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
}
-void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
- sScanConvertData scan;
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -257,9 +255,9 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -345,8 +343,8 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -505,8 +503,8 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -626,6 +624,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver)
{
+ //ETR_TEXTURE_GOURAUD_LIGHTMAP_M1
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureLightMap2_M1(driver);
#else
diff --git a/source/Irrlicht/CTRTextureLightMap2_M2.cpp b/source/Irrlicht/CTRTextureLightMap2_M2.cpp
index f748990..5976cfb 100644
--- a/source/Irrlicht/CTRTextureLightMap2_M2.cpp
+++ b/source/Irrlicht/CTRTextureLightMap2_M2.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -82,14 +82,12 @@ public:
CTRTextureLightMap2_M2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear2 ();
- sScanLineData line;
-
};
//! constructor
@@ -115,15 +113,15 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@@ -170,6 +168,7 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
line.z[0] = a;
line.z[1] = b;
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
a = (f32) i + subPixel;
@@ -226,7 +225,7 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
#endif
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
@@ -244,10 +243,8 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
}
-void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
- sScanConvertData scan;
-
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
@@ -257,9 +254,9 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -345,8 +342,8 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -505,8 +502,8 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
diff --git a/source/Irrlicht/CTRTextureLightMap2_M4.cpp b/source/Irrlicht/CTRTextureLightMap2_M4.cpp
index 3fd726c..b33a0e0 100644
--- a/source/Irrlicht/CTRTextureLightMap2_M4.cpp
+++ b/source/Irrlicht/CTRTextureLightMap2_M4.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -82,19 +82,21 @@ public:
CTRTextureLightMap2_M4(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
- void drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
- void drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
-
- void scanline_bilinear ();
+#if defined(SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)
+ void drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );
+ void drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );
void scanline_bilinear2_mag ();
void scanline_bilinear2_min ();
+#else
+ #define scanline_bilinear2_mag scanline_bilinear
+#endif
- sScanLineData line;
+ void scanline_bilinear ();
};
@@ -109,14 +111,14 @@ CTRTextureLightMap2_M4::CTRTextureLightMap2_M4(CBurningVideoDriver* driver)
/*!
*/
-REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
+void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
{
tVideoSample *dst;
fp24 *z;
// apply top-left fill-convention, left
- const s32 xStart = irr::core::ceil32_fast( line.x[0] );
- const s32 xEnd = irr::core::ceil32_fast( line.x[1] ) - 1;
+ const s32 xStart = fill_convention_left(line.x[0]);
+ const s32 xEnd = fill_convention_right(line.x[1]);
s32 dx;
s32 i;
@@ -125,8 +127,10 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
if ( dx < 0 )
return;
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
i = ( line.y * RenderTarget->getDimension().Width ) + xStart;
@@ -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) );
#endif
-
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),
- clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),
- clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )
- );
+ dst[i] = fix_to_sample(imulFix_tex4(r0, r1), imulFix_tex4(g0, g1), imulFix_tex4(b0, b1));
}
#ifdef IPOL_W
@@ -248,7 +248,8 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
}
-REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
+#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)
+void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
{
tVideoSample *dst;
fp24 *z;
@@ -260,15 +261,17 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left(line.x[0]);
+ xEnd = fill_convention_right(line.x[1]);
dx = xEnd - xStart;
if ( dx < 0 )
return;
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@@ -315,6 +318,7 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
line.z[0] = a;
line.z[1] = b;
#endif
+
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
a = (f32) i + subPixel;
@@ -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) );
getTexel_fix ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),
- clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),
- clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )
- );
+ dst[i] = fix_to_sample(imulFix_tex4(r0, r1), imulFix_tex4(g0, g1), imulFix_tex4(b0, b1));
}
#ifdef IPOL_W
@@ -369,21 +370,20 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
}
-//#ifdef BURNINGVIDEO_RENDERER_FAST
-#if 1
-
-void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
- if ( IT[0].lodLevel <= 2 )
- drawTriangle_Mag ( a, b, c );
+ if (IT[0].lodFactor < 4)
+ {
+ drawTriangle_Mag(a, b, c);
+ }
else
- drawTriangle_Min ( a, b, c );
+ {
+ drawTriangle_Min(a, b, c);
+ }
}
-void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
{
- sScanConvertData scan;
-
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
@@ -393,9 +393,9 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@@ -481,8 +481,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -641,8 +641,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -746,16 +746,15 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
}
-void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
-#else
+#else //#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)
-void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
#endif
{
- sScanConvertData scan;
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -765,14 +764,18 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
- // calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
- if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
+ if ( F32_LOWER_EQUAL_0 ( ca ) )
return;
+ // calculate delta y of the edges
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
+
+ //if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
+ // return;
+
// find if the major edge is left or right aligned
f32 temp[4];
@@ -855,8 +858,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -1015,8 +1018,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@@ -1120,6 +1123,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
}
+#undef scanline_bilinear2_mag
+
} // end namespace video
} // end namespace irr
diff --git a/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp b/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp
index 64a14ab..55e7ffc 100644
--- a/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp
+++ b/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp
@@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@@ -82,15 +82,12 @@ public:
CTRGTextureLightMap2_M4(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
- sScanConvertData scan;
- sScanLineData line;
-
};
//! constructor
@@ -137,8 +134,8 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
- xStart = core::ceil32_fast( line.x[0] );
- xEnd = core::ceil32_fast( line.x[1] ) - 1;
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@@ -146,7 +143,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
return;
// slopes
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@@ -183,6 +180,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
#endif
#endif
+ SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@@ -230,26 +228,22 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );
#ifdef IPOL_C0
- r2 = imulFix ( r0, r3 );
- g2 = imulFix ( g0, g3 );
- b2 = imulFix ( b0, b3 );
-
- r2 = clampfix_maxcolor ( imulFix_tex4 ( r2, r1 ) );
- g2 = clampfix_maxcolor ( imulFix_tex4 ( g2, g1 ) );
- b2 = clampfix_maxcolor ( imulFix_tex4 ( b2, b1 ) );
-/*
- r2 = r3 << 8;
- g2 = g3 << 8;
- b2 = b3 << 8;
-*/
+ r2 = imulFix_simple( r0, r3 );
+ g2 = imulFix_simple( g0, g3 );
+ b2 = imulFix_simple( b0, b3 );
+
+ r2 = imulFix_tex4 ( r2, r1 );
+ g2 = imulFix_tex4 ( g2, g1 );
+ b2 = imulFix_tex4 ( b2, b1 );
+
#else
- r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );
- g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );
- b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );
+ r2 = imulFix_tex4 ( r0, r1 );
+ g2 = imulFix_tex4 ( g0, g1 );
+ b2 = imulFix_tex4 ( b0, b1 );
#endif
- dst[i] = fix_to_color ( r2, g2, b2 );
+ dst[i] = fix_to_sample( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
@@ -278,7 +272,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
}
-void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@@ -289,9 +283,9 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
- scan.invDeltaY[0] = core::reciprocal( ca );
- scan.invDeltaY[1] = core::reciprocal( ba );
- scan.invDeltaY[2] = core::reciprocal( cb );
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_0 ( scan.invDeltaY[0] ) )
return;
@@ -379,8 +373,8 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( a->Pos.y );
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@@ -540,8 +534,8 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
- yStart = core::ceil32_fast( b->Pos.y );
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
diff --git a/source/Irrlicht/CTRTextureWire2.cpp b/source/Irrlicht/CTRTextureWire2.cpp
index e1bb8ba..b77b788 100644
--- a/source/Irrlicht/CTRTextureWire2.cpp
+++ b/source/Irrlicht/CTRTextureWire2.cpp
@@ -28,14 +28,14 @@
#define SUBTEXEL
#define INVERSE_W
-#define USE_ZBUFFER
+//#define USE_ZBUFFER
#define IPOL_W
-#define CMP_W
-#define WRITE_W
+//#define CMP_W
+//#define WRITE_W
-//#define IPOL_C0
-#define IPOL_T0
+#define IPOL_C0
+//#define IPOL_T0
//#define IPOL_T1
// apply global override
@@ -47,6 +47,10 @@
#undef SUBTEXEL
#endif
+#if BURNING_MATERIAL_MAX_COLORS < 1
+ #undef IPOL_C0
+#endif
+
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@@ -80,14 +84,17 @@ public:
CTRTextureWire2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) _IRR_OVERRIDE_;
+ virtual void drawPoint( const s4DVertex *a) _IRR_OVERRIDE_;
+ virtual bool canWireFrame () _IRR_OVERRIDE_ { return true; }
+ virtual bool canPointCloud() _IRR_OVERRIDE_ { return true; }
+protected:
+ virtual void scanline_bilinear ();
-
-private:
void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const;
- void renderLine ( const s4DVertex *a,const s4DVertex *b ) const;
+ void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const;
};
@@ -101,26 +108,22 @@ CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver)
}
-// swap integer with xor
-static inline void swap_xor ( s32 &a, s32 &b )
-{
- a ^= b;
- b ^= a;
- a ^= b;
-}
-
/*!
+ 2d line
*/
-void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
+void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const
{
int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY;
+#ifdef USE_ZBUFFER
int pitch1 = RenderTarget->getDimension().Width << 2;
+#endif
- int aposx = (int) a->Pos.x;
- int aposy = (int) a->Pos.y;
- int bposx = (int) b->Pos.x;
- int bposy = (int) b->Pos.y;
+ //todo:!
+ int aposx = fill_convention_none(a->Pos.x);
+ int aposy = fill_convention_none(a->Pos.y);
+ int bposx = fill_convention_none(b->Pos.x);
+ int bposy = fill_convention_none(b->Pos.y);
int dx = bposx - aposx;
int dy = bposy - aposy;
@@ -138,37 +141,39 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY;
int yInc0 = pitch0;
+#ifdef USE_ZBUFFER
int xInc1 = 4;
int yInc1 = pitch1;
-
- tVideoSample color;
-
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
- tFixPoint r0, g0, b0;
- getSample_color ( r0, g0, b0, a->Color[0] );
- color = fix_to_color ( r0, g0, b0 );
-#else
- color = (tVideoSample) 0xFFFFFFFF;
#endif
if ( dx < 0 )
{
xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY);
+#ifdef USE_ZBUFFER
xInc1 = -4;
+#endif
dx = -dx;
}
if ( dy > dx )
{
- swap_xor ( dx, dy );
- swap_xor ( xInc0, yInc0 );
- swap_xor ( xInc1, yInc1 );
+ //swap
+ register s32 t;
+ t = dx;dx=dy;dy=t;
+ t = xInc0;xInc0=yInc0;yInc0=t;
+#ifdef USE_ZBUFFER
+ t = xInc1;xInc1=yInc1;yInc1=t;
+#endif
}
- if ( 0 == dx )
- return;
+ if (0 == dx)
+ {
+ if (!renderZero) return;
+ dx = 1;
+ }
- dst = (tVideoSample*) ( (u8*) (tVideoSample*)RenderTarget->getData() + ( aposy * pitch0 ) + (aposx << VIDEO_SAMPLE_GRANULARITY ) );
+ SOFTWARE_DRIVER_2_CLIPCHECK_WIRE;
+ dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( aposy * pitch0 ) + (aposx* (1<< VIDEO_SAMPLE_GRANULARITY) ) );
#ifdef USE_ZBUFFER
z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) );
#endif
@@ -176,16 +181,43 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
c = dx << 1;
m = dy << 1;
+ // slopes
+ const f32 invDeltaX = reciprocal_zero2( (f32)dx );
+
#ifdef IPOL_Z
- f32 slopeZ = (b->Pos.z - a->Pos.z) / f32(dx);
+ f32 slopeZ = (b->Pos.z - a->Pos.z) * invDeltaX;
f32 dataZ = a->Pos.z;
#endif
#ifdef IPOL_W
- fp24 slopeW = (b->Pos.w - a->Pos.w) / f32( dx );
+ fp24 slopeW = (b->Pos.w - a->Pos.w) * invDeltaX;
fp24 dataW = a->Pos.w;
#endif
+ f32 inversew = FIX_POINT_F32_MUL;
+
+ tVideoSample color;
+#if BURNING_MATERIAL_MAX_COLORS > 0
+ tFixPoint r0, g0, b0;
+#ifdef IPOL_C0
+ sVec4 slopeC;
+ sVec4 C;
+ slopeC = (b->Color[0] - a->Color[0]) * invDeltaX;
+ C = a->Color[0];
+#endif
+
+#ifdef INVERSE_W
+ inversew = fix_inverse32_color(dataW);
+#endif
+
+ vec4_to_fix( r0, g0, b0, a->Color[0], inversew);
+ color = fix_to_sample( r0, g0, b0 );
+
+#else
+ color = (tVideoSample) 0xFFFFFFFF;
+#endif
+
+
run = dx;
while ( run )
{
@@ -203,15 +235,22 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
*z = dataW;
#endif
- *dst = color;
+#ifdef IPOL_C0
+#ifdef INVERSE_W
+ inversew = fix_inverse32_color(dataW);
+#endif
+ vec4_to_fix(r0, g0, b0, C,inversew);
+ color = fix_to_sample( r0, g0, b0 );
+#endif
+ *dst = color;
}
dst = (tVideoSample*) ( (u8*) dst + xInc0 ); // x += xInc
-#ifdef IPOL_Z
+#ifdef CMP_Z
z = (fp24*) ( (u8*) z + xInc1 );
#endif
-#ifdef IPOL_W
+#ifdef CMP_W
z = (fp24*) ( (u8*) z + xInc1 );
#endif
@@ -219,10 +258,10 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
if ( d > dx )
{
dst = (tVideoSample*) ( (u8*) dst + yInc0 ); // y += yInc
-#ifdef IPOL_Z
+#ifdef CMP_Z
z = (fp24*) ( (u8*) z + yInc1 );
#endif
-#ifdef IPOL_W
+#ifdef CMP_W
z = (fp24*) ( (u8*) z + yInc1 );
#endif
@@ -235,15 +274,21 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
#ifdef IPOL_W
dataW += slopeW;
#endif
+#ifdef IPOL_C0
+ C += slopeC;
+#endif
+
}
}
-void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+void CTRTextureWire2::scanline_bilinear()
{
- sScanLineData line;
+}
+void CTRTextureWire2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
+{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
@@ -258,14 +303,17 @@ void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b)
{
-
// query access to TexMaps
// sort on height, y
- if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
+ if (F32_A_GREATER_B(a->Pos.y,b->Pos.y )) swapVertexPointer(&a, &b);
renderLine ( a, b );
+}
+void CTRTextureWire2::drawPoint(const s4DVertex *a)
+{
+ if ( (a->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) renderLine(a, a,1);
}
@@ -283,6 +331,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver)
{
+ //ETR_TEXTURE_GOURAUD_WIRE
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureWire2(driver);
#else
diff --git a/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp b/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp
new file mode 100644
index 0000000..8fb9214
--- /dev/null
+++ b/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp
@@ -0,0 +1,729 @@
+// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#include "IrrCompileConfig.h"
+#include "IBurningShader.h"
+
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
+
+// compile flag for this file
+#undef USE_ZBUFFER
+#undef IPOL_Z
+#undef CMP_Z
+#undef WRITE_Z
+
+#undef IPOL_W
+#undef CMP_W
+#undef WRITE_W
+
+#undef SUBTEXEL
+#undef INVERSE_W
+
+#undef IPOL_C0
+#undef IPOL_T0
+#undef IPOL_T1
+
+// define render case
+#define SUBTEXEL
+#define INVERSE_W
+
+#define USE_ZBUFFER
+#define IPOL_W
+#define CMP_W
+#define WRITE_W
+
+#define IPOL_C0
+#define IPOL_T0
+#define IPOL_T1
+
+// apply global override
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+ #undef INVERSE_W
+#endif
+
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
+ #undef SUBTEXEL
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS < 1
+ #undef IPOL_C0
+#endif
+
+#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
+ #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+ #undef IPOL_W
+ #endif
+ #define IPOL_Z
+
+ #ifdef CMP_W
+ #undef CMP_W
+ #define CMP_Z
+ #endif
+
+ #ifdef WRITE_W
+ #undef WRITE_W
+ #define WRITE_Z
+ #endif
+
+#endif
+
+namespace irr
+{
+
+namespace video
+{
+
+class CTR_transparent_reflection_2_layer : public IBurningShader
+{
+public:
+
+ //! constructor
+ CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver);
+
+ //! draws an indexed triangle list
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
+
+private:
+ void fragmentShader();
+
+ E_MATERIAL_TYPE MaterialType;
+
+};
+
+//! constructor
+CTR_transparent_reflection_2_layer::CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver)
+: IBurningShader(driver)
+{
+ #ifdef _DEBUG
+ setDebugName("CTR_transparent_reflection_2_layer");
+ #endif
+}
+
+void CTR_transparent_reflection_2_layer::OnSetMaterial(const SBurningShaderMaterial& material)
+{
+ MaterialType = material.org.MaterialType;
+
+}
+
+/*!
+*/
+void CTR_transparent_reflection_2_layer::fragmentShader()
+{
+ tVideoSample *dst;
+
+#ifdef USE_ZBUFFER
+ fp24 *z;
+#endif
+
+ s32 xStart;
+ s32 xEnd;
+ s32 dx;
+
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+#ifdef IPOL_Z
+ f32 slopeZ;
+#endif
+#ifdef IPOL_W
+ fp24 slopeW;
+#endif
+#ifdef IPOL_C0
+ sVec4 slopeC;
+#endif
+#ifdef IPOL_T0
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
+#endif
+
+ // apply top-left fill-convention, left
+ xStart = fill_convention_left( line.x[0] );
+ xEnd = fill_convention_right( line.x[1] );
+
+ dx = xEnd - xStart;
+
+ if ( dx < 0 )
+ return;
+
+ // slopes
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
+
+#ifdef IPOL_Z
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
+#endif
+#ifdef IPOL_W
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;
+#endif
+#ifdef IPOL_C0
+ slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T0
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T1
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
+#endif
+
+#ifdef SUBTEXEL
+ subPixel = ( (f32) xStart ) - line.x[0];
+#ifdef IPOL_Z
+ line.z[0] += slopeZ * subPixel;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW * subPixel;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC * subPixel;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0] * subPixel;
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1] * subPixel;
+#endif
+#endif
+
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+ dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
+
+#ifdef USE_ZBUFFER
+ z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
+#endif
+
+
+ f32 inversew = FIX_POINT_F32_MUL;
+
+ tFixPoint r0, g0, b0;
+ tFixPoint r1, g1, b1;
+
+#ifdef IPOL_C0
+ tFixPoint a1;
+#endif
+
+ switch(MaterialType) {
+ default:
+ case EMT_REFLECTION_2_LAYER:
+ for (s32 i = 0; i <= dx; ++i)
+ {
+#ifdef CMP_Z
+ if (line.z[0] < z[i])
+#endif
+#ifdef CMP_W
+ if (line.w[0] >= z[i])
+#endif
+ {
+
+#ifdef INVERSE_W
+ inversew = fix_inverse32(line.w[0]);
+#endif
+
+ getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));
+ getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));
+
+ r0 = imulFix_tex1(r0, r1);
+ g0 = imulFix_tex1(g0, g1);
+ b0 = imulFix_tex1(b0, b1);
+
+#ifdef IPOL_C0
+ vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);
+ r0 = imulFix_simple(r1, r0);
+ g0 = imulFix_simple(g1, g0);
+ b0 = imulFix_simple(b1, b0);
+#endif
+
+ dst[i] = fix_to_sample(r0, g0, b0);
+
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ z[i] = line.w[0];
+#endif
+ }
+
+#ifdef IPOL_Z
+ line.z[0] += slopeZ;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0];
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1];
+#endif
+ }
+ break;
+
+ case EMT_TRANSPARENT_REFLECTION_2_LAYER:
+ for (s32 i = 0; i <= dx; ++i)
+ {
+#ifdef CMP_Z
+ if (line.z[0] < z[i])
+#endif
+#ifdef CMP_W
+ if (line.w[0] >= z[i])
+#endif
+ {
+
+#ifdef INVERSE_W
+ inversew = fix_inverse32(line.w[0]);
+#endif
+
+ getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));
+ getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));
+
+ r0 = imulFix_tex1(r0, r1);
+ g0 = imulFix_tex1(g0, g1);
+ b0 = imulFix_tex1(b0, b1);
+
+#ifdef IPOL_C0
+ vec4_to_fix(a1, r1, g1, b1, line.c[0][0], inversew);
+ r0 = imulFix_simple(r1, r0);
+ g0 = imulFix_simple(g1, g0);
+ b0 = imulFix_simple(b1, b0);
+
+ //vertex alpha blend EMT_TRANSPARENT_REFLECTION_2_LAYER
+ if (a1 + 2 < FIX_POINT_ONE)
+ {
+ color_to_fix(r1, g1, b1, dst[i]);
+ r0 = r1 + imulFix(a1, r0 - r1);
+ g0 = g1 + imulFix(a1, g0 - g1);
+ b0 = b1 + imulFix(a1, b0 - b1);
+ }
+#endif
+
+ dst[i] = fix_to_sample(r0, g0, b0);
+
+#ifdef WRITE_Z
+ //z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ //z[i] = line.w[0];
+#endif
+ }
+
+#ifdef IPOL_Z
+ line.z[0] += slopeZ;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0];
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1];
+#endif
+ }
+ break;
+
+ }
+
+
+}
+
+void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
+{
+ // sort on height, y
+ if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
+ if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
+ if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
+
+ const f32 ca = c->Pos.y - a->Pos.y;
+ const f32 ba = b->Pos.y - a->Pos.y;
+ const f32 cb = c->Pos.y - b->Pos.y;
+ // calculate delta y of the edges
+ scan.invDeltaY[0] = reciprocal_zero( ca );
+ scan.invDeltaY[1] = reciprocal_zero( ba );
+ scan.invDeltaY[2] = reciprocal_zero( cb );
+
+ if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
+ return;
+
+ // find if the major edge is left or right aligned
+ f32 temp[4];
+
+ temp[0] = a->Pos.x - c->Pos.x;
+ temp[1] = -ca;
+ temp[2] = b->Pos.x - a->Pos.x;
+ temp[3] = ba;
+
+ scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
+ scan.right = 1 - scan.left;
+
+ // calculate slopes for the major edge
+ scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
+ scan.x[0] = a->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
+ scan.z[0] = a->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
+ scan.w[0] = a->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
+ scan.c[0][0] = a->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
+ scan.t[0][0] = a->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
+ scan.t[1][0] = a->Tex[1];
+#endif
+
+ // top left fill convention y run
+ s32 yStart;
+ s32 yEnd;
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+ // rasterize upper sub-triangle
+ if ( F32_GREATER_0(scan.invDeltaY[1]) )
+ {
+ // calculate slopes for top edge
+ scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
+ scan.x[1] = a->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
+ scan.z[1] = a->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
+ scan.w[1] = a->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
+ scan.c[0][1] = a->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
+ scan.t[0][1] = a->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
+ scan.t[1][1] = a->Tex[1];
+#endif
+
+ // apply top-left fill convention, top part
+ yStart = fill_convention_left( a->Pos.y );
+ yEnd = fill_convention_right( b->Pos.y );
+
+#ifdef SUBTEXEL
+ subPixel = ( (f32) yStart ) - a->Pos.y;
+
+ // correct to pixel center
+ scan.x[0] += scan.slopeX[0] * subPixel;
+ scan.x[1] += scan.slopeX[1] * subPixel;
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0] * subPixel;
+ scan.z[1] += scan.slopeZ[1] * subPixel;
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0] * subPixel;
+ scan.w[1] += scan.slopeW[1] * subPixel;
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;
+#endif
+
+#endif
+
+ // rasterize the edge scanlines
+ for( line.y = yStart; line.y <= yEnd; ++line.y)
+ {
+ line.x[scan.left] = scan.x[0];
+ line.x[scan.right] = scan.x[1];
+
+#ifdef IPOL_Z
+ line.z[scan.left] = scan.z[0];
+ line.z[scan.right] = scan.z[1];
+#endif
+
+#ifdef IPOL_W
+ line.w[scan.left] = scan.w[0];
+ line.w[scan.right] = scan.w[1];
+#endif
+
+#ifdef IPOL_C0
+ line.c[0][scan.left] = scan.c[0][0];
+ line.c[0][scan.right] = scan.c[0][1];
+#endif
+
+#ifdef IPOL_T0
+ line.t[0][scan.left] = scan.t[0][0];
+ line.t[0][scan.right] = scan.t[0][1];
+#endif
+
+#ifdef IPOL_T1
+ line.t[1][scan.left] = scan.t[1][0];
+ line.t[1][scan.right] = scan.t[1][1];
+#endif
+
+ // render a scanline
+ fragmentShader();
+
+ scan.x[0] += scan.slopeX[0];
+ scan.x[1] += scan.slopeX[1];
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0];
+ scan.z[1] += scan.slopeZ[1];
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0];
+ scan.w[1] += scan.slopeW[1];
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0];
+ scan.c[0][1] += scan.slopeC[0][1];
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0];
+ scan.t[0][1] += scan.slopeT[0][1];
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0];
+ scan.t[1][1] += scan.slopeT[1][1];
+#endif
+
+ }
+ }
+
+ // rasterize lower sub-triangle
+ if ( F32_GREATER_0(scan.invDeltaY[2]) )
+ {
+ // advance to middle point
+ if( F32_GREATER_0(scan.invDeltaY[1]) )
+ {
+ temp[0] = b->Pos.y - a->Pos.y; // dy
+
+ scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
+#ifdef IPOL_Z
+ scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
+#endif
+#ifdef IPOL_W
+ scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
+#endif
+#ifdef IPOL_C0
+ scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
+#endif
+#ifdef IPOL_T0
+ scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
+#endif
+#ifdef IPOL_T1
+ scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
+#endif
+
+ }
+
+ // calculate slopes for bottom edge
+ scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
+ scan.x[1] = b->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
+ scan.z[1] = b->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
+ scan.w[1] = b->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
+ scan.c[0][1] = b->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
+ scan.t[0][1] = b->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
+ scan.t[1][1] = b->Tex[1];
+#endif
+
+ // apply top-left fill convention, top part
+ yStart = fill_convention_left( b->Pos.y );
+ yEnd = fill_convention_right( c->Pos.y );
+
+#ifdef SUBTEXEL
+
+ subPixel = ( (f32) yStart ) - b->Pos.y;
+
+ // correct to pixel center
+ scan.x[0] += scan.slopeX[0] * subPixel;
+ scan.x[1] += scan.slopeX[1] * subPixel;
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0] * subPixel;
+ scan.z[1] += scan.slopeZ[1] * subPixel;
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0] * subPixel;
+ scan.w[1] += scan.slopeW[1] * subPixel;
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;
+#endif
+
+#endif
+
+ // rasterize the edge scanlines
+ for( line.y = yStart; line.y <= yEnd; ++line.y)
+ {
+ line.x[scan.left] = scan.x[0];
+ line.x[scan.right] = scan.x[1];
+
+#ifdef IPOL_Z
+ line.z[scan.left] = scan.z[0];
+ line.z[scan.right] = scan.z[1];
+#endif
+
+#ifdef IPOL_W
+ line.w[scan.left] = scan.w[0];
+ line.w[scan.right] = scan.w[1];
+#endif
+
+#ifdef IPOL_C0
+ line.c[0][scan.left] = scan.c[0][0];
+ line.c[0][scan.right] = scan.c[0][1];
+#endif
+
+#ifdef IPOL_T0
+ line.t[0][scan.left] = scan.t[0][0];
+ line.t[0][scan.right] = scan.t[0][1];
+#endif
+
+#ifdef IPOL_T1
+ line.t[1][scan.left] = scan.t[1][0];
+ line.t[1][scan.right] = scan.t[1][1];
+#endif
+
+ // render a scanline
+ fragmentShader();
+
+ scan.x[0] += scan.slopeX[0];
+ scan.x[1] += scan.slopeX[1];
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0];
+ scan.z[1] += scan.slopeZ[1];
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0];
+ scan.w[1] += scan.slopeW[1];
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0];
+ scan.c[0][1] += scan.slopeC[0][1];
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0];
+ scan.t[0][1] += scan.slopeT[0][1];
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0];
+ scan.t[1][1] += scan.slopeT[1][1];
+#endif
+
+ }
+ }
+
+}
+
+
+} // end namespace video
+} // end namespace irr
+
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
+
+namespace irr
+{
+namespace video
+{
+
+//! creates a flat triangle renderer
+IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver)
+{
+ /*
+ ETR_TRANSPARENT_REFLECTION_2_LAYER
+ Irrlicht EMT_REFLECTION_2_LAYER,EMT_TRANSPARENT_REFLECTION_2_LAYER
+ */
+ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
+ return new CTR_transparent_reflection_2_layer(driver);
+ #else
+ return 0;
+ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
+}
+
+
+} // end namespace video
+} // end namespace irr
+
+
+
diff --git a/source/Irrlicht/CXMeshFileLoader.cpp b/source/Irrlicht/CXMeshFileLoader.cpp
index 89c2c77..feddb40 100644
--- a/source/Irrlicht/CXMeshFileLoader.cpp
+++ b/source/Irrlicht/CXMeshFileLoader.cpp
@@ -912,6 +912,12 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh)
s16 uv2type = -1;
s16 tangenttype = -1;
s16 binormaltype = -1;
+
+ (void)tangentpos; // disable unused variable warnings
+ (void)binormalpos; // disable unused variable warnings
+ (void)tangenttype; // disable unused variable warnings
+ (void)binormaltype; // disable unused variable warnings
+
for (j=0; j<dcnt; ++j)
{
const u32 type = readInt();
diff --git a/source/Irrlicht/IBurningShader.cpp b/source/Irrlicht/IBurningShader.cpp
index f11eac3..a375ef3 100644
--- a/source/Irrlicht/IBurningShader.cpp
+++ b/source/Irrlicht/IBurningShader.cpp
@@ -8,9 +8,12 @@
#include "SoftwareDriver2_compile_config.h"
#include "IBurningShader.h"
#include "CSoftwareDriver2.h"
+#include "IShaderConstantSetCallBack.h"
namespace irr
{
+
+
namespace video
{
@@ -22,95 +25,374 @@ namespace video
0xf0,0x70,0xd0,0x50
};
- IBurningShader::IBurningShader(CBurningVideoDriver* driver)
- {
- #ifdef _DEBUG
- setDebugName("IBurningShader");
- #endif
-
- for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
- {
- IT[i].Texture = 0;
- }
-
- Driver = driver;
- RenderTarget = 0;
- ColorMask = COLOR_BRIGHT_WHITE;
- DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();
- if ( DepthBuffer )
- DepthBuffer->grab();
-
- Stencil = (CStencilBuffer*) driver->getStencilBuffer ();
- if ( Stencil )
- Stencil->grab();
+void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
+{
+ #ifdef _DEBUG
+ setDebugName("IBurningShader");
+ #endif
+ EdgeTestPass = edge_test_pass;
+ EdgeTestPass_stack = edge_test_pass;
+
+ for ( u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i )
+ {
+ IT[i].Texture = 0;
}
+ Driver = driver;
+ CallBack = 0;
+
+ RenderTarget = 0;
+ ColorMask = COLOR_BRIGHT_WHITE;
+ DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();
+ if ( DepthBuffer )
+ DepthBuffer->grab();
+
+ Stencil = (CStencilBuffer*) driver->getStencilBuffer ();
+ if ( Stencil )
+ Stencil->grab();
+
+ stencilOp[0] = StencilOp_KEEP;
+ stencilOp[1] = StencilOp_KEEP;
+ stencilOp[2] = StencilOp_KEEP;
+ AlphaRef = 0;
+ RenderPass_ShaderIsTransparent = 0;
+ PrimitiveColor = COLOR_BRIGHT_WHITE;
+ TL_Flag = 0;
+}
+
+IBurningShader::IBurningShader(CBurningVideoDriver* driver)
+{
+ constructor_IBurningShader(driver);
+}
+
+//! Constructor
+IBurningShader::IBurningShader(
+ CBurningVideoDriver* driver,
+ s32& outMaterialTypeNr,
+ const c8* vertexShaderProgram,
+ const c8* vertexShaderEntryPointName,
+ E_VERTEX_SHADER_TYPE vsCompileTarget,
+ const c8* pixelShaderProgram,
+ const c8* pixelShaderEntryPointName,
+ E_PIXEL_SHADER_TYPE psCompileTarget,
+ const c8* geometryShaderProgram ,
+ const c8* geometryShaderEntryPointName,
+ E_GEOMETRY_SHADER_TYPE gsCompileTarget,
+ scene::E_PRIMITIVE_TYPE inType,
+ scene::E_PRIMITIVE_TYPE outType,
+ u32 verticesOut,
+ IShaderConstantSetCallBack* callback,
+ E_MATERIAL_TYPE baseMaterial,
+ s32 userData)
+{
+ constructor_IBurningShader(driver);
+ BaseMaterial = baseMaterial;
+ CallBack = callback;
+ if (CallBack)
+ CallBack->grab();
+
+ // register myself as new material
+ outMaterialTypeNr = Driver->addMaterialRenderer(this);
+}
+
+
+//! destructor
+IBurningShader::~IBurningShader()
+{
+ if (RenderTarget)
+ RenderTarget->drop();
- //! destructor
- IBurningShader::~IBurningShader()
+ if (DepthBuffer)
+ DepthBuffer->drop();
+
+ if (Stencil)
+ Stencil->drop();
+
+ for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
{
- if (RenderTarget)
- RenderTarget->drop();
+ if ( IT[i].Texture )
+ IT[i].Texture->drop();
+ }
- if (DepthBuffer)
- DepthBuffer->drop();
+ if (CallBack)
+ CallBack->drop();
- if (Stencil)
- Stencil->drop();
+}
- for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
- {
- if ( IT[i].Texture )
- IT[i].Texture->drop();
- }
+//! sets a render target
+void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)
+{
+ if (RenderTarget)
+ RenderTarget->drop();
+
+ RenderTarget = (video::CImage* ) surface;
+
+ if (RenderTarget)
+ {
+ RenderTarget->grab();
+
+ //(fp24*) DepthBuffer->lock() = DepthBuffer->lock();
}
+}
+
- //! sets a render target
- void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)
+//! sets the Texture
+void IBurningShader::setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor)
+{
+ sInternalTexture *it = &IT[stage];
+
+ if ( it->Texture)
+ it->Texture->drop();
+
+ it->Texture = texture;
+
+ if ( it->Texture)
{
- if (RenderTarget)
- RenderTarget->drop();
+ it->Texture->grab();
- RenderTarget = (video::CImage* ) surface;
+ // select mignify and magnify
+ it->lodFactor = lodFactor;
- if (RenderTarget)
- {
- RenderTarget->grab();
+ //only mipmap chain (means positive lodFactor)
+ u32 existing_level = it->Texture->getMipmapLevel(lodFactor);
+ it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY, existing_level, 0);
- //(fp24*) DepthBuffer->lock() = DepthBuffer->lock();
- }
+ // prepare for optimal fixpoint
+ it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );
+
+ const core::dimension2d<u32> &dim = it->Texture->getSize();
+ it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;
+ it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;
}
+}
+
+//emulate a line with degenerate triangle and special shader mode (not perfect...)
+void IBurningShader::drawLine ( const s4DVertex *a,const s4DVertex *b)
+{
+ sVec2 d;
+ d.x = b->Pos.x - a->Pos.x; d.x *= d.x;
+ d.y = b->Pos.y - a->Pos.y; d.y *= d.y;
+ //if ( d.x * d.y < 0.001f ) return;
+
+ if ( a->Pos.x > b->Pos.x ) swapVertexPointer(&a, &b);
+
+ s4DVertex c = *a;
+
+ const f32 w = (f32)RenderTarget->getDimension().Width-1;
+ const f32 h = (f32)RenderTarget->getDimension().Height-1;
+
+ if ( d.x < 2.f ) { c.Pos.x = b->Pos.x + 1.f + d.y; if ( c.Pos.x > w ) c.Pos.x = w; }
+ else c.Pos.x = b->Pos.x;
+ 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; }
+
+ drawTriangle ( a,b,&c );
+ EdgeTestPass &= ~edge_test_first_line;
+
+}
+void IBurningShader::drawPoint(const s4DVertex *a)
+{
+}
- //! sets the Texture
- void IBurningShader::setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel)
+void IBurningShader::drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
+{
+ if ( EdgeTestPass & edge_test_pass ) drawTriangle(a, b, c);
+ else if (EdgeTestPass & edge_test_point)
+ {
+ drawPoint(a);
+ drawPoint(b);
+ drawPoint(c);
+ }
+ else
{
- sInternalTexture *it = &IT[stage];
+ drawLine(a, b);
+ drawLine(b, c);
+ drawLine(a, c);
+ }
+}
- if ( it->Texture)
- it->Texture->drop();
- it->Texture = texture;
+void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
+ bool resetAllRenderstates, IMaterialRendererServices* services)
+{
+ if (Driver)
+ Driver->setFallback_Material(BaseMaterial);
+ services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
+ if (CallBack)
+ CallBack->OnSetMaterial(material);
- if ( it->Texture)
- {
- it->Texture->grab();
+}
- // select mignify and magnify ( lodLevel )
- //SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS
- it->lodLevel = lodLevel;
- it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY,
- core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 ), 0);
+void IBurningShader::OnUnsetMaterial()
+{
+}
- // prepare for optimal fixpoint
- it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );
+bool IBurningShader::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
+{
+ // call callback to set shader constants
+ if (CallBack)
+ CallBack->OnSetConstants(this, UserData);
+ return true;
+}
+
+
+//! Returns if the material is transparent.
+bool IBurningShader::isTransparent() const
+{
+ return RenderPass_ShaderIsTransparent != 0;
+}
+
+//! Access the callback provided by the users when creating shader materials
+IShaderConstantSetCallBack* IBurningShader::getShaderConstantSetCallBack() const
+{
+ return CallBack;
+}
- const core::dimension2d<u32> &dim = it->Texture->getSize();
- it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;
- it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;
- }
+// implementations for the render services
+void IBurningShader::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates)
+{
+ // forward
+ Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
+}
+
+s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags,const c8* name)
+{
+ if (!name || !name[0])
+ return -1;
+
+ BurningUniform add;
+ tiny_strcpy(add.name, name);
+ add.type = flags;
+
+ s32 index = UniformInfo.linear_search(add);
+ if (index < 0)
+ {
+ UniformInfo.push_back(add);
+ index = UniformInfo.size() - 1;
+ }
+
+ return index;
+}
+
+const char* tiny_itoa(s32 value, int base)
+{
+ static char b[32];
+ int p = 31;
+
+ //int sign = 0;
+ //if (value < 0) { sign = 1; value = -value; }
+
+ b[p] = '\0';
+ do {
+ b[--p] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[value%base];
+ value /= base;
+ } while (value && p > 0);
+
+ //if (sign && p > 0) { b[--p] = '-'; }
+
+ return b + p;
+}
+
+bool IBurningShader::setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count)
+{
+ if ((u32)index >= UniformInfo.size())
+ return false;
+#if 0
+ BurningUniform add;
+ while ((u32)index >= UniformInfo.size())
+ {
+ tiny_strcpy(add.name, tiny_itoa(UniformInfo.size(),10));
+ add.type = flags;
+ UniformInfo.push_back(add);
}
+#endif
+
+ BurningUniform& use = UniformInfo[index];
+ use.type = flags;
+
+ const u32* s = (u32*)data;
+ u32* d = (u32*)use.data;
+
+ if (!s) u32_count = 0;
+ if (u32_count > array_size(use.data)) u32_count = array_size(use.data);
+ for (size_t i = 0; i < u32_count; ++i)
+ {
+ d[i] = s[i];
+ }
+
+ return true;
+}
+
+
+s32 IBurningShader::getVertexShaderConstantID(const c8* name)
+{
+ return getShaderConstantID(BL_VERTEX_PROGRAM, name);
+}
+
+s32 IBurningShader::getPixelShaderConstantID(const c8* name)
+{
+ return getShaderConstantID(BL_FRAGMENT_PROGRAM, name);
+}
+
+void IBurningShader::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
+{
+ c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
+ tiny_strcpy(name, tiny_itoa(startRegister, 10));
+
+ setShaderConstantID(BL_VERTEX_FLOAT, getShaderConstantID(BL_VERTEX_PROGRAM,name), data, constantAmount);
+}
+
+void IBurningShader::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
+{
+ c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
+ tiny_strcpy(name, tiny_itoa(startRegister, 10));
+
+ setShaderConstantID(BL_FRAGMENT_FLOAT, getShaderConstantID(BL_FRAGMENT_PROGRAM, name), data, constantAmount);
+}
+
+bool IBurningShader::setVertexShaderConstant(s32 index, const f32* floats, int count)
+{
+ return setShaderConstantID(BL_VERTEX_FLOAT, index, floats, count);
+}
+
+bool IBurningShader::setVertexShaderConstant(s32 index, const s32* ints, int count)
+{
+ return setShaderConstantID(BL_VERTEX_INT, index, ints, count);
+}
+
+bool IBurningShader::setVertexShaderConstant(s32 index, const u32* ints, int count)
+{
+ return setShaderConstantID(BL_VERTEX_UINT, index, ints, count);
+}
+
+bool IBurningShader::setPixelShaderConstant(s32 index, const f32* floats, int count)
+{
+ return setShaderConstantID(BL_FRAGMENT_FLOAT, index, floats, count);
+}
+
+bool IBurningShader::setPixelShaderConstant(s32 index, const s32* ints, int count)
+{
+ return setShaderConstantID(BL_FRAGMENT_INT, index, ints, count);
+}
+
+bool IBurningShader::setPixelShaderConstant(s32 index, const u32* ints, int count)
+{
+ return setShaderConstantID(BL_FRAGMENT_UINT, index, ints, count);
+}
+
+void IBurningShader::setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass)
+{
+ stencilOp[0] = sfail;
+ stencilOp[1] = dpfail;
+ stencilOp[2] = dppass;
+}
+
+
+IVideoDriver* IBurningShader::getVideoDriver()
+{
+ return Driver;
+}
} // end namespace video
diff --git a/source/Irrlicht/IBurningShader.h b/source/Irrlicht/IBurningShader.h
index 0fffff7..8a9a818 100644
--- a/source/Irrlicht/IBurningShader.h
+++ b/source/Irrlicht/IBurningShader.h
@@ -18,7 +18,9 @@
#include "SLight.h"
#include "SMaterial.h"
#include "os.h"
-
+#include "IMaterialRenderer.h"
+#include "IMaterialRendererServices.h"
+#include "IGPUProgrammingServices.h"
namespace irr
{
@@ -29,56 +31,109 @@ namespace video
struct SBurningShaderLight
{
//SLight org;
- bool LightIsOn;
+
+ sVec4 pos; //light position input
+ sVec4 pos4; //light position Model*View (Identity*View)
E_LIGHT_TYPE Type;
- f32 radius;
f32 linearAttenuation;
f32 constantAttenuation;
f32 quadraticAttenuation;
- sVec4 pos;
- sVec3 AmbientColor;
- sVec3 DiffuseColor;
- sVec3 SpecularColor;
- sVec4 pos_objectspace;
+ sVec4 spotDirection;
+ sVec4 spotDirection4;
+ f32 spotCosCutoff;
+ f32 spotCosInnerCutoff;
+ f32 spotExponent;
+ bool LightIsOn;
+
+ sVec3Color AmbientColor;
+ sVec3Color DiffuseColor;
+ sVec3Color SpecularColor;
};
- enum eLightFlags
+ enum eTransformLightFlags
{
- ENABLED = 0x01,
- POINTLIGHT = 0x02,
- SPECULAR = 0x04,
- FOG = 0x08,
- NORMALIZE = 0x10,
- VERTEXTRANSFORM = 0x20,
+ //ENABLED = 0x01,
+ TL_SCISSOR = 0x02,
+ TL_LIGHT = 0x04,
+ TL_SPECULAR = 0x08,
+ TL_FOG = 0x10,
+ TL_NORMALIZE_NORMALS = 0x20,
+ TL_TEXTURE_TRANSFORM = 0x40,
+ TL_LIGHT_LOCAL_VIEWER = 0x80,
+ TL_LIGHT0_IS_NORMAL_MAP = 0x100 //sVec4 Light Vector is used as normal or specular
};
- struct SBurningShaderLightSpace
+ struct SBurningShaderEyeSpace
{
+ SBurningShaderEyeSpace() {}
+ virtual ~SBurningShaderEyeSpace() {}
void reset ()
{
Light.set_used ( 0 );
- Global_AmbientLight.set ( 0.f, 0.f, 0.f );
- Flags = 0;
+ Global_AmbientLight.set ( 0.f );
+
+ TL_Flag = TL_LIGHT_LOCAL_VIEWER;
+ }
+ void resetFog()
+ {
+ fog_scale = 0.f;
+ //cam_distance = 0.f;
}
+
core::array<SBurningShaderLight> Light;
- sVec3 Global_AmbientLight;
- sVec4 FogColor;
- sVec4 campos;
- sVec4 vertex;
- sVec4 normal;
- u32 Flags;
+ sVec3Color Global_AmbientLight;
+
+ //sVec4 cam_eye_pos; //Camera Position in eye Space (0,0,-1)
+ //sVec4 cam_world_pos; //Camera Position in world Space
+ //sVec4 vertex4; //eye coordinate position of vertex
+ sVec4 normal; //transformed normal
+ sVec4 vertex; //eye coordinate position of vertex projected
+
+ //derivative of vertex
+ //f32 cam_distance; // vertex.length();
+ sVec4 cam_dir; //vertex.normalize();
+
+ f32 fog_scale; // 1 / (fog.end-fog.start)
+
+ size_t TL_Flag; // eTransformLightFlags
+ };
+
+ enum eBurningCullFlag
+ {
+ CULL_FRONT = 1,
+ CULL_BACK = 2,
+ CULL_INVISIBLE = 4, //primitive smaller than a pixel (AreaMinDrawSize)
+ CULL_FRONT_AND_BACK = 8,
+ };
+
+ enum eBurningStencilOp
+ {
+ StencilOp_KEEP = 0x1E00,
+ StencilOp_INCR = 0x1E02,
+ StencilOp_DECR = 0x1E03
};
struct SBurningShaderMaterial
{
SMaterial org;
+ SMaterial lastMaterial;
+ bool resetRenderStates;
+
+ E_MATERIAL_TYPE Fallback_MaterialType;
- sVec3 AmbientColor;
- sVec3 DiffuseColor;
- sVec3 SpecularColor;
- sVec3 EmissiveColor;
+ SMaterial mat2D;
+ //SMaterial save3D;
+
+ size_t CullFlag; //eCullFlag
+ u32 depth_write;
+ u32 depth_test;
+
+ sVec3Color AmbientColor;
+ sVec3Color DiffuseColor;
+ sVec3Color SpecularColor;
+ sVec3Color EmissiveColor;
};
@@ -106,29 +161,88 @@ namespace video
ETR_TEXTURE_GOURAUD_DETAIL_MAP,
ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD,
- ETR_GOURAUD_ALPHA,
+ ETR_GOURAUD_NOZ,
+ //ETR_GOURAUD_ALPHA,
ETR_GOURAUD_ALPHA_NOZ,
ETR_TEXTURE_GOURAUD_ALPHA,
ETR_TEXTURE_GOURAUD_ALPHA_NOZ,
+ ETR_TEXTURE_GOURAUD_ALPHA_NOZ_NOPERSPECTIVE_CORRECT,
ETR_NORMAL_MAP_SOLID,
ETR_STENCIL_SHADOW,
ETR_TEXTURE_BLEND,
- ETR_REFERENCE,
+ ETR_TRANSPARENT_REFLECTION_2_LAYER,
+
+ ETR_COLOR,
+
+ //ETR_REFERENCE,
ETR_INVALID,
ETR2_COUNT
};
+ typedef enum
+ {
+ BL_VERTEX_PROGRAM = 1,
+ BL_FRAGMENT_PROGRAM = 2,
+ BL_TYPE_FLOAT = 4,
+ BL_TYPE_INT = 8,
+ BL_TYPE_UINT = 16,
+
+ BL_VERTEX_FLOAT = (BL_VERTEX_PROGRAM | BL_TYPE_FLOAT),
+ BL_VERTEX_INT = (BL_VERTEX_PROGRAM | BL_TYPE_INT),
+ BL_VERTEX_UINT = (BL_VERTEX_PROGRAM | BL_TYPE_UINT),
+ BL_FRAGMENT_FLOAT = (BL_FRAGMENT_PROGRAM | BL_TYPE_FLOAT),
+ BL_FRAGMENT_INT = (BL_FRAGMENT_PROGRAM | BL_TYPE_INT),
+ BL_FRAGMENT_UINT = (BL_FRAGMENT_PROGRAM | BL_TYPE_UINT),
+
+ BL_ACTIVE_UNIFORM_MAX_LENGTH = 28
+ } EBurningUniformFlags;
+
+ struct BurningUniform
+ {
+ c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
+ u32 type; //EBurningUniformFlags
+ //int location; // UniformLocation is index
+ f32 data[16]; // simple LocalParameter
+
+ bool operator==(const BurningUniform& other) const
+ {
+ return tiny_istoken(name, other.name);
+ }
+
+ };
+
class CBurningVideoDriver;
- class IBurningShader : public virtual IReferenceCounted
+ class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices
{
public:
+ //! Constructor
IBurningShader(CBurningVideoDriver* driver);
+ //! Constructor
+ IBurningShader(
+ CBurningVideoDriver* driver,
+ s32& outMaterialTypeNr,
+ const c8* vertexShaderProgram = 0,
+ const c8* vertexShaderEntryPointName = 0,
+ E_VERTEX_SHADER_TYPE vsCompileTarget = video::EVST_VS_1_1,
+ const c8* pixelShaderProgram = 0,
+ const c8* pixelShaderEntryPointName = 0,
+ E_PIXEL_SHADER_TYPE psCompileTarget = video::EPST_PS_1_1,
+ const c8* geometryShaderProgram = 0,
+ const c8* geometryShaderEntryPointName = "main",
+ E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
+ scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
+ scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
+ u32 verticesOut = 0,
+ IShaderConstantSetCallBack* callback = 0,
+ E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
+ s32 userData = 0);
+
//! destructor
virtual ~IBurningShader();
@@ -136,27 +250,121 @@ namespace video
virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort);
//! sets the Texture
- virtual void setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel);
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) = 0;
- virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) {};
+ virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor);
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) {};
+ virtual void drawLine ( const s4DVertex *a,const s4DVertex *b);
+ virtual void drawPoint(const s4DVertex *a);
+
+ void drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
+
+ virtual void OnSetMaterial( const SBurningShaderMaterial& material ) {};
+
+ void pushEdgeTest(const int wireFrame,const int point,int save)
+ {
+ if ( save ) EdgeTestPass_stack = EdgeTestPass;
+ EdgeTestPass = point ? edge_test_point : wireFrame ? edge_test_left : edge_test_pass;
+ }
+ void popEdgeTest() { EdgeTestPass = EdgeTestPass_stack; }
+ virtual bool canWireFrame () { return false; }
+ virtual bool canPointCloud() { return false; }
+
+ void setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass);
- virtual void setParam ( u32 index, f32 value) {};
- virtual void setZCompareFunc ( u32 func) {};
+ //IMaterialRenderer
- virtual void setMaterial ( const SBurningShaderMaterial &material ) {};
+ virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
+ bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_;
+
+ virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_;
+
+ virtual void OnUnsetMaterial() _IRR_OVERRIDE_;
+
+ //! Returns if the material is transparent.
+ virtual bool isTransparent() const _IRR_OVERRIDE_;
+
+ //! Access the callback provided by the users when creating shader materials
+ virtual IShaderConstantSetCallBack* getShaderConstantSetCallBack() const _IRR_OVERRIDE_;
+
+ // implementations for the render services
+ virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) _IRR_OVERRIDE_;
+ virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;
+ virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;
+ virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) _IRR_OVERRIDE_;
+ virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) _IRR_OVERRIDE_;
+ virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
+ virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
+ virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
+ virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
+ virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
+ virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
+ virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
+
+ //used if no color interpolation is defined
+ void setPrimitiveColor(const video::SColor& color)
+ {
+ #if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8
+ PrimitiveColor = color.color;
+ #else
+ PrimitiveColor = color.toA1R5G5B5();
+ #endif
+ }
+ void setTLFlag(size_t in /*eTransformLightFlags*/)
+ {
+ TL_Flag = in;
+ }
+ void setFog(SColor color_fog)
+ {
+#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8
+ fog_color_sample = color_fog.color;
+#else
+ fog_color_sample = color_fog.toA1R5G5B5();
+#endif
+ color_to_fix(fog_color, fog_color_sample);
+ }
+ void setScissor(const AbsRectangle& scissor)
+ {
+ Scissor = scissor;
+ }
protected:
+ void constructor_IBurningShader(CBurningVideoDriver* driver);
+
CBurningVideoDriver *Driver;
+ IShaderConstantSetCallBack* CallBack;
+ E_MATERIAL_TYPE BaseMaterial;
+ s32 UserData;
+
+ core::array<BurningUniform> UniformInfo;
+ s32 getShaderConstantID(EBurningUniformFlags program, const c8* name);
+ bool setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count);
video::CImage* RenderTarget;
CDepthBuffer* DepthBuffer;
- CStencilBuffer * Stencil;
+ CStencilBuffer* Stencil;
tVideoSample ColorMask;
sInternalTexture IT[ BURNING_MATERIAL_MAX_TEXTURES ];
static const tFixPointu dithermask[ 4 * 4];
+
+ //draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham
+ int EdgeTestPass; //edge_test_flag
+ int EdgeTestPass_stack;
+
+ eBurningStencilOp stencilOp[4];
+ tFixPoint AlphaRef;
+ int RenderPass_ShaderIsTransparent;
+
+ sScanConvertData scan;
+ sScanLineData line;
+ tVideoSample PrimitiveColor; //used if no color interpolation is defined
+
+ size_t /*eTransformLightFlags*/ TL_Flag;
+ tFixPoint fog_color[4];
+ tVideoSample fog_color_sample;
+
+ AbsRectangle Scissor;
};
@@ -172,6 +380,7 @@ namespace video
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver);
+ IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver);
@@ -192,8 +401,9 @@ namespace video
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver);
+ IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver);
-
+ IBurningShader* create_burning_shader_color(CBurningVideoDriver* driver);
} // end namespace video
} // end namespace irr
diff --git a/source/Irrlicht/IDepthBuffer.h b/source/Irrlicht/IDepthBuffer.h
index 719d9f1..89f604f 100644
--- a/source/Irrlicht/IDepthBuffer.h
+++ b/source/Irrlicht/IDepthBuffer.h
@@ -21,7 +21,7 @@ namespace video
virtual ~IDepthBuffer() {};
//! clears the zbuffer
- virtual void clear() = 0;
+ virtual void clear(f32 value) = 0;
//! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) = 0;
@@ -51,29 +51,29 @@ namespace video
//! destructor
virtual ~IStencilBuffer() {};
- //! clears the zbuffer
- virtual void clear() = 0;
+ //! clears the stencil buffer
+ virtual void clear(u8 value) = 0;
//! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) = 0;
- //! returns the size of the zbuffer
+ //! returns the size of the stencil buffer
virtual const core::dimension2d<u32>& getSize() const = 0;
- //! locks the zbuffer
+ //! locks the stencil buffer
virtual void* lock() = 0;
- //! unlocks the zbuffer
+ //! unlocks the stencil buffer
virtual void unlock() = 0;
- //! returns pitch of depthbuffer (in bytes)
+ //! returns pitch of stencil buffer (in bytes)
virtual u32 getPitch() const = 0;
};
//! creates a Stencil Buffer
- IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size);
+ IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size, u32 bit);
} // end namespace video
} // end namespace irr
diff --git a/source/Irrlicht/Irrlicht-gcc.cbp b/source/Irrlicht/Irrlicht-gcc.cbp
index 3e8d0ad..a1dbf21 100644
--- a/source/Irrlicht/Irrlicht-gcc.cbp
+++ b/source/Irrlicht/Irrlicht-gcc.cbp
@@ -972,6 +972,7 @@
<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" />
@@ -997,6 +998,7 @@
<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" />
@@ -1068,6 +1070,14 @@
<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>
diff --git a/source/Irrlicht/Irrlicht10.0.vcxproj b/source/Irrlicht/Irrlicht10.0.vcxproj
index 78c279c..b61cdc0 100644
--- a/source/Irrlicht/Irrlicht10.0.vcxproj
+++ b/source/Irrlicht/Irrlicht10.0.vcxproj
@@ -1005,6 +1005,13 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
+ <ClInclude Include="burning_shader_color_fraq.h" />
+ <ClInclude Include="burning_shader_compile_fragment_default.h" />
+ <ClInclude Include="burning_shader_compile_fragment_end.h" />
+ <ClInclude Include="burning_shader_compile_fragment_start.h" />
+ <ClInclude Include="burning_shader_compile_start.h" />
+ <ClInclude Include="burning_shader_compile_triangle.h" />
+ <ClInclude Include="burning_shader_compile_verify.h" />
<ClInclude Include="CB3DMeshWriter.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
@@ -1271,6 +1278,7 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="burning_shader_color.cpp" />
<ClCompile Include="CB3DMeshWriter.cpp" />
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
@@ -1322,6 +1330,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />
diff --git a/source/Irrlicht/Irrlicht10.0.vcxproj.filters b/source/Irrlicht/Irrlicht10.0.vcxproj.filters
index 6269a9c..618fb88 100644
--- a/source/Irrlicht/Irrlicht10.0.vcxproj.filters
+++ b/source/Irrlicht/Irrlicht10.0.vcxproj.filters
@@ -1390,6 +1390,27 @@
<ClInclude Include="..\..\include\IOctreeSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
+ <ClInclude Include="burning_shader_color_fraq.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_default.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_end.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_start.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_start.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_triangle.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_verify.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@@ -2357,6 +2378,15 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
+ <ClCompile Include="burning_shader_color.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTRGouraudNoZ2.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />
diff --git a/source/Irrlicht/Irrlicht11.0.vcxproj b/source/Irrlicht/Irrlicht11.0.vcxproj
index 791a36a..e6b828e 100644
--- a/source/Irrlicht/Irrlicht11.0.vcxproj
+++ b/source/Irrlicht/Irrlicht11.0.vcxproj
@@ -1004,6 +1004,13 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
+ <ClInclude Include="burning_shader_color_fraq.h" />
+ <ClInclude Include="burning_shader_compile_fragment_default.h" />
+ <ClInclude Include="burning_shader_compile_fragment_end.h" />
+ <ClInclude Include="burning_shader_compile_fragment_start.h" />
+ <ClInclude Include="burning_shader_compile_start.h" />
+ <ClInclude Include="burning_shader_compile_triangle.h" />
+ <ClInclude Include="burning_shader_compile_verify.h" />
<ClInclude Include="CB3DMeshWriter.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
@@ -1270,6 +1277,7 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="burning_shader_color.cpp" />
<ClCompile Include="CB3DMeshWriter.cpp" />
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
@@ -1321,6 +1329,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />
diff --git a/source/Irrlicht/Irrlicht11.0.vcxproj.filters b/source/Irrlicht/Irrlicht11.0.vcxproj.filters
index f61a3f9..1cffa75 100644
--- a/source/Irrlicht/Irrlicht11.0.vcxproj.filters
+++ b/source/Irrlicht/Irrlicht11.0.vcxproj.filters
@@ -1390,6 +1390,27 @@
<ClInclude Include="..\..\include\IOctreeSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
+ <ClInclude Include="burning_shader_color_fraq.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_default.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_end.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_start.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_start.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_triangle.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_verify.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@@ -2357,6 +2378,15 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
+ <ClCompile Include="burning_shader_color.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTRGouraudNoZ2.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />
diff --git a/source/Irrlicht/Irrlicht12.0.vcxproj b/source/Irrlicht/Irrlicht12.0.vcxproj
index 7b01c74..9581357 100644
--- a/source/Irrlicht/Irrlicht12.0.vcxproj
+++ b/source/Irrlicht/Irrlicht12.0.vcxproj
@@ -1321,6 +1321,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />
diff --git a/source/Irrlicht/Irrlicht12.0.vcxproj.filters b/source/Irrlicht/Irrlicht12.0.vcxproj.filters
index 7e94d18..0623a91 100644
--- a/source/Irrlicht/Irrlicht12.0.vcxproj.filters
+++ b/source/Irrlicht/Irrlicht12.0.vcxproj.filters
@@ -2357,6 +2357,12 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTRGouraudNoZ2.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />
diff --git a/source/Irrlicht/Irrlicht14.0.vcxproj b/source/Irrlicht/Irrlicht14.0.vcxproj
index 22385f1..47f07a3 100644
--- a/source/Irrlicht/Irrlicht14.0.vcxproj
+++ b/source/Irrlicht/Irrlicht14.0.vcxproj
@@ -1015,7 +1015,15 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
+ <ClInclude Include="burning_shader_color_fraq.h" />
+ <ClInclude Include="burning_shader_compile_fragment_default.h" />
+ <ClInclude Include="burning_shader_compile_fragment_end.h" />
+ <ClInclude Include="burning_shader_compile_fragment_start.h" />
+ <ClInclude Include="burning_shader_compile_start.h" />
+ <ClInclude Include="burning_shader_compile_triangle.h" />
+ <ClInclude Include="burning_shader_compile_verify.h" />
<ClInclude Include="CB3DMeshWriter.h" />
+ <ClInclude Include="CBlit.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
<ClInclude Include="CDefaultSceneNodeFactory.h" />
@@ -1281,6 +1289,7 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="burning_shader_color.cpp" />
<ClCompile Include="CB3DMeshWriter.cpp" />
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
@@ -1332,6 +1341,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />
diff --git a/source/Irrlicht/Irrlicht14.0.vcxproj.filters b/source/Irrlicht/Irrlicht14.0.vcxproj.filters
index ed8c285..077634d 100644
--- a/source/Irrlicht/Irrlicht14.0.vcxproj.filters
+++ b/source/Irrlicht/Irrlicht14.0.vcxproj.filters
@@ -1390,6 +1390,30 @@
<ClInclude Include="..\..\include\IOctreeSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
+ <ClInclude Include="burning_shader_color_fraq.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_default.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_end.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_start.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_start.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_triangle.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_verify.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="CBlit.h">
+ <Filter>Irrlicht\video\Null</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@@ -2357,6 +2381,15 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
+ <ClCompile Include="burning_shader_color.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTRGouraudNoZ2.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />
diff --git a/source/Irrlicht/Irrlicht15.0.vcxproj b/source/Irrlicht/Irrlicht15.0.vcxproj
index 3e76607..4ae8670 100644
--- a/source/Irrlicht/Irrlicht15.0.vcxproj
+++ b/source/Irrlicht/Irrlicht15.0.vcxproj
@@ -1014,6 +1014,13 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
+ <ClInclude Include="burning_shader_color_fraq.h" />
+ <ClInclude Include="burning_shader_compile_fragment_default.h" />
+ <ClInclude Include="burning_shader_compile_fragment_end.h" />
+ <ClInclude Include="burning_shader_compile_fragment_start.h" />
+ <ClInclude Include="burning_shader_compile_start.h" />
+ <ClInclude Include="burning_shader_compile_triangle.h" />
+ <ClInclude Include="burning_shader_compile_verify.h" />
<ClInclude Include="CB3DMeshWriter.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
@@ -1268,6 +1275,7 @@
<None Include="Irrlicht.ruleset" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="burning_shader_color.cpp" />
<ClCompile Include="CB3DMeshWriter.cpp" />
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
@@ -1309,6 +1317,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />
diff --git a/source/Irrlicht/Irrlicht15.0.vcxproj.filters b/source/Irrlicht/Irrlicht15.0.vcxproj.filters
index 7230ff8..16c0835 100644
--- a/source/Irrlicht/Irrlicht15.0.vcxproj.filters
+++ b/source/Irrlicht/Irrlicht15.0.vcxproj.filters
@@ -1342,6 +1342,27 @@
<ClInclude Include="..\..\include\SOverrideMaterial.h">
<Filter>include\video</Filter>
</ClInclude>
+ <ClInclude Include="burning_shader_color_fraq.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_default.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_end.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_fragment_start.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_start.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_triangle.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
+ <ClInclude Include="burning_shader_compile_verify.h">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@@ -2280,6 +2301,15 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
+ <ClCompile Include="burning_shader_color.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
+ <ClCompile Include="CTRGouraudNoZ2.cpp">
+ <Filter>Irrlicht\video\Burning Video</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />
diff --git a/source/Irrlicht/Makefile b/source/Irrlicht/Makefile
index 37b14fb..c967d24 100644
--- a/source/Irrlicht/Makefile
+++ b/source/Irrlicht/Makefile
@@ -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 \
CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o
IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)
-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
+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 CTR_transparent_reflection_2_layer.o CTRGouraudNoZ2.o burning_shader_color.o
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
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
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
diff --git a/source/Irrlicht/S4DVertex.h b/source/Irrlicht/S4DVertex.h
index 7ad6b83..92abbb2 100644
--- a/source/Irrlicht/S4DVertex.h
+++ b/source/Irrlicht/S4DVertex.h
@@ -9,6 +9,7 @@
#include "SoftwareDriver2_compile_config.h"
#include "SoftwareDriver2_helper.h"
#include "irrAllocator.h"
+#include "EPrimitiveTypes.h"
namespace irr
{
@@ -16,6 +17,7 @@ namespace irr
namespace video
{
+//! sVec2 used in BurningShader texture coordinates
struct sVec2
{
f32 x;
@@ -34,10 +36,10 @@ struct sVec2
}
// f = a * t + b * ( 1 - t )
- void interpolate(const sVec2& a, const sVec2& b, const f32 t)
+ void interpolate(const sVec2& burning_restrict a, const sVec2& burning_restrict b, const ipoltype t)
{
- x = b.x + ( ( a.x - b.x ) * t );
- y = b.y + ( ( a.y - b.y ) * t );
+ x = (f32)(b.x + ( ( a.x - b.x ) * t ));
+ y = (f32)(b.y + ( ( a.y - b.y ) * t ));
}
sVec2 operator-(const sVec2& other) const
@@ -75,333 +77,298 @@ struct sVec2
};
-// A8R8G8B8
-struct sVec4;
-struct sCompressedVec4
+#include "irrpack.h"
+
+//! sVec3Pack used in BurningShader, packed direction
+struct sVec3Pack
{
- u32 argb;
+ f32 x, y, z;
+ //f32 _can_pack;
+
+ sVec3Pack() {}
+ sVec3Pack(f32 _x, f32 _y, f32 _z)
+ : x(_x), y(_y), z(_z) {}
- void setA8R8G8B8 ( u32 value )
+ // f = a * t + b * ( 1 - t )
+ void interpolate(const sVec3Pack& burning_restrict v0, const sVec3Pack& burning_restrict v1, const ipoltype t)
{
- argb = value;
+ x = (f32)(v1.x + ((v0.x - v1.x) * t));
+ y = (f32)(v1.y + ((v0.y - v1.y) * t));
+ z = (f32)(v1.z + ((v0.z - v1.z) * t));
}
- void setColorf ( const video::SColorf & color )
+ sVec3Pack operator-(const sVec3Pack& other) const
{
- argb = core::floor32_fast( color.a * 255.f ) << 24 |
- core::floor32_fast( color.r * 255.f ) << 16 |
- core::floor32_fast( color.g * 255.f ) << 8 |
- core::floor32_fast( color.b * 255.f );
+ return sVec3Pack(x - other.x, y - other.y, z - other.z);
}
- void setVec4 ( const sVec4 & v );
+ sVec3Pack operator+(const sVec3Pack& other) const
+ {
+ return sVec3Pack(x + other.x, y + other.y, z + other.z);
+ }
- // f = a * t + b * ( 1 - t )
- void interpolate(const sCompressedVec4& a, const sCompressedVec4& b, const f32 t)
+ sVec3Pack operator*(const f32 s) const
{
- argb = PixelBlend32 ( b.argb, a.argb, core::floor32_fast( t * 256.f ) );
+ return sVec3Pack(x * s, y * s, z * s);
}
+ void operator+=(const sVec3Pack& other)
+ {
+ x += other.x;
+ y += other.y;
+ z += other.z;
+ }
-};
+ void operator=(const sVec3Pack& other)
+ {
+ x = other.x;
+ y = other.y;
+ z = other.z;
+ }
+} PACK_STRUCT;
+#include "irrunpack.h"
+
+//! sVec4 used in Driver,BurningShader, direction/color
struct sVec4
{
union
{
struct { f32 x, y, z, w; };
struct { f32 a, r, g, b; };
-// struct { sVec2 xy, zw; }; // sorry, this does not compile with gcc
};
-
-
sVec4 () {}
-
- sVec4 ( f32 s) : x ( s ), y ( s ), z ( s ), w ( s ) {}
-
sVec4 ( f32 _x, f32 _y, f32 _z, f32 _w )
: x ( _x ), y ( _y ), z( _z ), w ( _w ){}
- void set ( f32 _x, f32 _y, f32 _z, f32 _w )
- {
- x = _x;
- y = _y;
- z = _z;
- w = _w;
- }
-
- void setA8R8G8B8 ( u32 argb )
- {
- x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f );
- y = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f );
- z = ( ( argb & 0x0000FF00 ) >> 8 ) * ( 1.f / 255.f );
- w = ( ( argb & 0x000000FF ) ) * ( 1.f / 255.f );
- }
-
-
- void setColorf ( const video::SColorf & color )
- {
- x = color.a;
- y = color.r;
- z = color.g;
- w = color.b;
- }
-
-
// f = a * t + b * ( 1 - t )
- void interpolate(const sVec4& a, const sVec4& b, const f32 t)
+ void interpolate(const sVec4& burning_restrict a, const sVec4& burning_restrict b, const ipoltype t)
{
- x = b.x + ( ( a.x - b.x ) * t );
- y = b.y + ( ( a.y - b.y ) * t );
- z = b.z + ( ( a.z - b.z ) * t );
- w = b.w + ( ( a.w - b.w ) * t );
+ x = (f32)(b.x + ( ( a.x - b.x ) * t ));
+ y = (f32)(b.y + ( ( a.y - b.y ) * t ));
+ z = (f32)(b.z + ( ( a.z - b.z ) * t ));
+ w = (f32)(b.w + ( ( a.w - b.w ) * t ));
}
-
- f32 dotProduct(const sVec4& other) const
+ sVec4 operator-(const sVec4& other) const
{
- return x*other.x + y*other.y + z*other.z + w*other.w;
+ return sVec4(x - other.x, y - other.y, z - other.z,w - other.w);
}
- f32 dot_xyz( const sVec4& other) const
+ sVec4 operator+(const sVec4& other) const
{
- return x*other.x + y*other.y + z*other.z;
+ return sVec4(x + other.x, y + other.y, z + other.z,w + other.w);
}
- f32 get_length_xyz_square () const
+ void operator+=(const sVec4& other)
{
- return x * x + y * y + z * z;
+ x += other.x;
+ y += other.y;
+ z += other.z;
+ w += other.w;
}
- f32 get_length_xyz () const
+ sVec4 operator*(const f32 s) const
{
- return core::squareroot ( x * x + y * y + z * z );
+ return sVec4(x * s , y * s, z * s,w * s);
}
- void normalize_xyz ()
+ sVec4 operator*(const sVec4 &other) const
{
- const f32 l = core::reciprocal_squareroot ( x * x + y * y + z * z );
-
- x *= l;
- y *= l;
- z *= l;
+ return sVec4(x * other.x , y * other.y, z * other.z,w * other.w);
}
- void project_xyz ()
+ void operator*=(const sVec4 &other)
{
- w = core::reciprocal ( w );
- x *= w;
- y *= w;
- z *= w;
+ x *= other.x;
+ y *= other.y;
+ z *= other.z;
+ w *= other.w;
}
- sVec4 operator-(const sVec4& other) const
+ void operator=(const sVec4& other)
{
- return sVec4(x - other.x, y - other.y, z - other.z,w - other.w);
+ x = other.x;
+ y = other.y;
+ z = other.z;
+ w = other.w;
}
- sVec4 operator+(const sVec4& other) const
+ //outside shader
+ void set(f32 _x, f32 _y, f32 _z, f32 _w)
{
- return sVec4(x + other.x, y + other.y, z + other.z,w + other.w);
+ x = _x;
+ y = _y;
+ z = _z;
+ w = _w;
}
-
- void operator+=(const sVec4& other)
+ void setA8R8G8B8(const u32 argb)
{
- x += other.x;
- y += other.y;
- z += other.z;
- w += other.w;
+ a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
+ r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);
+ g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);
+ b = ((argb & 0x000000FF) ) * (1.f / 255.f);
}
- sVec4 operator*(const f32 s) const
+ REALINLINE ipoltype dot_xyzw(const sVec4& other) const
{
- return sVec4(x * s , y * s, z * s,w * s);
+ return (ipoltype)x * other.x + (ipoltype)y * other.y + (ipoltype)z * other.z + (ipoltype)w * other.w;
}
- sVec4 operator*(const sVec4 &other) const
+ REALINLINE f32 dot_xyz(const sVec4& other) const
{
- return sVec4(x * other.x , y * other.y, z * other.z,w * other.w);
+ return x * other.x + y * other.y + z * other.z;
}
- void mulReciprocal ( f32 s )
+ REALINLINE f32 dot_minus_xyz(const sVec4& other) const
{
- const f32 i = core::reciprocal ( s );
- x = (f32) ( x * i );
- y = (f32) ( y * i );
- z = (f32) ( z * i );
- w = (f32) ( w * i );
+ return -x * other.x + -y * other.y + -z * other.z;
}
- void mul ( const f32 s )
+ void mul_xyz(const f32 s)
{
x *= s;
y *= s;
z *= s;
- w *= s;
}
-/*
- void operator*=(f32 s)
+ f32 length_xyz() const
{
- x *= s;
- y *= s;
- z *= s;
- w *= s;
+ return sqrtf(x * x + y * y + z * z);
}
-*/
- void operator*=(const sVec4 &other)
+
+ void normalize_dir_xyz()
{
- x *= other.x;
- y *= other.y;
- z *= other.z;
- w *= other.w;
+ //const f32 l = core::reciprocal_squareroot(x * x + y * y + z * z);
+ f32 l = x * x + y * y + z * z;
+ l = l > 0.0000001f ? 1.f / sqrtf(l) : 1.f;
+ x *= l;
+ y *= l;
+ z *= l;
}
- void operator=(const sVec4& other)
+
+ //unpack sVec3 to aligned during runtime
+ sVec4(const sVec3Pack& other)
{
x = other.x;
y = other.y;
z = other.z;
- w = other.w;
+ w = 0.f;
}
-};
-struct sVec3
-{
- union
+ void normalize_pack_xyz(sVec3Pack& out, const f32 len, const f32 ofs) const
{
- struct { f32 r, g, b; };
- struct { f32 x, y, z; };
- };
+ //const f32 l = len * core::reciprocal_squareroot ( r * r + g * g + b * b );
+ f32 l = x * x + y * y + z * z;
+ l = l > 0.0000001f ? len / sqrtf(l) : 0.f;
+ out.x = (x*l) + ofs;
+ out.y = (y*l) + ofs;
+ out.z = (z*l) + ofs;
+ }
- sVec3 () {}
- sVec3 ( f32 _x, f32 _y, f32 _z )
- : r ( _x ), g ( _y ), b( _z ) {}
+};
- sVec3 ( const sVec4 &v )
- : r ( v.x ), g ( v.y ), b( v.z ) {}
+//!during runtime sVec3Pack
+typedef sVec4 sVec3Pack_unpack;
- void set ( f32 _r, f32 _g, f32 _b )
+//!sVec4 is argb. sVec3Color is rgba
+struct sVec3Color
+{
+ f32 r, g, b,a;
+
+ void set(const f32 s)
{
- r = _r;
- g = _g;
- b = _b;
+ r = s;
+ g = s;
+ b = s;
+ a = s;
}
- void setR8G8B8 ( u32 argb )
+ void setA8R8G8B8(const u32 argb)
{
- r = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f );
- g = ( ( argb & 0x0000FF00 ) >> 8 ) * ( 1.f / 255.f );
- b = ( ( argb & 0x000000FF ) ) * ( 1.f / 255.f );
+ r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);
+ g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);
+ b = ((argb & 0x000000FF) ) * (1.f / 255.f);
+ a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
}
- void setColorf ( const video::SColorf & color )
+ void setColorf(const video::SColorf & color)
{
r = color.r;
g = color.g;
b = color.b;
+ a = color.a;
}
- void add (const sVec3& other)
+ void add_rgb(const sVec3Color& other)
{
r += other.r;
g += other.g;
b += other.b;
}
- void mulAdd(const sVec3& other, const f32 v)
+ void mad_rgb(const sVec3Color& other, const f32 v)
{
r += other.r * v;
g += other.g * v;
b += other.b * v;
}
- void mulAdd(const sVec3& v0, const sVec3& v1)
+ void mad_rgbv(const sVec3Color& v0, const sVec3Color& v1)
{
r += v0.r * v1.r;
g += v0.g * v1.g;
b += v0.b * v1.b;
}
- void saturate ( sVec4 &dest, u32 argb )
- {
- dest.x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f );
- dest.y = core::min_ ( r, 1.f );
- dest.z = core::min_ ( g, 1.f );
- dest.w = core::min_ ( b, 1.f );
- }
-
- // f = a * t + b * ( 1 - t )
- void interpolate(const sVec3& v0, const sVec3& v1, const f32 t)
- {
- r = v1.r + ( ( v0.r - v1.r ) * t );
- g = v1.g + ( ( v0.g - v1.g ) * t );
- b = v1.b + ( ( v0.b - v1.b ) * t );
- }
-
- sVec3 operator-(const sVec3& other) const
+ //sVec4 is a,r,g,b, alpha pass
+ void sat(sVec4 &dest, const u32 argb) const
{
- return sVec3(r - other.r, b - other.b, g - other.g);
+ dest.a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
+ dest.r = r <= 1.f ? r : 1.f;
+ dest.g = g <= 1.f ? g : 1.f;
+ dest.b = b <= 1.f ? b : 1.f;
}
- sVec3 operator+(const sVec3& other) const
+ void sat_xyz(sVec3Pack &dest, const sVec3Color& v1) const
{
- return sVec3(r + other.r, g + other.g, b + other.b);
+ f32 v;
+ v = r * v1.r; dest.x = v < 1.f ? v : 1.f;
+ v = g * v1.g; dest.y = v < 1.f ? v : 1.f;
+ v = b * v1.b; dest.z = v < 1.f ? v : 1.f;
}
- sVec3 operator*(const f32 s) const
+ void sat_xyz(sVec4 &dest, const sVec3Color& v1) const
{
- return sVec3(r * s , g * s, b * s);
+ f32 v;
+ dest.a = 1.f;
+ v = r * v1.r; dest.r = v < 1.f ? v : 1.f;
+ v = g * v1.g; dest.g = v < 1.f ? v : 1.f;
+ v = b * v1.b; dest.b = v < 1.f ? v : 1.f;
}
- sVec3 operator/(const f32 s) const
- {
- f32 inv = 1.f / s;
- return sVec3(r * inv , g * inv, b * inv);
- }
-
- sVec3 operator*(const sVec3 &other) const
- {
- return sVec3(r * other.r , b * other.b, g * other.g);
- }
-
- void operator+=(const sVec3& other)
- {
- r += other.r;
- g += other.g;
- b += other.b;
- }
-
- void setLength ( f32 len )
- {
- const f32 l = len * core::reciprocal_squareroot ( r * r + g * g + b * b );
-
- r *= l;
- g *= l;
- b *= l;
- }
};
-
-
-inline void sCompressedVec4::setVec4 ( const sVec4 & v )
-{
- argb = core::floor32_fast( v.x * 255.f ) << 24 |
- core::floor32_fast( v.y * 255.f ) << 16 |
- core::floor32_fast( v.z * 255.f ) << 8 |
- core::floor32_fast( v.w * 255.f );
-}
-
-
+//internal BurningShaderFlag for a Vertex
enum e4DVertexFlag
{
- VERTEX4D_INSIDE = 0x0000003F,
- VERTEX4D_CLIPMASK = 0x0000003F,
- VERTEX4D_PROJECTED = 0x00000100,
+ VERTEX4D_CLIPMASK = 0x0000003F,
+ VERTEX4D_CLIP_NEAR = 0x00000001,
+ VERTEX4D_CLIP_FAR = 0x00000002,
+ VERTEX4D_CLIP_LEFT = 0x00000004,
+ VERTEX4D_CLIP_RIGHT = 0x00000008,
+ VERTEX4D_CLIP_BOTTOM = 0x00000010,
+ VERTEX4D_CLIP_TOP = 0x00000020,
+ VERTEX4D_INSIDE = 0x0000003F,
+
+ VERTEX4D_PROJECTED = 0x00000100,
+ VERTEX4D_VAL_ZERO = 0x00000200,
+ VERTEX4D_VAL_ONE = 0x00000400,
VERTEX4D_FORMAT_MASK = 0xFFFF0000,
@@ -413,113 +380,291 @@ enum e4DVertexFlag
VERTEX4D_FORMAT_MASK_COLOR = 0x00F00000,
VERTEX4D_FORMAT_COLOR_1 = 0x00100000,
- VERTEX4D_FORMAT_COLOR_2 = 0x00200000,
+ VERTEX4D_FORMAT_COLOR_2_FOG = 0x00200000,
+ VERTEX4D_FORMAT_COLOR_3 = 0x00300000,
+ VERTEX4D_FORMAT_COLOR_4 = 0x00400000,
+
+ VERTEX4D_FORMAT_MASK_LIGHT = 0x0F000000,
+ VERTEX4D_FORMAT_LIGHT_1 = 0x01000000,
+ VERTEX4D_FORMAT_LIGHT_2 = 0x02000000,
- VERTEX4D_FORMAT_MASK_BUMP = 0x0F000000,
- VERTEX4D_FORMAT_BUMP_DOT3 = 0x01000000,
+ VERTEX4D_FORMAT_MASK_TANGENT = 0xF0000000,
+ VERTEX4D_FORMAT_BUMP_DOT3 = 0x10000000,
+ VERTEX4D_FORMAT_SPECULAR = 0x20000000,
};
-const u32 MATERIAL_MAX_COLORS = 1;
-const u32 BURNING_MATERIAL_MAX_TEXTURES = 2;
-const u32 BURNING_MATERIAL_MAX_TANGENT = 1;
+//! vertex layout
+enum e4DVertexType
+{
+ E4VT_STANDARD = 0, // EVT_STANDARD, video::S3DVertex.
+ E4VT_2TCOORDS = 1, // EVT_2TCOORDS, video::S3DVertex2TCoords.
+ E4VT_TANGENTS = 2, // EVT_TANGENTS, video::S3DVertexTangents
+ E4VT_REFLECTION_MAP = 3,
+ E4VT_SHADOW = 4, // float * 3
+ E4VT_NO_TEXTURE = 5, // runtime if texture missing
+ E4VT_LINE = 6,
+
+ E4VT_COUNT
+};
+
+enum e4DIndexType
+{
+ E4IT_16BIT = 1, // EIT_16BIT,
+ E4IT_32BIT = 2, // EIT_32BIT,
+ E4IT_NONE = 4, //
+};
+
+#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
+ #define BURNING_MATERIAL_MAX_TEXTURES 4
+ #define BURNING_MATERIAL_MAX_COLORS 4
+ #define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
+
+ //ensure handcrafted sizeof(s4DVertex)
+ #define sizeof_s4DVertex 128
+
+#else
+ #define BURNING_MATERIAL_MAX_TEXTURES 2
+ #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+ #define BURNING_MATERIAL_MAX_COLORS 1
+ #else
+ #define BURNING_MATERIAL_MAX_COLORS 0
+ #endif
+ #define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
+
+ //ensure handcrafted sizeof(s4DVertex)
+ #define sizeof_s4DVertex 64
+#endif
// dummy Vertex. used for calculation vertex memory size
struct s4DVertex_proxy
{
- u32 flag;
sVec4 Pos;
+#if BURNING_MATERIAL_MAX_TEXTURES > 0
sVec2 Tex[BURNING_MATERIAL_MAX_TEXTURES];
-
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
- sVec4 Color[MATERIAL_MAX_COLORS];
#endif
-
- sVec3 LightTangent[BURNING_MATERIAL_MAX_TANGENT];
+#if BURNING_MATERIAL_MAX_COLORS > 0
+ sVec4 Color[BURNING_MATERIAL_MAX_COLORS];
+#endif
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
+ sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
+#endif
+ u32 flag; // e4DVertexFlag
};
-#define SIZEOF_SVERTEX 64
-#define SIZEOF_SVERTEX_LOG2 6
/*!
Internal BurningVideo Vertex
*/
struct s4DVertex
{
- u32 flag;
-
sVec4 Pos;
+#if BURNING_MATERIAL_MAX_TEXTURES > 0
sVec2 Tex[ BURNING_MATERIAL_MAX_TEXTURES ];
-
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
- sVec4 Color[ MATERIAL_MAX_COLORS ];
+#endif
+#if BURNING_MATERIAL_MAX_COLORS > 0
+ sVec4 Color[ BURNING_MATERIAL_MAX_COLORS ];
+#endif
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
+ sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
#endif
- sVec3 LightTangent[BURNING_MATERIAL_MAX_TANGENT];
+ u32 flag; // e4DVertexFlag
- //u8 fill [ SIZEOF_SVERTEX - sizeof (s4DVertex_proxy) ];
+
+#if BURNING_MATERIAL_MAX_COLORS < 1 || BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
+ u8 __align [sizeof_s4DVertex - sizeof (s4DVertex_proxy) ];
+#endif
// f = a * t + b * ( 1 - t )
- void interpolate(const s4DVertex& b, const s4DVertex& a, const f32 t)
+ void interpolate(const s4DVertex& burning_restrict b, const s4DVertex& burning_restrict a, const ipoltype t)
{
- u32 i;
- u32 size;
-
Pos.interpolate ( a.Pos, b.Pos, t );
+#if 0
+ Tex[0].interpolate(a.Tex[0], b.Tex[0], t);
+ Tex[1].interpolate(a.Tex[1], b.Tex[1], t);
+ Color[0].interpolate(a.Color[0], b.Color[0], t);
+ LightTangent[0].interpolate(a.LightTangent[0], b.LightTangent[0], t);
+#endif
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
- size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;
+ size_t i;
+ size_t size;
+
+#if BURNING_MATERIAL_MAX_TEXTURES > 0
+ size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;
for ( i = 0; i!= size; ++i )
{
- Color[i].interpolate ( a.Color[i], b.Color[i], t );
+ Tex[i].interpolate ( a.Tex[i], b.Tex[i], t );
}
#endif
- size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;
+#if BURNING_MATERIAL_MAX_COLORS > 0
+ size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;
for ( i = 0; i!= size; ++i )
{
- Tex[i].interpolate ( a.Tex[i], b.Tex[i], t );
+ Color[i].interpolate ( a.Color[i], b.Color[i], t );
}
+#endif
- size = (flag & VERTEX4D_FORMAT_MASK_BUMP) >> 24;
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
+ size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24;
for ( i = 0; i!= size; ++i )
{
LightTangent[i].interpolate ( a.LightTangent[i], b.LightTangent[i], t );
}
+#endif
}
};
// ----------------- Vertex Cache ---------------------------
-struct SAlignedVertex
+// Buffer is used as pairs of S4DVertex (0 ... ndc, 1 .. dc and projected)
+typedef s4DVertex s4DVertexPair;
+#define sizeof_s4DVertexPairRel 2
+#define s4DVertex_ofs(index) ((index)*sizeof_s4DVertexPairRel)
+#define s4DVertex_proj(index) ((index)*sizeof_s4DVertexPairRel) + 1
+
+struct SAligned4DVertex
{
- SAlignedVertex ( u32 element, u32 aligned )
- : ElementSize ( element )
+ SAligned4DVertex()
+ :data(0),mem(0), ElementSize(0) {}
+
+ virtual ~SAligned4DVertex ()
{
- u32 byteSize = (ElementSize << SIZEOF_SVERTEX_LOG2 ) + aligned;
- mem = new u8 [ byteSize ];
- data = (s4DVertex*) mem;
+ if (mem)
+ {
+ delete[] mem;
+ mem = 0;
+ }
}
- virtual ~SAlignedVertex ()
+ void resize(size_t element)
{
- delete [] mem;
+ if (element > ElementSize)
+ {
+ if (mem) delete[] mem;
+ size_t byteSize = align_next(element * sizeof_s4DVertex, 4096);
+ mem = new u8[byteSize];
+ }
+ ElementSize = element;
+ data = (s4DVertex*)mem;
}
- s4DVertex *data;
- u8 *mem;
- u32 ElementSize;
+ s4DVertex* data; //align to 16 byte
+ u8* mem;
+ size_t ElementSize;
};
+//#define memcpy_s4DVertexPair(dst,src) memcpy(dst,src,sizeof_s4DVertex * 2)
+static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const void* burning_restrict src)
+{
+ //test alignment -> if already in aligned data
+#if 0
+ if (((size_t)dst & 0xC) | ((size_t)src & 0xC))
+ {
+ int g = 1;
+ }
+#endif
+
+#if defined(ENV64BIT) && (sizeof_s4DVertex * sizeof_s4DVertexPairRel == 128)
+ u64* burning_restrict dst64 = (u64*)dst;
+ const u64* burning_restrict src64 = (const u64*)src;
+
+ dst64[0] = src64[0];
+ dst64[1] = src64[1];
+ dst64[2] = src64[2];
+ dst64[3] = src64[3];
+ dst64[4] = src64[4];
+ dst64[5] = src64[5];
+ dst64[6] = src64[6];
+ dst64[7] = src64[7];
+
+ dst64[8] = src64[8];
+ dst64[9] = src64[9];
+ dst64[10] = src64[10];
+ dst64[11] = src64[11];
+ dst64[12] = src64[12];
+ dst64[13] = src64[13];
+ dst64[14] = src64[14];
+ dst64[15] = src64[15];
+
+#elif defined(ENV64BIT) && (sizeof_s4DVertex * sizeof_s4DVertexPairRel == 256)
+ u64* burning_restrict dst64 = (u64*)dst;
+ const u64* burning_restrict src64 = (const u64*)src;
+
+ dst64[0] = src64[0];
+ dst64[1] = src64[1];
+ dst64[2] = src64[2];
+ dst64[3] = src64[3];
+ dst64[4] = src64[4];
+ dst64[5] = src64[5];
+ dst64[6] = src64[6];
+ dst64[7] = src64[7];
+
+ dst64[8] = src64[8];
+ dst64[9] = src64[9];
+ dst64[10] = src64[10];
+ dst64[11] = src64[11];
+ dst64[12] = src64[12];
+ dst64[13] = src64[13];
+ dst64[14] = src64[14];
+ dst64[15] = src64[15];
+
+ dst64[16] = src64[16];
+ dst64[17] = src64[17];
+ dst64[18] = src64[18];
+ dst64[19] = src64[19];
+ dst64[20] = src64[20];
+ dst64[21] = src64[21];
+ dst64[22] = src64[22];
+ dst64[23] = src64[23];
+
+ dst64[24] = src64[24];
+ dst64[25] = src64[25];
+ dst64[26] = src64[26];
+ dst64[27] = src64[27];
+ dst64[28] = src64[28];
+ dst64[29] = src64[29];
+ dst64[30] = src64[30];
+ dst64[31] = src64[31];
-// hold info for different Vertex Types
+#else
+ u32* dst32 = (u32*)dst;
+ const u32* src32 = (const u32*)src;
+
+ size_t len = sizeof_s4DVertex * sizeof_s4DVertexPairRel;
+ while (len >= 32)
+ {
+ *dst32++ = *src32++;
+ *dst32++ = *src32++;
+ *dst32++ = *src32++;
+ *dst32++ = *src32++;
+ *dst32++ = *src32++;
+ *dst32++ = *src32++;
+ *dst32++ = *src32++;
+ *dst32++ = *src32++;
+ len -= 32;
+ }
+/*
+ while (len >= 4)
+ {
+ *dst32++ = *src32++;
+ len -= 4;
+ }
+*/
+#endif
+}
+
+
+//! hold info for different Vertex Types
struct SVSize
{
- u32 Format;
- u32 Pitch;
- u32 TexSize;
+ size_t Format; // e4DVertexFlag VERTEX4D_FORMAT_MASK_TEXTURE
+ size_t Pitch; // sizeof Vertex
+ size_t TexSize; // amount Textures
+ size_t TexCooSize; // sizeof TextureCoordinates
};
@@ -530,18 +675,24 @@ struct SCacheInfo
u32 hit;
};
-#define VERTEXCACHE_ELEMENT 16
+//must at least hold all possible (clipped) vertices of primitive.
+#define VERTEXCACHE_ELEMENT 16
#define VERTEXCACHE_MISS 0xFFFFFFFF
struct SVertexCache
{
- SVertexCache (): mem ( VERTEXCACHE_ELEMENT * 2, 128 ) {}
+ SVertexCache () {}
+ ~SVertexCache() {}
+
+ //VertexType
+ SVSize vSize[E4VT_COUNT];
SCacheInfo info[VERTEXCACHE_ELEMENT];
+ SCacheInfo info_temp[VERTEXCACHE_ELEMENT];
// Transformed and lite, clipping state
// + Clipped, Projected
- SAlignedVertex mem;
+ SAligned4DVertex mem;
// source
const void* vertices;
@@ -550,15 +701,15 @@ struct SVertexCache
const void* indices;
u32 indexCount;
u32 indicesIndex;
-
u32 indicesRun;
+ u32 indicesPitch;
// primitives consist of x vertices
- u32 primitivePitch;
+ size_t primitiveHasVertex;
- u32 vType; //E_VERTEX_TYPE
- u32 pType; //scene::E_PRIMITIVE_TYPE
- u32 iType; //E_INDEX_TYPE iType
+ e4DVertexType vType; //E_VERTEX_TYPE
+ scene::E_PRIMITIVE_TYPE pType; //scene::E_PRIMITIVE_TYPE
+ e4DIndexType iType; //E_INDEX_TYPE iType
};
@@ -579,10 +730,11 @@ REALINLINE void swapVertexPointer(const s4DVertex** v1, const s4DVertex** v2)
// internal scan convert
struct sScanConvertData
{
- u8 left; // major edge left/right
- u8 right; // !left
+ u32 left; // major edge left/right
+ u32 right; // !left
+ u32 _unused_pack[2];
- f32 invDeltaY[3]; // inverse edge delta y
+ f32 invDeltaY[4]; // inverse edge delta for screen space sorted triangle
f32 x[2]; // x coordinate
f32 slopeX[2]; // x slope along edges
@@ -595,20 +747,27 @@ struct sScanConvertData
f32 slopeZ[2]; // z slope along edges
#endif
- sVec4 c[MATERIAL_MAX_COLORS][2]; // color
- sVec4 slopeC[MATERIAL_MAX_COLORS][2]; // color slope along edges
+#if BURNING_MATERIAL_MAX_COLORS > 0
+ sVec4 c[BURNING_MATERIAL_MAX_COLORS][2]; // color
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS][2]; // color slope along edges
+#endif
+#if BURNING_MATERIAL_MAX_TEXTURES > 0
sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture slope along edges
+#endif
- sVec3 l[BURNING_MATERIAL_MAX_TANGENT][2]; // Light Tangent
- sVec3 slopeL[BURNING_MATERIAL_MAX_TEXTURES][2]; // tanget slope along edges
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
+ sVec3Pack_unpack l[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2]; // Light Tangent
+ sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2]; // tanget slope along edges
+#endif
};
// passed to scan Line
struct sScanLineData
{
s32 y; // y position of scanline
+ u32 _unused_pack[1];
f32 x[2]; // x start, x end of scanline
#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )
@@ -617,12 +776,19 @@ struct sScanLineData
f32 z[2]; // z start, z end of scanline
#endif
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
- sVec4 c[MATERIAL_MAX_COLORS][2]; // color start, color end of scanline
+ u32 _unused_pack_1[2];
+
+#if BURNING_MATERIAL_MAX_COLORS > 0
+ sVec4 c[BURNING_MATERIAL_MAX_COLORS][2]; // color start, color end of scanline
#endif
+#if BURNING_MATERIAL_MAX_TEXTURES > 0
sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture start, texture end of scanline
- sVec3 l[BURNING_MATERIAL_MAX_TANGENT][2]; // Light Tangent start, end
+#endif
+
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
+ sVec3Pack_unpack l[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2]; // Light Tangent start, end
+#endif
};
// passed to pixel Shader
@@ -640,49 +806,54 @@ struct sPixelShaderData
/*
load a color value
*/
-inline void getTexel_plain2 ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sVec4 &v
- )
+REALINLINE void getTexel_plain2 ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )
{
- r = tofix(v.y, FIX_POINT_F32_MUL);
- g = tofix(v.z, FIX_POINT_F32_MUL);
- b = tofix(v.w, FIX_POINT_F32_MUL);
+ r = tofix(v.r, FIX_POINT_F32_MUL);
+ g = tofix(v.g, FIX_POINT_F32_MUL);
+ b = tofix(v.b, FIX_POINT_F32_MUL);
}
+#if 0
/*
load a color value
*/
-inline void getSample_color ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sVec4 &v
- )
+REALINLINE void getSample_color ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const sVec4 &v )
{
- a = tofix(v.x, FIX_POINT_F32_MUL);
- r = tofix ( v.y, COLOR_MAX * FIX_POINT_F32_MUL);
- g = tofix ( v.z, COLOR_MAX * FIX_POINT_F32_MUL);
- b = tofix ( v.w, COLOR_MAX * FIX_POINT_F32_MUL);
+ a = tofix ( v.a, FIX_POINT_F32_MUL);
+ r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL);
+ g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);
+ b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL);
}
/*
load a color value
*/
-inline void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )
+REALINLINE void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )
{
- r = tofix ( v.y, COLOR_MAX * FIX_POINT_F32_MUL);
- g = tofix ( v.z, COLOR_MAX * FIX_POINT_F32_MUL);
- b = tofix ( v.w, COLOR_MAX * FIX_POINT_F32_MUL);
+ r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL);
+ g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);
+ b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL);
}
+#endif
/*
- load a color value
+ load a color value. mulby controls [0;1] or [0;ColorMax]
+ aka getSample_color
*/
-inline void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sVec4 &v, const f32 mulby )
+REALINLINE void vec4_to_fix(tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby )
{
- r = tofix ( v.y, mulby);
- g = tofix ( v.z, mulby);
- b = tofix ( v.w, mulby);
+ r = tofix(v.r, mulby);
+ g = tofix(v.g, mulby);
+ b = tofix(v.b, mulby);
}
+REALINLINE void vec4_to_fix(tFixPoint &a,tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby)
+{
+ a = tofix(v.a, mulby);
+ r = tofix(v.r, mulby);
+ g = tofix(v.g, mulby);
+ b = tofix(v.b, mulby);
+}
}
diff --git a/source/Irrlicht/SoftwareDriver2_compile_config.h b/source/Irrlicht/SoftwareDriver2_compile_config.h
index a471318..725ba1a 100644
--- a/source/Irrlicht/SoftwareDriver2_compile_config.h
+++ b/source/Irrlicht/SoftwareDriver2_compile_config.h
@@ -7,10 +7,28 @@
#include "IrrCompileConfig.h"
-
// Generic Render Flags for burning's video rasterizer
// defined now in irrlicht compile config
+#if defined(PATCH_SUPERTUX_8_0_1)
+ #undef BURNINGVIDEO_RENDERER_BEAUTIFUL
+
+ //#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+ #define SOFTWARE_DRIVER_2_SUBTEXEL
+ //#define SOFTWARE_DRIVER_2_BILINEAR
+ #define SOFTWARE_DRIVER_2_LIGHTING
+ #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+ #define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
+ #define SOFTWARE_DRIVER_2_32BIT
+ #define SOFTWARE_DRIVER_2_MIPMAPPING
+ #define SOFTWARE_DRIVER_2_USE_WBUFFER
+ #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
+ #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
+ #define SOFTWARE_DRIVER_2_CLIPPING
+ #define SOFTWARE_DRIVER_2_2D_AS_2D
+#endif
+
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
@@ -18,11 +36,15 @@
#define SOFTWARE_DRIVER_2_BILINEAR
#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+ #define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
+ #define SOFTWARE_DRIVER_2_CLIPPING
+ #define SOFTWARE_DRIVER_2_2D_AS_3D
#endif
//! Set Flags for Windows Mobile
@@ -36,7 +58,10 @@
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
- #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128
+ #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 64
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
+ //#define SOFTWARE_DRIVER_2_CLIPPING
+ #define SOFTWARE_DRIVER_2_2D_AS_2D
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
@@ -44,25 +69,34 @@
#define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING
- //#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
- #define SOFTWARE_DRIVER_2_32BIT
+ #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+ //#define SOFTWARE_DRIVER_2_32BIT
+ #define SOFTWARE_DRIVER_2_16BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
- #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0
+ #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
+ #define SOFTWARE_DRIVER_2_CLIPPING
+ #define SOFTWARE_DRIVER_2_2D_AS_2D
#endif
#ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST
#define BURNINGVIDEO_RENDERER_FAST
//#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
- #define SOFTWARE_DRIVER_2_SUBTEXEL
+ //#define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING
- //#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+ #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_32BIT
- #define SOFTWARE_DRIVER_2_MIPMAPPING
- #define SOFTWARE_DRIVER_2_USE_WBUFFER
- #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0
+ #define SOFTWARE_DRIVER_2_16BIT
+ //#define SOFTWARE_DRIVER_2_MIPMAPPING
+ //#define SOFTWARE_DRIVER_2_USE_WBUFFER
+ //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
+ #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
+ //#define SOFTWARE_DRIVER_2_CLIPPING
+ #define SOFTWARE_DRIVER_2_2D_AS_2D
#endif
// Derivate flags
@@ -74,24 +108,24 @@
#define BURNINGSHADER_COLOR_FORMAT ECF_A1R5G5B5
#endif
-// mip mapping
+// mip mapping - precalculated texture filter
#if defined ( SOFTWARE_DRIVER_2_MIPMAPPING )
#if defined( BURNINGVIDEO_RENDERER_BEAUTIFUL )
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16
- #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#elif defined ( BURNINGVIDEO_RENDERER_CE )
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
- #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#else
- #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8
- #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#endif
#else
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1
- #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#endif
-#define SOFTWARE_DRIVER_2_MIPMAPPING_SCALE (16/SOFTWARE_DRIVER_2_MIPMAPPING_MAX)
+
#ifndef REALINLINE
#ifdef _MSC_VER
@@ -101,4 +135,155 @@
#endif
#endif
+
+// null check necessary (burningvideo only)
+#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f)
+static inline float reciprocal_zero2(float x) { return x != 0.f ? 1.f / x : 0.f; }
+#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)
+
+#define fill_convention_left(x) (s32) ceilf(x)
+#define fill_convention_right(x) ((s32) ceilf(x))-1
+#define fill_convention_none(x) (s32) (x)
+//#define fill_convention_left(x) 65536 - int(65536.0f - x)
+//#define fill_convention_right(x) 65535 - int(65536.0f - x)
+
+
+//Check coordinates are in render target/window space
+//#define SOFTWARE_DRIVER_2_DO_CLIPCHECK
+#if defined (SOFTWARE_DRIVER_2_DO_CLIPCHECK) && defined(_WIN32)
+#define SOFTWARE_DRIVER_2_CLIPCHECK if( xStart < 0 || xStart + dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
+#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()
+#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE if( aposx < 0 || aposx >= (s32)RenderTarget->getDimension().Width || aposy < 0 || aposy >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
+
+inline float reciprocal_zero_no(const float x)
+{
+ if (x*x <= 0.00001f) __debugbreak();
+ return 1.f / x;
+}
+#else
+#define SOFTWARE_DRIVER_2_CLIPCHECK
+#define SOFTWARE_DRIVER_2_CLIPCHECK_REF
+#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE
+
+#define reciprocal_zero_no(x) 1.f/x
#endif
+
+//!scanline renderer emulate line
+enum edge_test_flag
+{
+ edge_test_pass = 1, //! not wireframe
+ edge_test_left = 0,
+ edge_test_first_line = 2,
+ edge_test_point = 4
+};
+//if any edge test flag is set result=1 else 0. ( pass height test for degenerate triangle )
+#define reciprocal_edge(x) ((x) != 0.f ? 1.f / (x):(~EdgeTestPass)&1)
+
+//! normalize from fixed point Color Max to fixed point [0;1]
+#define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2
+
+//! from 1 bit to 5 bit
+#ifdef SOFTWARE_DRIVER_2_32BIT
+ #define fix_alpha_color_max(x)
+#else
+ #define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1
+#endif
+
+// Check windows
+#if _WIN32 || _WIN64
+#if _WIN64
+ #define ENV64BIT
+#else
+ #define ENV32BIT
+#endif
+#endif
+
+// Check GCC
+#if __GNUC__
+#if __x86_64__ || __ppc64__
+ #define ENV64BIT
+#else
+ #define ENV32BIT
+#endif
+#endif
+
+#if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL)
+ typedef float ipoltype;
+#else
+ typedef float ipoltype;
+#endif
+
+#define ipol_lower_equal_0(n) ((n) <= (ipoltype)0.0)
+#define ipol_greater_0(n) ((n) > (ipoltype)0.0)
+
+#if (_MSC_VER > 1700 )
+ #define burning_restrict __restrict
+#else
+ #define burning_restrict
+#endif
+
+/*
+ if (condition) state |= mask; else state &= ~mask;
+*/
+static inline void burning_setbit(size_t &state, int condition, size_t mask)
+{
+ if (condition) state |= mask;
+ else state &= ~mask;
+}
+
+/*
+ if (condition) state |= m; else state &= ~m;
+*/
+REALINLINE void burning_setbit32(unsigned int &state, int condition, const unsigned int mask)
+{
+ // 0, or any positive to mask
+ //s32 conmask = -condition >> 31;
+ state ^= ((-condition >> 31) ^ state) & mask;
+}
+
+#define burning_stringify(s) #s
+#define burning_create_indirect(s) create_##s
+#define burning_create(s) burning_create_indirect(s)
+
+
+#if defined(PATCH_SUPERTUX_8_0_1)
+#define getData lock
+#define snprintf_irr sprintf_s
+
+#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
+#ifdef SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
+#define BURNING_MATERIAL_MAX_COLORS 2
+#else
+#define BURNING_MATERIAL_MAX_COLORS 1
+#endif
+#else
+#define BURNING_MATERIAL_MAX_COLORS 0
+#endif
+
+#ifndef _IRR_OVERRIDE_
+#define _IRR_OVERRIDE_ /**/
+#endif
+
+#define fix_to_color fix_to_sample
+#define fix4_to_color fix4_to_sample
+#define vec4_to_fix getSample_color
+#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
+
+namespace irr {
+
+ REALINLINE void memcpy32_small(void * dest, const void *source, size_t bytesize)
+ {
+ size_t c = bytesize >> 2;
+
+ do
+ {
+ ((unsigned int *)dest)[c - 1] = ((unsigned int *)source)[c - 1];
+ } while (--c);
+
+ }
+
+} // namespace irr
+#endif // #if defined(PATCH_SUPERTUX_8_0_1)
+
+
+#endif // __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__
diff --git a/source/Irrlicht/SoftwareDriver2_helper.h b/source/Irrlicht/SoftwareDriver2_helper.h
index 01e2f4f..59a91b8 100644
--- a/source/Irrlicht/SoftwareDriver2_helper.h
+++ b/source/Irrlicht/SoftwareDriver2_helper.h
@@ -24,40 +24,42 @@ namespace irr
#ifdef SOFTWARE_DRIVER_2_32BIT
typedef u32 tVideoSample;
+ typedef u32 tStencilSample;
#define MASK_A 0xFF000000
#define MASK_R 0x00FF0000
#define MASK_G 0x0000FF00
#define MASK_B 0x000000FF
- #define SHIFT_A 24
- #define SHIFT_R 16
- #define SHIFT_G 8
- #define SHIFT_B 0
+ #define SHIFT_A (unsigned)24
+ #define SHIFT_R (unsigned)16
+ #define SHIFT_G (unsigned)8
+ #define SHIFT_B (unsigned)0
#define COLOR_MAX 0xFF
#define COLOR_MAX_LOG2 8
#define COLOR_BRIGHT_WHITE 0xFFFFFFFF
- #define VIDEO_SAMPLE_GRANULARITY 2
+ #define VIDEO_SAMPLE_GRANULARITY (unsigned)2
#else
typedef u16 tVideoSample;
+ typedef u8 tStencilSample;
#define MASK_A 0x8000
#define MASK_R 0x7C00
#define MASK_G 0x03E0
#define MASK_B 0x001F
- #define SHIFT_A 15
- #define SHIFT_R 10
- #define SHIFT_G 5
- #define SHIFT_B 0
+ #define SHIFT_A (unsigned)15
+ #define SHIFT_R (unsigned)10
+ #define SHIFT_G (unsigned)5
+ #define SHIFT_B (unsigned)0
#define COLOR_MAX 0x1F
#define COLOR_MAX_LOG2 5
#define COLOR_BRIGHT_WHITE 0xFFFF
- #define VIDEO_SAMPLE_GRANULARITY 1
+ #define VIDEO_SAMPLE_GRANULARITY (unsigned)1
#endif
@@ -65,14 +67,16 @@ namespace irr
// ----------------------- Generic ----------------------------------
+//! align_next - align to next upper 2^n
+#define align_next(num,to) (((num) + (to-1)) & (~(to-1)))
-//! a more useful memset for pixel
+//! a more useful memset for pixel. dest must be aligned at least to 4 byte
// (standard memset only works with 8-bit values)
-inline void memset32(void * dest, const u32 value, u32 bytesize)
+inline void memset32(void * dest, const u32 value, size_t bytesize)
{
u32 * d = (u32*) dest;
- u32 i;
+ size_t i;
// loops unrolled to reduce the number of increments by factor ~8.
i = bytesize >> (2 + 3);
@@ -101,13 +105,13 @@ inline void memset32(void * dest, const u32 value, u32 bytesize)
}
}
-//! a more useful memset for pixel
+//! a more useful memset for pixel. dest must be aligned at least to 2 byte
// (standard memset only works with 8-bit values)
-inline void memset16(void * dest, const u16 value, u32 bytesize)
+inline void memset16(void * dest, const u16 value, size_t bytesize)
{
u16 * d = (u16*) dest;
- u32 i;
+ size_t i;
// loops unrolled to reduce the number of increments by factor ~8.
i = bytesize >> (1 + 3);
@@ -136,35 +140,52 @@ inline void memset16(void * dest, const u16 value, u32 bytesize)
}
}
-/*
- use biased loop counter
- --> 0 byte copy is forbidden
-*/
-REALINLINE void memcpy32_small ( void * dest, const void *source, u32 bytesize )
-{
- u32 c = bytesize >> 2;
- do
- {
- ((u32*) dest ) [ c-1 ] = ((u32*) source) [ c-1 ];
- } while ( --c );
+// byte-align structures
+#include "irrpack.h"
-}
+//IEEE Standard for Floating - Point Arithmetic(IEEE 754)
+typedef union {
+ float f;
+ unsigned int u;
+ struct { unsigned int frac:23; unsigned exp:8; unsigned int sign:1; } fields;
+ struct { unsigned int frac_exp:31; } abs;
+} ieee754 PACK_STRUCT;
+// Default alignment
+#include "irrunpack.h"
+// 0.5f as integer
+#define ieee754_zero_dot_5 0x3f000000
+#define ieee754_one 0x3f800000
+#define ieee754_two 0x40000000
-// integer log2 of a float ieee 754. TODO: non ieee floating point
+#if 0
+// integer log2 of a float ieee 754. [not used anymore]
static inline s32 s32_log2_f32( f32 f)
{
- u32 x = IR ( f );
- return ((x & 0x7F800000) >> 23) - 127;
+ //u32 x = IR ( f ); return ((x & 0x7F800000) >> 23) - 127;
+ ieee754 _log2;
+ _log2.f = f;
+ return _log2.fields.exp ? _log2.fields.exp - 127 : 10000000; /*denormal very high number*/
}
+#endif
-static inline s32 s32_log2_s32(u32 x)
+// integer log2 of an integer. returning 0 as denormal
+static inline s32 s32_log2_s32(u32 in)
{
- return s32_log2_f32( (f32) x);
+ s32 ret = 0;
+ while (in > 1)
+ {
+ in >>= 1;
+ ret++;
+ }
+ return ret;
+ //return s32_log2_f32( (f32) x);
+ //ieee754 _log2;_log2.f = (f32) in; return _log2.fields.exp - 127;
}
+#if 0
static inline s32 s32_abs(s32 x)
{
s32 b = x >> 31;
@@ -177,13 +198,14 @@ REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b )
{
return ( mask & ( a ^ b ) ) ^ b;
}
+#endif
// ------------------ Video---------------------------------------
/*!
Pixel = dest * ( 1 - alpha ) + source * alpha
alpha [0;256]
*/
-REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, u32 alpha )
+REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, const u32 alpha )
{
u32 srcRB = c1 & 0x00FF00FF;
u32 srcXG = c1 & 0x0000FF00;
@@ -213,7 +235,7 @@ REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, u32 alpha )
Pixel = dest * ( 1 - alpha ) + source * alpha
alpha [0;32]
*/
-inline u16 PixelBlend16 ( const u16 c2, const u32 c1, const u16 alpha )
+inline u16 PixelBlend16 ( const u16 c2, const u16 c1, const u16 alpha )
{
const u16 srcRB = c1 & 0x7C1F;
const u16 srcXG = c1 & 0x03E0;
@@ -386,97 +408,45 @@ inline u32 PixelBlend32 ( const u32 c2, const u32 c1 )
return (c1 & 0xFF000000) | rb | xg;
}
-/*!
- Pixel =>
- color = sourceAlpha > 0 ? source, else dest
- alpha = max(destAlpha, sourceAlpha)
-*/
-inline u16 PixelCombine16 ( const u16 c2, const u16 c1 )
-{
- if ( video::getAlpha(c1) > 0 )
- return c1;
- else
- return c2;
-}
-
-/*!
- Pixel =>
- color = dest * ( 1 - SourceAlpha ) + source * SourceAlpha,
- alpha = destAlpha * ( 1 - SourceAlpha ) + sourceAlpha
-
- where "1" means "full scale" (255)
-*/
-inline u32 PixelCombine32 ( const u32 c2, const u32 c1 )
-{
- // alpha test
- u32 alpha = c1 & 0xFF000000;
-
- if ( 0 == alpha )
- return c2;
- if ( 0xFF000000 == alpha )
- {
- return c1;
- }
-
- alpha >>= 24;
-
- // add highbit alpha, if ( alpha > 127 ) alpha += 1;
- // stretches [0;255] to [0;256] to avoid division by 255. use division 256 == shr 8
- alpha += ( alpha >> 7);
-
- u32 srcRB = c1 & 0x00FF00FF;
- u32 srcXG = c1 & 0x0000FF00;
-
- u32 dstRB = c2 & 0x00FF00FF;
- u32 dstXG = c2 & 0x0000FF00;
-
-
- u32 rb = srcRB - dstRB;
- u32 xg = srcXG - dstXG;
-
- rb *= alpha;
- xg *= alpha;
- rb >>= 8;
- xg >>= 8;
-
- rb += dstRB;
- xg += dstXG;
-
- rb &= 0x00FF00FF;
- xg &= 0x0000FF00;
-
- u32 sa = c1 >> 24;
- u32 da = c2 >> 24;
- u32 blendAlpha_fix8 = (sa*256 + da*(256-alpha))>>8;
- return blendAlpha_fix8 << 24 | rb | xg;
-}
-
// ------------------ Fix Point ----------------------------------
+#if defined(ENV64BIT)
typedef s32 tFixPoint;
typedef u32 tFixPointu;
+#else
+typedef s32 tFixPoint;
+typedef u32 tFixPointu;
+#endif
-// Fix Point 12
+// Fix Point 12 (overflow on s32)
#if 0
#define FIX_POINT_PRE 12
#define FIX_POINT_FRACT_MASK 0xFFF
- #define FIX_POINT_SIGNED_MASK 0xFFFFF000
#define FIX_POINT_UNSIGNED_MASK 0x7FFFF000
#define FIX_POINT_ONE 0x1000
#define FIX_POINT_ZERO_DOT_FIVE 0x0800
#define FIX_POINT_F32_MUL 4096.f
#endif
+// Fix Point 11 (overflow on s32)
+#if 0
+ #define FIX_POINT_PRE 11
+ #define FIX_POINT_FRACT_MASK 0x7FF
+ #define FIX_POINT_UNSIGNED_MASK 0xFFFFF800
+ #define FIX_POINT_ONE 0x800
+ #define FIX_POINT_ZERO_DOT_FIVE 0x400
+ #define FIX_POINT_F32_MUL 2048.f
+#endif
+
// Fix Point 10
#if 1
#define FIX_POINT_PRE 10
- #define FIX_POINT_FRACT_MASK 0x3FF
- #define FIX_POINT_SIGNED_MASK 0xFFFFFC00
+ #define FIX_POINT_FRACT_MASK 0x000003FF
#define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00
- #define FIX_POINT_ONE 0x400
- #define FIX_POINT_ZERO_DOT_FIVE 0x200
+ #define FIX_POINT_ONE 0x00000400
+ #define FIX_POINT_ZERO_DOT_FIVE 0x00000200
#define FIX_POINT_F32_MUL 1024.f
#endif
@@ -484,7 +454,6 @@ typedef u32 tFixPointu;
#if 0
#define FIX_POINT_PRE 9
#define FIX_POINT_FRACT_MASK 0x1FF
- #define FIX_POINT_SIGNED_MASK 0xFFFFFE00
#define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00
#define FIX_POINT_ONE 0x200
#define FIX_POINT_ZERO_DOT_FIVE 0x100
@@ -495,7 +464,6 @@ typedef u32 tFixPointu;
#if 0
#define FIX_POINT_PRE 7
#define FIX_POINT_FRACT_MASK 0x7F
- #define FIX_POINT_SIGNED_MASK 0xFFFFFF80
#define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80
#define FIX_POINT_ONE 0x80
#define FIX_POINT_ZERO_DOT_FIVE 0x40
@@ -503,7 +471,20 @@ typedef u32 tFixPointu;
#endif
#define FIXPOINT_COLOR_MAX ( COLOR_MAX << FIX_POINT_PRE )
-#define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )
+
+#if FIX_POINT_PRE == 10 && COLOR_MAX == 255
+ #define FIX_POINT_HALF_COLOR 0x1FE00
+ #define FIX_POINT_COLOR_ERROR 4
+#elif FIX_POINT_PRE == 12 && COLOR_MAX == 255
+ #define FIX_POINT_HALF_COLOR 0x7F800
+ #define FIX_POINT_COLOR_ERROR 16
+#elif FIX_POINT_PRE == 10 && COLOR_MAX == 31
+ #define FIX_POINT_HALF_COLOR 0x3E00
+ #define FIX_POINT_COLOR_ERROR 32
+#else
+ #define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )
+ #define FIX_POINT_COLOR_ERROR (1<<(FIX_POINT_PRE-COLOR_MAX_LOG2))
+#endif
/*
@@ -521,12 +502,13 @@ inline tFixPointu u32_to_fixPoint (const u32 x)
inline u32 fixPointu_to_u32 (const tFixPointu x)
{
- return x >> FIX_POINT_PRE;
+ return (u32)(x >> FIX_POINT_PRE);
}
// 1/x * FIX_POINT
#define fix_inverse32(x) (FIX_POINT_F32_MUL / (x))
+#define fix_inverse32_color(x) ((FIX_POINT_F32_MUL*COLOR_MAX) / (x))
/*
@@ -535,38 +517,50 @@ inline u32 fixPointu_to_u32 (const tFixPointu x)
hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different
others should use their favourite assembler..
*/
+#if 0
static inline int f_round2(f32 f)
{
f += (3<<22);
return IR(f) - 0x4b400000;
}
+#endif
/*
convert f32 to Fix Point.
multiply is needed anyway, so scale mulby
*/
+/*
REALINLINE tFixPoint tofix0 (const f32 x, const f32 mulby = FIX_POINT_F32_MUL )
{
return (tFixPoint) (x * mulby);
}
+*/
#define tofix(x,y) (tFixPoint)(x * y)
+
/*
Fix Point , Fix Point Multiply
*/
+/*
REALINLINE tFixPointu imulFixu(const tFixPointu x, const tFixPointu y)
{
return (x * y) >> (tFixPointu) FIX_POINT_PRE;
}
+*/
+#define imulFixu(x,y) (((x) * (y)) >> (tFixPointu) FIX_POINT_PRE)
+
/*
Fix Point , Fix Point Multiply
*/
REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y)
{
- return ( x * y) >> ( FIX_POINT_PRE );
+ return (x * y) >> FIX_POINT_PRE;
}
+#define imulFix_simple(x,y) ((x*y)>>FIX_POINT_PRE)
+
+#if 0
/*
Fix Point , Fix Point Multiply x * y * 2
*/
@@ -574,14 +568,18 @@ REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y)
{
return ( x * y) >> ( FIX_POINT_PRE -1 );
}
-
+#endif
/*
- Multiply x * y * 1
+ Multiply x * y * 1 FIXPOINT_COLOR_MAX
*/
REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y)
{
- return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 4 );
+#ifdef SOFTWARE_DRIVER_2_32BIT
+ return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4);
+#else
+ return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5);
+#endif
}
/*
@@ -593,26 +591,42 @@ REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y)
}
/*
- Multiply x * y * 4
+ Multiply x * y * 4 clamp
*/
+
REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)
{
#ifdef SOFTWARE_DRIVER_2_32BIT
- return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 );
+ register tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2);
#else
- return ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) );
+ register tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3);
#endif
+ register tFixPoint mask = (a - FIXPOINT_COLOR_MAX) >> 31;
+ return (a & mask) | (FIXPOINT_COLOR_MAX & ~mask);
}
+
+#if 0
+#define imulFix_tex1(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 4))
+#define imulFix_tex2(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 3))
+
+#ifdef SOFTWARE_DRIVER_2_32BIT
+#define imulFix_tex4(x,y) ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 )
+#else
+#define imulFix_tex4(x,y) ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) )
+#endif
+#endif
+
/*!
- clamp FixPoint to maxcolor in FixPoint, min(a,31)
+ clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX)
*/
REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a)
{
- tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;
+ register tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;
return (a & c) | ( FIXPOINT_COLOR_MAX & ~c);
}
+
/*!
clamp FixPoint to 0 in FixPoint, max(a,0)
*/
@@ -630,22 +644,24 @@ REALINLINE tFixPoint saturateFix ( const tFixPoint a)
// rount fixpoint to int
inline s32 roundFix ( const tFixPoint x )
{
- return ( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE;
+ return (s32)(( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE);
}
// x in [0;1[
+#if 0
inline s32 f32_to_23Bits(const f32 x)
{
f32 y = x + 1.f;
return IR(y) & 0x7FFFFF; // last 23 bits
}
+#endif
/*!
- return VideoSample from fixpoint
+ fixpoint in [0..Fixpoint_color] to VideoSample xrgb
*/
-REALINLINE tVideoSample fix_to_color ( const tFixPoint r, const tFixPoint g, const tFixPoint b )
+REALINLINE tVideoSample fix_to_sample ( const tFixPoint r, const tFixPoint g, const tFixPoint b )
{
return ( FIXPOINT_COLOR_MAX & FIXPOINT_COLOR_MAX) << ( SHIFT_A - FIX_POINT_PRE ) |
( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |
@@ -655,9 +671,11 @@ REALINLINE tVideoSample fix_to_color ( const tFixPoint r, const tFixPoint g, con
/*!
- return VideoSample from fixpoint
+ fixpoint to VideoSample argb
+ a in [0;1]
+ rgb in [0;255] colormax
*/
-REALINLINE tVideoSample fix4_to_color ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )
+REALINLINE tVideoSample fix4_to_sample ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )
{
return ( a & (FIX_POINT_FRACT_MASK - 1 )) << ( SHIFT_A - 1 ) |
( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |
@@ -666,7 +684,7 @@ REALINLINE tVideoSample fix4_to_color ( const tFixPoint a, const tFixPoint r, co
}
/*!
- return fixpoint from VideoSample granularity COLOR_MAX
+ return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX
*/
inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
{
@@ -676,7 +694,7 @@ inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVide
}
/*!
- return fixpoint from VideoSample granularity COLOR_MAX
+ return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX
*/
inline void color_to_fix ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
{
@@ -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 );
(tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );
(tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );
+
+ //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0
+ r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+ g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+ b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
}
/*!
@@ -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 );
(tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );
(tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );
+
+ //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0
+ a += (a & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+ r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+ g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+ b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+
+}
+
+/*!
+ return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX
+*/
+inline void color_to_fix(tFixPoint c[4], const tVideoSample t00)
+{
+ c[0] = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);
+ c[1] = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
+ c[2] = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
+ c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
+}
+
+/*!
+ return fixpoint from VideoSample granularity 0..FIX_POINT_ONE
+*/
+inline void color_to_fix1(tFixPoint c[4], const tVideoSample t00)
+{
+ c[0] = (t00 & MASK_A) >> (SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE);
+ c[1] = (t00 & MASK_R) >> (SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE);
+ c[2] = (t00 & MASK_G) >> (SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE);
+ c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - COLOR_MAX_LOG2);
+
+ //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0
+ c[0] += (c[0] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+ c[1] += (c[1] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+ c[2] += (c[2] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+ c[3] += (c[3] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
+
}
-// ----- FP24 ---- floating point z-buffer
+//! ----- FP24 1.23 fix point z-buffer
#if 1
typedef f32 fp24;
@@ -751,22 +810,23 @@ struct fp24
struct sInternalTexture
{
- u32 textureXMask;
- u32 textureYMask;
+ //power-of-two
+ void* data; //tVideoSample* Texture->lock(miplevel)
+ size_t textureXMask;
+ size_t textureYMask;
- u32 pitchlog2;
- void *data;
+ size_t pitchlog2;
video::CSoftwareTexture2 *Texture;
- s32 lodLevel;
+ s32 lodFactor; // magnify/minify
};
// get video sample plain
-inline tVideoSample getTexel_plain ( const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty )
+static inline tVideoSample getTexel_plain ( const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty )
{
- u32 ofs;
+ register size_t ofs;
ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
@@ -777,16 +837,16 @@ inline tVideoSample getTexel_plain ( const sInternalTexture * t, const tFixPoint
// get video sample to fix
inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
+ const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty
)
{
- u32 ofs;
+ register size_t ofs;
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
+ ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
+ ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
// texel
- tVideoSample t00;
+ register tVideoSample t00;
t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
@@ -795,165 +855,247 @@ inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
}
-// get video sample to fixpoint
-REALINLINE void getTexel_fix ( tFixPoint &a,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty)
+// get video sample to fixpoint colormax
+inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
+ const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty
+)
{
- u32 ofs;
+ register size_t ofs;
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
+ ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
+ ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
// texel
- tVideoSample t00;
- t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
+ register tVideoSample t00;
+ t00 = *((tVideoSample*)((u8*)t->data + ofs));
- a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);
-}
+ a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);
+ r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
+ g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
+ b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
+}
-inline void getSample_texture_dither ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty,
- const u32 x, const u32 y
- )
+#if 0
+// get video sample to fixpoint
+static REALINLINE void getTexel_fix ( tFixPoint &a,
+ const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty)
{
- static const tFixPointu dithermask[] =
- {
- 0x00,0x80,0x20,0xa0,
- 0xc0,0x40,0xe0,0x60,
- 0x30,0xb0,0x10,0x90,
- 0xf0,0x70,0xd0,0x50
- };
-
- const u32 index = (y & 3 ) << 2 | (x & 3);
-
- const tFixPointu _ntx = (tx + dithermask [ index ] ) & t->textureXMask;
- const tFixPointu _nty = (ty + dithermask [ index ] ) & t->textureYMask;
+ size_t ofs;
- u32 ofs;
- ofs = ( ( _nty ) >> FIX_POINT_PRE ) << t->pitchlog2;
- ofs |= ( _ntx ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
+ ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
+ ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
// texel
- const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
-
- (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
- (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
- (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
+ tVideoSample t00;
+ t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
+ a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);
}
+#endif
/*
load a sample from internal texture at position tx,ty to fixpoint
*/
-#ifndef SOFTWARE_DRIVER_2_BILINEAR
-
-// get Sample linear == getSample_fixpoint
+#if defined(SOFTWARE_DRIVER_2_BILINEAR)
-inline void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
- )
+#if 0
+// texture2D in fixpoint color range bilinear
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,
+ const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty
+)
{
- u32 ofs;
-
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
-
- // texel
- const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
+#if 0
+ if (t->lodFactor > 0)
+ {
+ register size_t ofs;
- (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
- (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
- (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
-}
+ ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
+ ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
-inline void getSample_texture ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
- )
-{
- u32 ofs;
+ // texel
+ tVideoSample t00;
+ t00 = *((tVideoSample*)((u8*)t->data + ofs));
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
+ r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
+ g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
+ b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
+ return;
+ }
+#endif
- // texel
- const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
+ tFixPointu r00, g00, b00;
+ tFixPointu r01, g01, b01;
+ tFixPointu r10, g10, b10;
+ tFixPointu r11, g11, b11;
+
+ size_t o0, o1, o2, o3;
+ register tVideoSample t00;
+
+ //wraps positive (ignoring negative)
+ o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
+ o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
+ o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
+ o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
+
+ t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2)));
+ r00 = (t00 & MASK_R) >> SHIFT_R;
+ g00 = (t00 & MASK_G) >> SHIFT_G;
+ b00 = (t00 & MASK_B);
+
+ t00 = *((tVideoSample*)((u8*)t->data + (o0 + o3)));
+ r10 = (t00 & MASK_R) >> SHIFT_R;
+ g10 = (t00 & MASK_G) >> SHIFT_G;
+ b10 = (t00 & MASK_B);
+
+ t00 = *((tVideoSample*)((u8*)t->data + (o1 + o2)));
+ r01 = (t00 & MASK_R) >> SHIFT_R;
+ g01 = (t00 & MASK_G) >> SHIFT_G;
+ b01 = (t00 & MASK_B);
+
+ t00 = *((tVideoSample*)((u8*)t->data + (o1 + o3)));
+ r11 = (t00 & MASK_R) >> SHIFT_R;
+ g11 = (t00 & MASK_G) >> SHIFT_G;
+ b11 = (t00 & MASK_B);
+
+
+ register tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;
+ register tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;
+
+ //w00 w01 w10 w11
+ tFixPointu w[4];
+ w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);
+ w[1] = imulFixu(FIX_POINT_ONE - fracx, fracy);
+ w[2] = imulFixu(fracx, FIX_POINT_ONE - fracy);
+ w[3] = imulFixu(fracx, fracy);
+
+ r = (r00 * w[0]) +
+ (r01 * w[1]) +
+ (r10 * w[2]) +
+ (r11 * w[3]);
+
+ g = (g00 * w[0]) +
+ (g01 * w[1]) +
+ (g10 * w[2]) +
+ (g11 * w[3]);
+
+ b = (b00 * w[0]) +
+ (b01 * w[1]) +
+ (b10 * w[2]) +
+ (b11 * w[3]);
- (tFixPointu &)a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);
- (tFixPointu &)r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
- (tFixPointu &)g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
- (tFixPointu &)b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
}
-
#else
-
-// get sample linear
-REALINLINE void getSample_linear ( tFixPointu &r, tFixPointu &g, tFixPointu &b,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
- )
+// texture2D in fixpoint color range bilinear
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,
+ const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty
+)
{
- u32 ofs;
+#if 0
+ if (tex->lodFactor > 1)
+ {
+ //nearest neighbor
+ register size_t ofs;
+ ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
+ ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
+
+ register tVideoSample t00;
+ t00 = *((tVideoSample*)((u8*)tex->data + ofs));
+
+ r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
+ g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
+ b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
+ return;
+ }
+#endif
+ //w00 w01 w10 w11
+ tFixPointu w[4];
+ {
+ register tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;
+ register tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;
+ w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);
+ w[1] = imulFixu(fracx, FIX_POINT_ONE - fracy);
+ w[2] = imulFixu(FIX_POINT_ONE - fracx, fracy);
+ w[3] = imulFixu(fracx, fracy);
+ }
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
+ //wraps positive (ignoring negative)
+ tVideoSample t[4];
+ {
+ register size_t o0, o1, o2, o3;
+ o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
+ o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
+ o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
+ o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
+
+ t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));
+ t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));
+ t[2] = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));
+ t[3] = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));
+ }
- // texel
- tVideoSample t00;
- t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
+ r = (((t[0] & MASK_R) >> SHIFT_R) * w[0]) +
+ (((t[1] & MASK_R) >> SHIFT_R) * w[1]) +
+ (((t[2] & MASK_R) >> SHIFT_R) * w[2]) +
+ (((t[3] & MASK_R) >> SHIFT_R) * w[3]);
- r = (t00 & MASK_R) >> SHIFT_R;
- g = (t00 & MASK_G) >> SHIFT_G;
- b = (t00 & MASK_B);
+ g = (((t[0] & MASK_G) >> SHIFT_G) * w[0]) +
+ (((t[1] & MASK_G) >> SHIFT_G) * w[1]) +
+ (((t[2] & MASK_G) >> SHIFT_G) * w[2]) +
+ (((t[3] & MASK_G) >> SHIFT_G) * w[3]);
+
+ b = ((t[0] & MASK_B) * w[0]) +
+ ((t[1] & MASK_B) * w[1]) +
+ ((t[2] & MASK_B) * w[2]) +
+ ((t[3] & MASK_B) * w[3]);
}
+#endif
+
// get Sample bilinear
-REALINLINE void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
- )
+static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
+ const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty
+)
{
- tFixPointu r00,g00,b00;
- tFixPointu r01,g01,b01;
- tFixPointu r10,g10,b10;
- tFixPointu r11,g11,b11;
-
-#if 0
- getSample_linear ( r00, g00, b00, t, tx,ty );
- getSample_linear ( r10, g10, b10, t, tx + FIX_POINT_ONE,ty );
- getSample_linear ( r01, g01, b01, t, tx,ty + FIX_POINT_ONE );
- getSample_linear ( r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE );
-#else
- u32 o0, o1,o2,o3;
- tVideoSample t00;
-
- o0 = ( ( (ty) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
- o1 = ( ( (ty+FIX_POINT_ONE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
- o2 = ( (tx) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
- o3 = ( (tx+FIX_POINT_ONE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
-
- t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o2 ) ));
- r00 = (t00 & MASK_R) >> SHIFT_R;
- g00 = (t00 & MASK_G) >> SHIFT_G;
- b00 = (t00 & MASK_B);
-
- t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o3 ) ));
- r10 = (t00 & MASK_R) >> SHIFT_R;
- g10 = (t00 & MASK_G) >> SHIFT_G;
- b10 = (t00 & MASK_B);
-
- t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o2 ) ));
- r01 = (t00 & MASK_R) >> SHIFT_R;
- g01 = (t00 & MASK_G) >> SHIFT_G;
- b01 = (t00 & MASK_B);
-
- t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o3 ) ));
- r11 = (t00 & MASK_R) >> SHIFT_R;
- g11 = (t00 & MASK_G) >> SHIFT_G;
- b11 = (t00 & MASK_B);
-
-#endif
+ tFixPointu a00, r00, g00, b00;
+ tFixPointu a01, r01, g01, b01;
+ tFixPointu a10, r10, g10, b10;
+ tFixPointu a11, r11, g11, b11;
+
+ size_t o0, o1, o2, o3;
+ register tVideoSample t00;
+
+ o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
+ o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
+ o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
+ o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
+
+ t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));
+ a00 = (t00 & MASK_A) >> SHIFT_A;
+ r00 = (t00 & MASK_R) >> SHIFT_R;
+ g00 = (t00 & MASK_G) >> SHIFT_G;
+ b00 = (t00 & MASK_B);
+
+ t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));
+ a10 = (t00 & MASK_A) >> SHIFT_A;
+ r10 = (t00 & MASK_R) >> SHIFT_R;
+ g10 = (t00 & MASK_G) >> SHIFT_G;
+ b10 = (t00 & MASK_B);
+
+ t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));
+ a01 = (t00 & MASK_A) >> SHIFT_A;
+ r01 = (t00 & MASK_R) >> SHIFT_R;
+ g01 = (t00 & MASK_G) >> SHIFT_G;
+ b01 = (t00 & MASK_B);
+
+ t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));
+ a11 = (t00 & MASK_A) >> SHIFT_A;
+ r11 = (t00 & MASK_R) >> SHIFT_R;
+ g11 = (t00 & MASK_G) >> SHIFT_G;
+ b11 = (t00 & MASK_B);
const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;
const tFixPointu txFractInv = FIX_POINT_ONE - txFract;
@@ -961,102 +1103,78 @@ REALINLINE void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;
const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;
- const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv );
- const tFixPointu w10 = imulFixu ( txFract , tyFractInv );
- const tFixPointu w01 = imulFixu ( txFractInv, tyFract );
- const tFixPointu w11 = imulFixu ( txFract , tyFract );
+ const tFixPointu w00 = imulFixu(txFractInv, tyFractInv);
+ const tFixPointu w10 = imulFixu(txFract, tyFractInv);
+ const tFixPointu w01 = imulFixu(txFractInv, tyFract);
+ const tFixPointu w11 = imulFixu(txFract, tyFract);
+
+ a = (a00 * w00) +
+ (a01 * w01) +
+ (a10 * w10) +
+ (a11 * w11);
- r = (r00 * w00 ) +
- (r01 * w01 ) +
- (r10 * w10 ) +
- (r11 * w11 );
+ fix_alpha_color_max(a);
- g = (g00 * w00 ) +
- (g01 * w01 ) +
- (g10 * w10 ) +
- (g11 * w11 );
+ r = (r00 * w00) +
+ (r01 * w01) +
+ (r10 * w10) +
+ (r11 * w11);
- b = (b00 * w00 ) +
- (b01 * w01 ) +
- (b10 * w10 ) +
- (b11 * w11 );
+ g = (g00 * w00) +
+ (g01 * w01) +
+ (g10 * w10) +
+ (g11 * w11);
+
+ b = (b00 * w00) +
+ (b01 * w01) +
+ (b10 * w10) +
+ (b11 * w11);
}
+#else // SOFTWARE_DRIVER_2_BILINEAR
-// get sample linear
-REALINLINE void getSample_linear ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
- )
-{
- u32 ofs;
+// get Sample linear == getSample_fixpoint
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,
+ const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty
+)
+{
+ register size_t ofs;
+ ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
+ ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
// texel
- tVideoSample t00;
- t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
+ const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));
- a = (t00 & MASK_A) >> SHIFT_A;
- r = (t00 & MASK_R) >> SHIFT_R;
- g = (t00 & MASK_G) >> SHIFT_G;
- b = (t00 & MASK_B);
+ (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
+ (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
+ (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
}
-// get Sample bilinear
-REALINLINE void getSample_texture ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty
- )
+static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
+ const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty
+)
{
+ register size_t ofs;
+ ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
+ ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);
- tFixPointu a00, r00,g00,b00;
- tFixPointu a01, r01,g01,b01;
- tFixPointu a10, r10,g10,b10;
- tFixPointu a11, r11,g11,b11;
-
- getSample_linear ( a00, r00, g00, b00, t, tx,ty );
- getSample_linear ( a10, r10, g10, b10, t, tx + FIX_POINT_ONE,ty );
- getSample_linear ( a01, r01, g01, b01, t, tx,ty + FIX_POINT_ONE );
- getSample_linear ( a11, r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE );
-
- const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;
- const tFixPointu txFractInv = FIX_POINT_ONE - txFract;
-
- const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;
- const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;
-
- const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv );
- const tFixPointu w10 = imulFixu ( txFract , tyFractInv );
- const tFixPointu w01 = imulFixu ( txFractInv, tyFract );
- const tFixPointu w11 = imulFixu ( txFract , tyFract );
-
- a = (a00 * w00 ) +
- (a01 * w01 ) +
- (a10 * w10 ) +
- (a11 * w11 );
-
- r = (r00 * w00 ) +
- (r01 * w01 ) +
- (r10 * w10 ) +
- (r11 * w11 );
-
- g = (g00 * w00 ) +
- (g01 * w01 ) +
- (g10 * w10 ) +
- (g11 * w11 );
-
- b = (b00 * w00 ) +
- (b01 * w01 ) +
- (b10 * w10 ) +
- (b11 * w11 );
+ // texel
+ const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));
+ (tFixPointu &)a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);
+ fix_alpha_color_max(a);
+ (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
+ (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
+ (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
}
-#endif
+#endif // SOFTWARE_DRIVER_2_BILINEAR
+
-// some 2D Defines
+// 2D Region closed [x0;x1]
struct AbsRectangle
{
s32 x0;
@@ -1075,6 +1193,7 @@ inline bool intersect ( AbsRectangle &dest, const AbsRectangle& a, const AbsRect
return dest.x0 < dest.x1 && dest.y0 < dest.y1;
}
+#if 0
// some 1D defines
struct sIntervall
{
@@ -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 );
}
+#endif
+
+// strings
+static inline void tiny_strncpy(char* to, const char* from, const size_t count)
+{
+ for (size_t r = 0; r < count && (*to = *from) != '\0'; ++from, ++to, ++r);
+ *to = '\0';
+}
+
+#define tiny_strcpy(a, b) tiny_strncpy(a,b,sizeof(a)-1)
+
+
+// tiny_isequal = !strncmp(a,b,sizeof(a)-1)
+static inline int tiny_isequal(const char *s1, const char *s2, size_t n)
+{
+ do {
+ if (*s1 != *s2++) return 0;
+ if (*s1++ == 0)
+ break;
+ } while (--n != 0);
+ return 1;
+}
+
+#define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0
+//! Size of a static C-style array.
+#define array_size(_arr) ((sizeof(_arr)/sizeof(*_arr)))
+
} // end namespace irr
diff --git a/source/Irrlicht/burning_shader_color.cpp b/source/Irrlicht/burning_shader_color.cpp
new file mode 100644
index 0000000..3af52ab
--- /dev/null
+++ b/source/Irrlicht/burning_shader_color.cpp
@@ -0,0 +1,95 @@
+// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
+// This file is part of the "Irrlicht Engine".
+// For conditions of distribution and use, see copyright notice in irrlicht.h
+
+#include "IrrCompileConfig.h"
+#include "IBurningShader.h"
+
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
+
+namespace irr
+{
+
+namespace video
+{
+
+#define burning_shader_class burning_shader_color
+#define burning_shader_frag "burning_shader_color_fraq.h"
+#include "burning_shader_compile_fragment_default.h"
+
+
+/*!
+*/
+void burning_shader_class::OnSetMaterial(const SBurningShaderMaterial& material)
+{
+ switch (material.org.MaterialType)
+ {
+ case EMT_TRANSPARENT_ADD_COLOR:
+ case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
+ case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
+ //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
+
+ case EMT_TRANSPARENT_ALPHA_CHANNEL:
+ //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
+ //? glBlendFunc(GL_ONE,GL_ZERO) or glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ case EMT_TRANSPARENT_REFLECTION_2_LAYER:
+
+ case EMT_TRANSPARENT_VERTEX_ALPHA:
+ case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
+ case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
+ RenderPass_ShaderIsTransparent = 1;
+ AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
+ break;
+ default:
+ RenderPass_ShaderIsTransparent = 0;
+ AlphaRef = 0;
+ break;
+ }
+
+ if (0 == RenderPass_ShaderIsTransparent)
+ {
+ if (material.org.ZBuffer == ECFN_LESSEQUAL)
+ {
+ if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;
+ else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_one_zero;
+ }
+ else /*if (material.org.ZBuffer == ECFN_DISABLED)*/
+ {
+ //check triangle on w = 1.f instead..
+#ifdef SOFTWARE_DRIVER_2_BILINEAR
+ if (material.org.TextureLayer[0].BilinearFilter) fragmentShader = &burning_shader_class::fragment_nodepth_perspective_blend_one_zero;
+ else
+#endif
+ fragmentShader = &burning_shader_class::fragment_nodepth_noperspective_blend_one_zero;
+ }
+ }
+ else
+ {
+ if (material.org.ZBuffer == ECFN_LESSEQUAL)
+ {
+ if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha;
+ else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha;
+ }
+ else /*if (material.org.ZBuffer == ECFN_DISABLED)*/
+ {
+ //check triangle on w = 1.f instead..
+#ifdef SOFTWARE_DRIVER_2_BILINEAR
+ if (material.org.TextureLayer[0].BilinearFilter) fragmentShader = &burning_shader_class::fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha;
+ else
+#endif
+ fragmentShader = &burning_shader_class::fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha;
+ }
+ }
+
+}
+
+
+
+} // end namespace video
+} // end namespace irr
+
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
+
diff --git a/source/Irrlicht/burning_shader_color_fraq.h b/source/Irrlicht/burning_shader_color_fraq.h
new file mode 100644
index 0000000..f9efae2
--- /dev/null
+++ b/source/Irrlicht/burning_shader_color_fraq.h
@@ -0,0 +1,24 @@
+// pixelshader
+#ifdef IPOL_C0
+
+#ifdef IPOL_A0
+vec4_to_fix(a0, r0, g0, b0, line.c[0][0], inversew);
+if (a0 > AlphaRef)
+{
+ color_to_fix(r1, g1, b1, dst[i]);
+
+ fix_color_norm(a0);
+ r0 = r1 + imulFix(a0, r0 - r1);
+ g0 = g1 + imulFix(a0, g0 - g1);
+ b0 = b1 + imulFix(a0, b0 - b1);
+ dst[i] = fix_to_sample(r0, g0, b0);
+}
+#else
+vec4_to_fix(r0, g0, b0, line.c[0][0], inversew);
+dst[i] = fix_to_sample(r0, g0, b0);
+#endif
+
+#else
+dst[i] = PrimitiveColor;
+#endif
+
diff --git a/source/Irrlicht/burning_shader_compile_fragment_default.h b/source/Irrlicht/burning_shader_compile_fragment_default.h
new file mode 100644
index 0000000..f28ab70
--- /dev/null
+++ b/source/Irrlicht/burning_shader_compile_fragment_default.h
@@ -0,0 +1,164 @@
+
+
+class burning_shader_class : public IBurningShader
+{
+public:
+
+ //! constructor
+ burning_shader_class(CBurningVideoDriver* driver);
+
+ //! draws an indexed triangle list
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
+ virtual bool canWireFrame() { return true; }
+
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
+
+private:
+
+ // fragment shader
+ typedef void (burning_shader_class::*tFragmentShader) ();
+ void fragment_depth_less_equal_depth_write_blend_one_zero();
+ void fragment_depth_less_equal_no_depth_write_blend_one_zero();
+ void fragment_nodepth_perspective_blend_one_zero();
+ void fragment_nodepth_noperspective_blend_one_zero(); // 2D Gradient
+
+ void fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha();
+ void fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha();
+ void fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha();
+ void fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha();
+
+
+ tFragmentShader fragmentShader;
+
+};
+
+
+//! constructor
+burning_shader_class::burning_shader_color(CBurningVideoDriver* driver)
+ : IBurningShader(driver)
+{
+#ifdef _DEBUG
+ setDebugName(burning_stringify(burning_shader_class) );
+#endif
+
+ fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;
+
+}
+
+
+IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver)
+{
+ return new burning_shader_class(driver);
+}
+
+
+
+// compile flag for this triangle
+#include "burning_shader_compile_start.h"
+#define SUBTEXEL
+#define IPOL_W
+#define IPOL_C0
+#define USE_ZBUFFER
+#define CMP_W
+#include "burning_shader_compile_triangle.h"
+
+// compile flag for this scanline fragment
+#include "burning_shader_compile_start.h"
+#define burning_shader_fragment fragment_nodepth_noperspective_blend_one_zero
+#define SUBTEXEL
+#define IPOL_C0
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
+#include "burning_shader_compile_fragment_start.h"
+#include burning_shader_frag
+#include "burning_shader_compile_fragment_end.h"
+
+#include "burning_shader_compile_start.h"
+#define burning_shader_fragment fragment_nodepth_perspective_blend_one_zero
+#define SUBTEXEL
+#define INVERSE_W
+#define IPOL_W
+#define IPOL_C0
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
+#include "burning_shader_compile_fragment_start.h"
+#include burning_shader_frag
+#include "burning_shader_compile_fragment_end.h"
+
+#include "burning_shader_compile_start.h"
+#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_blend_one_zero
+#define SUBTEXEL
+#define INVERSE_W
+#define IPOL_W
+#define IPOL_C0
+#define USE_ZBUFFER
+#define CMP_W
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
+#include "burning_shader_compile_fragment_start.h"
+#include burning_shader_frag
+#include "burning_shader_compile_fragment_end.h"
+
+#include "burning_shader_compile_start.h"
+#define burning_shader_fragment fragment_depth_less_equal_depth_write_blend_one_zero
+#define SUBTEXEL
+#define INVERSE_W
+#define IPOL_W
+#define IPOL_C0
+#define USE_ZBUFFER
+#define CMP_W
+#define WRITE_W
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
+#include "burning_shader_compile_fragment_start.h"
+#include burning_shader_frag
+#include "burning_shader_compile_fragment_end.h"
+
+
+// compile flag for this scanline fragment
+#include "burning_shader_compile_start.h"
+#define burning_shader_fragment fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha
+#define SUBTEXEL
+#define IPOL_C0
+#define IPOL_A0
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
+#include "burning_shader_compile_fragment_start.h"
+#include burning_shader_frag
+#include "burning_shader_compile_fragment_end.h"
+
+#include "burning_shader_compile_start.h"
+#define burning_shader_fragment fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha
+#define SUBTEXEL
+#define INVERSE_W
+#define IPOL_W
+#define IPOL_C0
+#define IPOL_A0
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
+#include "burning_shader_compile_fragment_start.h"
+#include burning_shader_frag
+#include "burning_shader_compile_fragment_end.h"
+
+#include "burning_shader_compile_start.h"
+#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha
+#define SUBTEXEL
+#define INVERSE_W
+#define IPOL_W
+#define IPOL_C0
+#define IPOL_A0
+#define USE_ZBUFFER
+#define CMP_W
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
+#include "burning_shader_compile_fragment_start.h"
+#include burning_shader_frag
+#include "burning_shader_compile_fragment_end.h"
+
+#include "burning_shader_compile_start.h"
+#define burning_shader_fragment fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha
+#define SUBTEXEL
+#define INVERSE_W
+#define IPOL_W
+#define IPOL_C0
+#define IPOL_A0
+#define USE_ZBUFFER
+#define CMP_W
+#define WRITE_W
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
+#include "burning_shader_compile_fragment_start.h"
+#include burning_shader_frag
+#include "burning_shader_compile_fragment_end.h"
diff --git a/source/Irrlicht/burning_shader_compile_fragment_end.h b/source/Irrlicht/burning_shader_compile_fragment_end.h
new file mode 100644
index 0000000..8e4719e
--- /dev/null
+++ b/source/Irrlicht/burning_shader_compile_fragment_end.h
@@ -0,0 +1,20 @@
+ }
+
+#ifdef IPOL_Z
+ line.z[0] += slopeZ;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0];
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1];
+#endif
+ }
+
+}
diff --git a/source/Irrlicht/burning_shader_compile_fragment_start.h b/source/Irrlicht/burning_shader_compile_fragment_start.h
new file mode 100644
index 0000000..64a8463
--- /dev/null
+++ b/source/Irrlicht/burning_shader_compile_fragment_start.h
@@ -0,0 +1,119 @@
+#include "burning_shader_compile_verify.h"
+
+/*!
+*/
+void burning_shader_class::burning_shader_fragment()
+{
+ tVideoSample *dst;
+
+#ifdef USE_ZBUFFER
+ fp24 *z;
+#endif
+
+ s32 xStart;
+ s32 xEnd;
+ s32 dx;
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+#ifdef IPOL_Z
+ f32 slopeZ;
+#endif
+#ifdef IPOL_W
+ fp24 slopeW;
+#endif
+#ifdef IPOL_C0
+ sVec4 slopeC;
+#endif
+#ifdef IPOL_T0
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
+#endif
+
+ // apply top-left fill-convention, left
+ xStart = fill_convention_left(line.x[0]);
+ xEnd = fill_convention_right(line.x[1]);
+
+ dx = xEnd - xStart;
+ if (dx < 0)
+ return;
+
+ // slopes
+ const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);
+
+#ifdef IPOL_Z
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
+#endif
+#ifdef IPOL_W
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;
+#endif
+#ifdef IPOL_C0
+ slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T0
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
+#endif
+#ifdef IPOL_T1
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
+#endif
+
+#ifdef SUBTEXEL
+ subPixel = ((f32)xStart) - line.x[0];
+#ifdef IPOL_Z
+ line.z[0] += slopeZ * subPixel;
+#endif
+#ifdef IPOL_W
+ line.w[0] += slopeW * subPixel;
+#endif
+#ifdef IPOL_C0
+ line.c[0][0] += slopeC * subPixel;
+#endif
+#ifdef IPOL_T0
+ line.t[0][0] += slopeT[0] * subPixel;
+#endif
+#ifdef IPOL_T1
+ line.t[1][0] += slopeT[1] * subPixel;
+#endif
+#endif
+
+ SOFTWARE_DRIVER_2_CLIPCHECK;
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
+
+#ifdef USE_ZBUFFER
+ z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
+#endif
+
+
+ f32 inversew = INVERSE_W_RANGE;
+
+#ifdef IPOL_C0
+ tFixPoint r0, g0, b0;
+#endif
+
+#ifdef IPOL_A0
+ tFixPoint a0;
+ tFixPoint r1, g1, b1;
+#endif
+
+ for (s32 i = 0; i <= dx; ++i)
+ {
+ if ((0 == EdgeTestPass) & i) break;
+
+#ifdef CMP_Z
+ if (line.z[0] < z[i])
+#endif
+#ifdef CMP_W
+ if (line.w[0] >= z[i])
+#endif
+ {
+#ifdef WRITE_Z
+ z[i] = line.z[0];
+#endif
+#ifdef WRITE_W
+ z[i] = line.w[0];
+#endif
+ /* Pixel Shader here */
+#ifdef INVERSE_W
+ inversew = (INVERSE_W_RANGE) / line.w[0]; /* fix_inverse32(line.w[0]);*/
+#endif
diff --git a/source/Irrlicht/burning_shader_compile_start.h b/source/Irrlicht/burning_shader_compile_start.h
new file mode 100644
index 0000000..0d8a5f7
--- /dev/null
+++ b/source/Irrlicht/burning_shader_compile_start.h
@@ -0,0 +1,24 @@
+// undef compile flag for this file
+#undef USE_ZBUFFER
+#undef IPOL_Z
+#undef CMP_Z
+#undef WRITE_Z
+
+#undef IPOL_W
+#undef CMP_W
+#undef WRITE_W
+
+#undef SUBTEXEL
+#undef INVERSE_W
+
+#undef IPOL_C0
+#undef IPOL_A0
+#undef IPOL_T0
+#undef IPOL_T1
+#undef IPOL_T2
+#undef IPOL_L0
+
+#undef burning_shader_fragment
+#undef ipol_test
+
+#undef INVERSE_W_RANGE
diff --git a/source/Irrlicht/burning_shader_compile_triangle.h b/source/Irrlicht/burning_shader_compile_triangle.h
new file mode 100644
index 0000000..aa58858
--- /dev/null
+++ b/source/Irrlicht/burning_shader_compile_triangle.h
@@ -0,0 +1,368 @@
+#include "burning_shader_compile_verify.h"
+
+
+void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
+{
+ // sort on height, y
+ if (a->Pos.y > b->Pos.y) swapVertexPointer(&a, &b);
+ if (a->Pos.y > c->Pos.y) swapVertexPointer(&a, &c);
+ if (b->Pos.y > c->Pos.y) swapVertexPointer(&b, &c);
+
+ const f32 ca = c->Pos.y - a->Pos.y;
+ const f32 ba = b->Pos.y - a->Pos.y;
+ const f32 cb = c->Pos.y - b->Pos.y;
+
+ // calculate delta y of the edges
+ scan.invDeltaY[0] = reciprocal_edge(ca);
+ scan.invDeltaY[1] = reciprocal_edge(ba);
+ scan.invDeltaY[2] = reciprocal_edge(cb);
+
+ if (F32_LOWER_EQUAL_0(scan.invDeltaY[0]))
+ return;
+
+ // find if the major edge is left or right aligned
+ f32 temp[4];
+
+ temp[0] = a->Pos.x - c->Pos.x;
+ temp[1] = -ca;
+ temp[2] = b->Pos.x - a->Pos.x;
+ temp[3] = ba;
+
+ scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) > 0.f ? 0 : 1;
+ scan.right = 1 - scan.left;
+
+ // calculate slopes for the major edge
+ scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
+ scan.x[0] = a->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
+ scan.z[0] = a->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
+ scan.w[0] = a->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
+ scan.c[0][0] = a->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
+ scan.t[0][0] = a->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
+ scan.t[1][0] = a->Tex[1];
+#endif
+
+ // top left fill convention y run
+ s32 yStart;
+ s32 yEnd;
+
+#ifdef SUBTEXEL
+ f32 subPixel;
+#endif
+
+
+ // rasterize upper sub-triangle
+ if (F32_GREATER_0(scan.invDeltaY[1]))
+ {
+ // calculate slopes for top edge
+ scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
+ scan.x[1] = a->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
+ scan.z[1] = a->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
+ scan.w[1] = a->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
+ scan.c[0][1] = a->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
+ scan.t[0][1] = a->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
+ scan.t[1][1] = a->Tex[1];
+#endif
+
+ // apply top-left fill convention, top part
+ yStart = fill_convention_left(a->Pos.y);
+ yEnd = fill_convention_right(b->Pos.y);
+
+#ifdef SUBTEXEL
+ subPixel = ((f32)yStart) - a->Pos.y;
+
+ // correct to pixel center
+ scan.x[0] += scan.slopeX[0] * subPixel;
+ scan.x[1] += scan.slopeX[1] * subPixel;
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0] * subPixel;
+ scan.z[1] += scan.slopeZ[1] * subPixel;
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0] * subPixel;
+ scan.w[1] += scan.slopeW[1] * subPixel;
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;
+#endif
+
+#endif
+
+ // rasterize the edge scanlines
+ for (line.y = yStart; line.y <= yEnd; ++line.y)
+ {
+ line.x[scan.left] = scan.x[0];
+ line.x[scan.right] = scan.x[1];
+
+#ifdef IPOL_Z
+ line.z[scan.left] = scan.z[0];
+ line.z[scan.right] = scan.z[1];
+#endif
+
+#ifdef IPOL_W
+ line.w[scan.left] = scan.w[0];
+ line.w[scan.right] = scan.w[1];
+#endif
+
+#ifdef IPOL_C0
+ line.c[0][scan.left] = scan.c[0][0];
+ line.c[0][scan.right] = scan.c[0][1];
+#endif
+
+#ifdef IPOL_T0
+ line.t[0][scan.left] = scan.t[0][0];
+ line.t[0][scan.right] = scan.t[0][1];
+#endif
+
+#ifdef IPOL_T1
+ line.t[1][scan.left] = scan.t[1][0];
+ line.t[1][scan.right] = scan.t[1][1];
+#endif
+
+ // render a scanline
+ (this->*fragmentShader) ();
+ if (EdgeTestPass & edge_test_first_line) break;
+
+ scan.x[0] += scan.slopeX[0];
+ scan.x[1] += scan.slopeX[1];
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0];
+ scan.z[1] += scan.slopeZ[1];
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0];
+ scan.w[1] += scan.slopeW[1];
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0];
+ scan.c[0][1] += scan.slopeC[0][1];
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0];
+ scan.t[0][1] += scan.slopeT[0][1];
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0];
+ scan.t[1][1] += scan.slopeT[1][1];
+#endif
+ }
+ }
+
+ // rasterize lower sub-triangle
+ if (F32_GREATER_0(scan.invDeltaY[2]))
+ {
+ // advance to middle point
+ if (F32_GREATER_0(scan.invDeltaY[1]))
+ {
+ temp[0] = b->Pos.y - a->Pos.y; // dy
+
+ scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
+#ifdef IPOL_Z
+ scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
+#endif
+#ifdef IPOL_W
+ scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
+#endif
+#ifdef IPOL_C0
+ scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
+#endif
+#ifdef IPOL_T0
+ scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
+#endif
+#ifdef IPOL_T1
+ scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
+#endif
+
+ }
+
+ // calculate slopes for bottom edge
+ scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
+ scan.x[1] = b->Pos.x;
+
+#ifdef IPOL_Z
+ scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
+ scan.z[1] = b->Pos.z;
+#endif
+
+#ifdef IPOL_W
+ scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
+ scan.w[1] = b->Pos.w;
+#endif
+
+#ifdef IPOL_C0
+ scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
+ scan.c[0][1] = b->Color[0];
+#endif
+
+#ifdef IPOL_T0
+ scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
+ scan.t[0][1] = b->Tex[0];
+#endif
+
+#ifdef IPOL_T1
+ scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
+ scan.t[1][1] = b->Tex[1];
+#endif
+
+ // apply top-left fill convention, top part
+ yStart = fill_convention_left(b->Pos.y);
+ yEnd = fill_convention_right(c->Pos.y);
+
+#ifdef SUBTEXEL
+
+ subPixel = ((f32)yStart) - b->Pos.y;
+
+ // correct to pixel center
+ scan.x[0] += scan.slopeX[0] * subPixel;
+ scan.x[1] += scan.slopeX[1] * subPixel;
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0] * subPixel;
+ scan.z[1] += scan.slopeZ[1] * subPixel;
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0] * subPixel;
+ scan.w[1] += scan.slopeW[1] * subPixel;
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;
+#endif
+
+#endif
+
+ // rasterize the edge scanlines
+ for (line.y = yStart; line.y <= yEnd; ++line.y)
+ {
+ line.x[scan.left] = scan.x[0];
+ line.x[scan.right] = scan.x[1];
+
+#ifdef IPOL_Z
+ line.z[scan.left] = scan.z[0];
+ line.z[scan.right] = scan.z[1];
+#endif
+
+#ifdef IPOL_W
+ line.w[scan.left] = scan.w[0];
+ line.w[scan.right] = scan.w[1];
+#endif
+
+#ifdef IPOL_C0
+ line.c[0][scan.left] = scan.c[0][0];
+ line.c[0][scan.right] = scan.c[0][1];
+#endif
+
+#ifdef IPOL_T0
+ line.t[0][scan.left] = scan.t[0][0];
+ line.t[0][scan.right] = scan.t[0][1];
+#endif
+
+#ifdef IPOL_T1
+ line.t[1][scan.left] = scan.t[1][0];
+ line.t[1][scan.right] = scan.t[1][1];
+#endif
+
+ // render a scanline
+ (this->*fragmentShader) ();
+ if (EdgeTestPass & edge_test_first_line) break;
+
+ scan.x[0] += scan.slopeX[0];
+ scan.x[1] += scan.slopeX[1];
+
+#ifdef IPOL_Z
+ scan.z[0] += scan.slopeZ[0];
+ scan.z[1] += scan.slopeZ[1];
+#endif
+
+#ifdef IPOL_W
+ scan.w[0] += scan.slopeW[0];
+ scan.w[1] += scan.slopeW[1];
+#endif
+
+#ifdef IPOL_C0
+ scan.c[0][0] += scan.slopeC[0][0];
+ scan.c[0][1] += scan.slopeC[0][1];
+#endif
+
+#ifdef IPOL_T0
+ scan.t[0][0] += scan.slopeT[0][0];
+ scan.t[0][1] += scan.slopeT[0][1];
+#endif
+
+#ifdef IPOL_T1
+ scan.t[1][0] += scan.slopeT[1][0];
+ scan.t[1][1] += scan.slopeT[1][1];
+#endif
+
+ }
+ }
+
+}
diff --git a/source/Irrlicht/burning_shader_compile_verify.h b/source/Irrlicht/burning_shader_compile_verify.h
new file mode 100644
index 0000000..c31c575
--- /dev/null
+++ b/source/Irrlicht/burning_shader_compile_verify.h
@@ -0,0 +1,43 @@
+// apply global override
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
+#undef INVERSE_W
+#endif
+
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
+#undef SUBTEXEL
+#endif
+
+#if BURNING_MATERIAL_MAX_COLORS < 1
+#undef IPOL_C0
+#undef IPOL_A0
+#endif
+
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
+#undef IPOL_L0
+#endif
+
+
+// 1/x * FIX_POINT
+#if !defined(INVERSE_W_RANGE)
+ #define INVERSE_W_RANGE FIX_POINT_F32_MUL
+#endif
+
+#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )
+#else
+
+#ifdef IPOL_W
+ #undef IPOL_W
+ #define IPOL_Z
+#endif
+
+#ifdef CMP_W
+ #undef CMP_W
+ #define CMP_Z
+#endif
+
+#ifdef WRITE_W
+ #undef WRITE_W
+ #define WRITE_Z
+#endif
+
+#endif
diff --git a/tests/media/Burning's Video-2dmatFilter.png b/tests/media/Burning's Video-2dmatFilter.png
index af1a9e0..bdd17cd 100644
--- a/tests/media/Burning's Video-2dmatFilter.png
+++ b/tests/media/Burning's Video-2dmatFilter.png
Binary files differ
diff --git a/tests/media/Burning's Video-b3dAnimation.png b/tests/media/Burning's Video-b3dAnimation.png
index 52feb69..d16e689 100644
--- a/tests/media/Burning's Video-b3dAnimation.png
+++ b/tests/media/Burning's Video-b3dAnimation.png
Binary files differ
diff --git a/tests/media/Burning's Video-b3dJointPosition.png b/tests/media/Burning's Video-b3dJointPosition.png
index fc33f23..b669f8f 100644
--- a/tests/media/Burning's Video-b3dJointPosition.png
+++ b/tests/media/Burning's Video-b3dJointPosition.png
Binary files differ
diff --git a/tests/media/Burning's Video-billboard.png b/tests/media/Burning's Video-billboard.png
index 9892076..59f36c1 100644
--- a/tests/media/Burning's Video-billboard.png
+++ b/tests/media/Burning's Video-billboard.png
Binary files differ
diff --git a/tests/media/Burning's Video-billboardOrientation.png b/tests/media/Burning's Video-billboardOrientation.png
index fb99360..2805aed 100644
--- a/tests/media/Burning's Video-billboardOrientation.png
+++ b/tests/media/Burning's Video-billboardOrientation.png
Binary files differ
diff --git a/tests/media/Burning's Video-draw2DImage4cFilter.png b/tests/media/Burning's Video-draw2DImage4cFilter.png
index a245525..0a98b70 100644
--- a/tests/media/Burning's Video-draw2DImage4cFilter.png
+++ b/tests/media/Burning's Video-draw2DImage4cFilter.png
Binary files differ
diff --git a/tests/media/Burning's Video-drawPixel.png b/tests/media/Burning's Video-drawPixel.png
index b7539cf..08288a8 100644
--- a/tests/media/Burning's Video-drawPixel.png
+++ b/tests/media/Burning's Video-drawPixel.png
Binary files differ
diff --git a/tests/media/Burning's Video-drawVPL_e.png b/tests/media/Burning's Video-drawVPL_e.png
index a3f5162..bc83992 100644
--- a/tests/media/Burning's Video-drawVPL_e.png
+++ b/tests/media/Burning's Video-drawVPL_e.png
Binary files differ
diff --git a/tests/media/Burning's Video-drawVPL_g.png b/tests/media/Burning's Video-drawVPL_g.png
index 113dc35..438941d 100644
--- a/tests/media/Burning's Video-drawVPL_g.png
+++ b/tests/media/Burning's Video-drawVPL_g.png
Binary files differ
diff --git a/tests/media/Burning's Video-drawVPL_h.png b/tests/media/Burning's Video-drawVPL_h.png
index d1b1f8d..8ed4455 100644
--- a/tests/media/Burning's Video-drawVPL_h.png
+++ b/tests/media/Burning's Video-drawVPL_h.png
Binary files differ
diff --git a/tests/media/Burning's Video-drawVPL_i.png b/tests/media/Burning's Video-drawVPL_i.png
index be45d0f..e344631 100644
--- a/tests/media/Burning's Video-drawVPL_i.png
+++ b/tests/media/Burning's Video-drawVPL_i.png
Binary files differ
diff --git a/tests/media/Burning's Video-flyCircleAnimator.png b/tests/media/Burning's Video-flyCircleAnimator.png
index fbc2eca..218af2a 100644
--- a/tests/media/Burning's Video-flyCircleAnimator.png
+++ b/tests/media/Burning's Video-flyCircleAnimator.png
Binary files differ
diff --git a/tests/media/Burning's Video-lightType.png b/tests/media/Burning's Video-lightType.png
index a472e92..446cc6d 100644
--- a/tests/media/Burning's Video-lightType.png
+++ b/tests/media/Burning's Video-lightType.png
Binary files differ
diff --git a/tests/media/Burning's Video-loadScene.png b/tests/media/Burning's Video-loadScene.png
index b68c914..00e08b1 100644
--- a/tests/media/Burning's Video-loadScene.png
+++ b/tests/media/Burning's Video-loadScene.png
Binary files differ
diff --git a/tests/media/Burning's Video-md2Normals.png b/tests/media/Burning's Video-md2Normals.png
index 709b97e..302b9b3 100644
--- a/tests/media/Burning's Video-md2Normals.png
+++ b/tests/media/Burning's Video-md2Normals.png
Binary files differ
diff --git a/tests/media/Burning's Video-multiTexture.png b/tests/media/Burning's Video-multiTexture.png
index a5666b7..338f257 100644
--- a/tests/media/Burning's Video-multiTexture.png
+++ b/tests/media/Burning's Video-multiTexture.png
Binary files differ
diff --git a/tests/media/Burning's Video-orthoCam.png b/tests/media/Burning's Video-orthoCam.png
index 5e35ddd..41a96b8 100644
--- a/tests/media/Burning's Video-orthoCam.png
+++ b/tests/media/Burning's Video-orthoCam.png
Binary files differ
diff --git a/tests/media/Burning's Video-planeMatrix-scaledClip.png b/tests/media/Burning's Video-planeMatrix-scaledClip.png
index 14f6dc3..7c93216 100644
--- a/tests/media/Burning's Video-planeMatrix-scaledClip.png
+++ b/tests/media/Burning's Video-planeMatrix-scaledClip.png
Binary files differ
diff --git a/tests/media/Burning's Video-renderMipmap.png b/tests/media/Burning's Video-renderMipmap.png
index 06fc37f..d2d5321 100644
--- a/tests/media/Burning's Video-renderMipmap.png
+++ b/tests/media/Burning's Video-renderMipmap.png
Binary files differ
diff --git a/tests/media/Burning's Video-stencilSelfShadow.png b/tests/media/Burning's Video-stencilSelfShadow.png
index dcdb608..2bd6eec 100644
--- a/tests/media/Burning's Video-stencilSelfShadow.png
+++ b/tests/media/Burning's Video-stencilSelfShadow.png
Binary files differ
diff --git a/tests/media/Burning's Video-stencilShadow.png b/tests/media/Burning's Video-stencilShadow.png
index 60f31cd..77c53fd 100644
--- a/tests/media/Burning's Video-stencilShadow.png
+++ b/tests/media/Burning's Video-stencilShadow.png
Binary files differ
diff --git a/tests/media/Burning's Video-terrainGap.png b/tests/media/Burning's Video-terrainGap.png
index 835a946..db12562 100644
--- a/tests/media/Burning's Video-terrainGap.png
+++ b/tests/media/Burning's Video-terrainGap.png
Binary files differ
diff --git a/tests/media/Burning's Video-terrainSceneNode-1.png b/tests/media/Burning's Video-terrainSceneNode-1.png
index ba53a28..e7a8993 100644
--- a/tests/media/Burning's Video-terrainSceneNode-1.png
+++ b/tests/media/Burning's Video-terrainSceneNode-1.png
Binary files differ
diff --git a/tests/media/Burning's Video-terrainSceneNode-2.png b/tests/media/Burning's Video-terrainSceneNode-2.png
index 4c92f02..1c7538a 100644
--- a/tests/media/Burning's Video-terrainSceneNode-2.png
+++ b/tests/media/Burning's Video-terrainSceneNode-2.png
Binary files differ
diff --git a/tests/media/Burning's Video-testGeometryCreator.png b/tests/media/Burning's Video-testGeometryCreator.png
index 5ea4166..6904bde 100644
--- a/tests/media/Burning's Video-testGeometryCreator.png
+++ b/tests/media/Burning's Video-testGeometryCreator.png
Binary files differ
diff --git a/tests/media/Burning's Video-testTerrainMesh.png b/tests/media/Burning's Video-testTerrainMesh.png
index 53d0aa5..ffbc74c 100644
--- a/tests/media/Burning's Video-testTerrainMesh.png
+++ b/tests/media/Burning's Video-testTerrainMesh.png
Binary files differ
diff --git a/tests/media/Burning's Video-textureMatrix.png b/tests/media/Burning's Video-textureMatrix.png
new file mode 100644
index 0000000..26afc9e
--- /dev/null
+++ b/tests/media/Burning's Video-textureMatrix.png
Binary files differ
diff --git a/tests/media/Burning's Video-textureMatrix2.png b/tests/media/Burning's Video-textureMatrix2.png
new file mode 100644
index 0000000..26afc9e
--- /dev/null
+++ b/tests/media/Burning's Video-textureMatrix2.png
Binary files differ
diff --git a/tests/media/Burning's Video-textureMatrixInMixedScenes.png b/tests/media/Burning's Video-textureMatrixInMixedScenes.png
new file mode 100644
index 0000000..e5cdeb2
--- /dev/null
+++ b/tests/media/Burning's Video-textureMatrixInMixedScenes.png
Binary files differ
diff --git a/tests/media/Burning's Video-textureRenderStates.png b/tests/media/Burning's Video-textureRenderStates.png
index 98282fa..92c29fc 100644
--- a/tests/media/Burning's Video-textureRenderStates.png
+++ b/tests/media/Burning's Video-textureRenderStates.png
Binary files differ
diff --git a/tests/media/Burning's Video-transparentAddColor.png b/tests/media/Burning's Video-transparentAddColor.png
index 87261e5..5937448 100644
--- a/tests/media/Burning's Video-transparentAddColor.png
+++ b/tests/media/Burning's Video-transparentAddColor.png
Binary files differ
diff --git a/tests/media/Burning's Video-transparentAlphaChannel.png b/tests/media/Burning's Video-transparentAlphaChannel.png
index 0986ed4..358455d 100644
--- a/tests/media/Burning's Video-transparentAlphaChannel.png
+++ b/tests/media/Burning's Video-transparentAlphaChannel.png
Binary files differ
diff --git a/tests/media/Burning's Video-transparentAlphaChannelRef.png b/tests/media/Burning's Video-transparentAlphaChannelRef.png
index 09ff338..21844ab 100644
--- a/tests/media/Burning's Video-transparentAlphaChannelRef.png
+++ b/tests/media/Burning's Video-transparentAlphaChannelRef.png
Binary files differ
diff --git a/tests/media/Burning's Video-transparentReflection2Layer.png b/tests/media/Burning's Video-transparentReflection2Layer.png
index 7acfba6..926d189 100644
--- a/tests/media/Burning's Video-transparentReflection2Layer.png
+++ b/tests/media/Burning's Video-transparentReflection2Layer.png
Binary files differ
diff --git a/tests/media/Burning's Video-transparentVertexAlpha.png b/tests/media/Burning's Video-transparentVertexAlpha.png
index b8f268c..aef6dbd 100644
--- a/tests/media/Burning's Video-transparentVertexAlpha.png
+++ b/tests/media/Burning's Video-transparentVertexAlpha.png
Binary files differ
diff --git a/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png b/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png
index 4dfaff0..666b814 100644
--- a/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png
+++ b/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png
Binary files differ
diff --git a/tests/media/Burning's Video-viewPortText.png b/tests/media/Burning's Video-viewPortText.png
index 7c9f781..56e3065 100644
--- a/tests/media/Burning's Video-viewPortText.png
+++ b/tests/media/Burning's Video-viewPortText.png
Binary files differ
diff --git a/tests/media/Burning's Video-writeImageToFile.png b/tests/media/Burning's Video-writeImageToFile.png
new file mode 100644
index 0000000..08288a8
--- /dev/null
+++ b/tests/media/Burning's Video-writeImageToFile.png
Binary files differ
diff --git a/tests/tests-last-passed-at.txt b/tests/tests-last-passed-at.txt
index 673e1c4..9158849 100644
--- a/tests/tests-last-passed-at.txt
+++ b/tests/tests-last-passed-at.txt
@@ -1,4 +1,4 @@
Tests finished. 72 tests of 72 passed.
-Compiled as DEBUG
-Test suite pass at GMT Mon Feb 10 14:59:56 2020
+Compiled as RELEASE
+Test suite pass at GMT Sun Feb 23 02:59:02 2020