\r
--------------------------\r
Changes in 1.9 (not yet released)\r
+- BurningVideo: 0.51\r
+ - 10 year anniversary update\r
+ - Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map] \r
+ - increased internal s4DVertex to support 4 Textures and 4 Colors [switchable]\r
+ - Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption\r
+ - 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D\r
+ - Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE]\r
+ - NormalMap for 1 Light accurate. still all lights are accumulated\r
+ - SuperTuxKart 8.0.1 playable\r
+ - Known Problems\r
+ - Depthbuffer range not equal to Hardware Drivers. Problems with Orthographic Stencil Shadows\r
+ - Triangle MipMap Selection. Wrong for TextureAtlas and Billboards\r
- Fix CPLYMeshFileLoader checking for wrong vertex count when switching between 16/32 bit. Thanks @randomMesh for reporting.\r
- Fix bug that AnimatedMeshSceneNode ignored ReadOnlyMaterials flag when checking materials for transparent render passes.\r
- Unify checks if materials should use transparent render pass with new IVideoDriver::needsTransparentRenderPass function.\r
/*\r
And at last, we create a nice Irrlicht Engine logo in the top left corner.\r
*/\r
- env->addImage(driver->getTexture(mediaPath + "irrlichtlogo2.png"),\r
+ env->addImage(driver->getTexture(mediaPath + "irrlichtlogo3.png"),\r
position2d<int>(10,10));\r
\r
\r
\r
// load the irrlicht engine logo\r
IGUIImage *img =\r
- env->addImage(driver->getTexture("irrlichtlogo2.png"),\r
+ env->addImage(driver->getTexture("irrlichtlogo3.png"),\r
core::position2d<s32>(10, driver->getScreenSize().Height - 128));\r
\r
// lock the logo's edges to the bottom left corner of the screen\r
vsFileName = mediaPath + "opengl.vsh";\r
}\r
break;\r
+ default:\r
+ break;\r
}\r
\r
/*\r
driver->getTexture(mediaPath + "rockwall.jpg"));\r
room->setMaterialTexture(1, normalMap);\r
\r
- // Stones don't glitter..\r
- room->getMaterial(0).SpecularColor.set(0,0,0,0);\r
- room->getMaterial(0).Shininess = 0.f;\r
+ // Stones don't glitter.. (but specular highlight for EMT_SOLID)\r
+ //room->getMaterial(0).SpecularColor.set(0,0,0,0);\r
+ //room->getMaterial(0).Shininess = 0.f;\r
\r
room->setMaterialFlag(video::EMF_FOG_ENABLE, true);\r
room->setMaterialType(video::EMT_PARALLAX_MAP_SOLID);\r
// add light 1 (more green)\r
scene::ILightSceneNode* light1 =\r
smgr->addLightSceneNode(0, core::vector3df(0,0,0),\r
- video::SColorf(0.5f, 1.0f, 0.5f, 0.0f), 800.0f);\r
+ video::SColorf(0.5f, 1.0f, 0.5f, 0.0f), 400.0f);\r
\r
// add fly circle animator to light 1\r
scene::ISceneNodeAnimator* anim =\r
// add light 2 (red)\r
scene::ISceneNode* light2 =\r
smgr->addLightSceneNode(0, core::vector3df(0,0,0),\r
- video::SColorf(1.0f, 0.2f, 0.2f, 0.0f), 800.0f);\r
+ video::SColorf(1.0f, 0.2f, 0.2f, 0.0f), 400.0f);\r
\r
// add fly circle animator to light 2\r
anim = smgr->createFlyCircleAnimator(core::vector3df(0,150,0), 200.0f,\r
const io::path mediaPath = getExampleMediaPath();\r
\r
// add irrlicht logo\r
- env->addImage(driver->getTexture(mediaPath + "irrlichtlogo2.png"),\r
+ env->addImage(driver->getTexture(mediaPath + "irrlichtlogo3.png"),\r
core::position2d<s32>(10,10));\r
\r
//set other font\r
terrain->getMeshBufferForLOD(*buffer, 0);\r
video::S3DVertex2TCoords* data = (video::S3DVertex2TCoords*)buffer->getVertexBuffer().getData();\r
// Work on data or get the IndexBuffer with a similar call.\r
+ (void)data; // disable unused variable warnings\r
buffer->drop(); // When done drop the buffer again.\r
\r
/*\r
device->getCursorControl()->setVisible(false);\r
\r
// load the engine logo\r
- gui->addImage(driver->getTexture("irrlichtlogo2.png"),\r
+ gui->addImage(driver->getTexture("irrlichtlogo3.png"),\r
core::position2d<s32>(10, 10));\r
\r
// show the driver logo\r
case video::EDT_DIRECT3D9:\r
gui->addImage(driver->getTexture("directxlogo.png"), pos);\r
break;\r
+ default:\r
+ break;\r
}\r
\r
/*\r
driver->endScene();\r
\r
int fps = driver->getFPS();\r
- //if (lastFPS != fps)\r
+ if (1 || lastFPS != fps)\r
{\r
- io::IAttributes * const attr = smgr->getParameters();\r
core::stringw str = L"Q3 [";\r
str += driver->getName();\r
str += "] FPS:";\r
str += fps;\r
#ifdef _IRR_SCENEMANAGER_DEBUG \r
+ io::IAttributes * const attr = smgr->getParameters();\r
str += " Cull:";\r
str += attr->getAttributeAsInt("calls");\r
str += "/";\r
\r
Driver = device->getVideoDriver ();\r
gui::IGUIEnvironment* guiEnv = device->getGUIEnvironment();\r
- scene::ISceneManager* smgr = device->getSceneManager();\r
+ //scene::ISceneManager* smgr = device->getSceneManager();\r
const video::SMaterial & material = node->getMaterial(0);\r
\r
s32 top = pos.Y;\r
f32 eggbox(s16 x, s16 y, f32 s)\r
{\r
const f32 r = 4.f*sqrtf((f32)(x*x + y*y))/s;\r
- const f32 z = expf(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));\r
+ const f32 z = (f32)exp(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));\r
return 0.25f+0.25f*z;\r
}\r
\r
public:\r
SMesh* Mesh;\r
\r
- TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f)\r
+ TMesh() : Width(0), Height(0), Scale(1.f), Mesh(0)\r
{\r
Mesh = new SMesh();\r
}\r
//we were at the end of the video section so we reset our tag\r
currentSection=L"";\r
break;\r
+ default:\r
+ break;\r
}\r
}\r
\r
}\r
}\r
break;\r
+ default:\r
+ break;\r
}\r
}\r
\r
bill = sm->addBillboardSceneNode(0, core::dimension2d<f32>(100,100),\r
waypoint[r]+ core::vector3df(0,20,0));\r
bill->setMaterialFlag(video::EMF_LIGHTING, false);\r
+ bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);\r
bill->setMaterialTexture(0, driver->getTexture(mediaPath + "portal1.bmp"));\r
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);\r
bill->addAnimator(anim);\r
const io::path mediaPath = getExampleMediaPath();\r
\r
// irrlicht logo\r
- device->getGUIEnvironment()->addImage(device->getVideoDriver()->getTexture(mediaPath + "irrlichtlogo2.png"),\r
+ device->getGUIEnvironment()->addImage(device->getVideoDriver()->getTexture(mediaPath + "irrlichtlogo3.png"),\r
core::position2d<s32>(5,5));\r
\r
// loading text\r
else\r
{\r
// doesnt collide with wall\r
- core::vector3df start = camera->getPosition();\r
- core::vector3df end = (camera->getTarget() - start);\r
+ start = camera->getPosition();\r
+ end = (camera->getTarget() - start);\r
end.normalize();\r
start += end*8.0f;\r
end = start + (end * camera->getFarValue());\r
\r
bool CMainMenu::run()\r
{\r
- video::E_DRIVER_TYPE driverType = EDT_OPENGL;\r
+ video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;\r
if (!IrrlichtDevice::isDriverSupported(video::EDT_OPENGL))\r
- driverType = video::video::EDT_BURNINGSVIDEO;\r
+ driverType = video::EDT_BURNINGSVIDEO;\r
\r
MenuDevice = createDevice(driverType,\r
core::dimension2d<u32>(512, 384), 16, false, false, false, this);\r
{\r
bill->setMaterialFlag(video::EMF_LIGHTING, false);\r
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);\r
+ bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);\r
bill->setMaterialTexture(0, driver->getTexture(mediaPath + "particlered.bmp"));\r
}\r
// add fly circle animator to the light\r
{\r
bill->setMaterialFlag(video::EMF_LIGHTING, false);\r
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);\r
+ bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);\r
bill->setMaterialTexture(0, driver->getTexture(mediaPath + "portal1.bmp"));\r
}\r
// add fly circle animator to the light\r
{\r
if (!selected)\r
{\r
- outDriver=video::E_DRIVER_TYPE(i);\r
+ driverType=video::E_DRIVER_TYPE(i);\r
break;\r
}\r
--selected;\r
aesGladman/pwd2key.cpp \
aesGladman/sha1.cpp \
aesGladman/sha2.cpp \
+ burning_shader_color.cpp \
C3DSMeshFileLoader.cpp \
CAnimatedMeshHalfLife.cpp \
CAnimatedMeshMD2.cpp \
CTRGouraudWire.cpp \
CTriangleBBSelector.cpp \
CTriangleSelector.cpp \
+ CTRGouraudNoZ2.cpp \
CTRNormalMap.cpp \
CTRStencilShadow.cpp \
CTRTextureBlend.cpp \
CTRTextureLightMap2_M4.cpp \
CTRTextureLightMapGouraud2_M4.cpp \
CTRTextureWire2.cpp \
+ CTR_transparent_reflection_2_layer.cpp \
CVideoModeList.cpp \
CVolumeLightSceneNode.cpp \
CWADReader.cpp \
if (FramesPerSecond > 0.f) //forwards...\r
{\r
if (CurrentFrameNr > EndFrame)\r
- CurrentFrameNr = StartFrame + fmod(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame));\r
+ CurrentFrameNr = StartFrame + fmodf(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame));\r
}\r
else //backwards...\r
{\r
if (CurrentFrameNr < StartFrame)\r
- CurrentFrameNr = EndFrame - fmod(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame));\r
+ CurrentFrameNr = EndFrame - fmodf(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame));\r
}\r
}\r
else\r
namespace irr\r
{\r
\r
+//! f18 - fixpoint 14.18 limit to 16k Textures\r
+#define CBLIT_USE_FIXPOINT18\r
+\r
+#if defined(CBLIT_USE_FIXPOINT18)\r
+ typedef int f18;\r
+ #define f18_one 262144\r
+ #define f18_zero 0\r
+ #define f32_to_f18(x)((f18)floorf(((x) * 262144.f) + 0.f))\r
+ #define f32_to_f32(x)(x)\r
+ #define f18_floor(x) ((x)>>18)\r
+ #define f18_round(x) ((x+131.072)>>18)\r
+#else\r
+ typedef float f18;\r
+ #define f18_one 1.f\r
+ #define f18_zero_dot_five 0.5f\r
+ #define f18_zero 0.f\r
+ #define f32_to_f18(x)(x)\r
+ #define f32_to_f32(x)(x)\r
+ #define f18_floor(x) ((int)(x))\r
+ #define f18_round(x) ((int)(x+0.5f))\r
+#endif\r
+\r
struct SBlitJob\r
{\r
AbsRectangle Dest;\r
\r
u32 argb;\r
\r
- void * src;\r
- void * dst;\r
+ const void* src;\r
+ void* dst;\r
\r
- s32 width;\r
- s32 height;\r
+ u32 width; //draw size\r
+ u32 height;\r
\r
- u32 srcPitch;\r
- u32 dstPitch;\r
-\r
- u32 srcPixelMul;\r
+ u32 srcPixelMul; //pixel byte size\r
u32 dstPixelMul;\r
\r
- bool stretch;\r
- float x_stretch;\r
- float y_stretch;\r
+ int srcPitch; //scanline byte size. allow negative for mirror\r
+ u32 dstPitch;\r
\r
- SBlitJob() : stretch(false) {}\r
+ bool stretch;\r
+ f32 x_stretch;\r
+ f32 y_stretch;\r
};\r
\r
// Bitfields Cohen Sutherland\r
}\r
\r
u32 *dst;\r
- dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) );\r
+ dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 4 ) );\r
\r
if ( dy > dx )\r
{\r
}\r
\r
u32 *dst;\r
- dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) );\r
+ dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 4 ) );\r
\r
if ( dy > dx )\r
{\r
}\r
\r
u16 *dst;\r
- dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) );\r
+ dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 2 ) );\r
\r
if ( dy > dx )\r
{\r
}\r
\r
u16 *dst;\r
- dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) );\r
+ dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 2 ) );\r
\r
if ( dy > dx )\r
{\r
*/\r
static void executeBlit_TextureCopy_x_to_x( const SBlitJob * job )\r
{\r
- const u32 w = job->width;\r
- const u32 h = job->height;\r
if (job->stretch)\r
{\r
- const u32 *src = static_cast<const u32*>(job->src);\r
- u32 *dst = static_cast<u32*>(job->dst);\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const f18 wscale = f32_to_f18(job->x_stretch);\r
+ const f18 hscale = f32_to_f18(job->y_stretch);\r
\r
- for ( u32 dy = 0; dy < h; ++dy )\r
+ f18 src_y = f18_zero;\r
+\r
+ if (job->srcPixelMul == 4)\r
{\r
- const u32 src_y = (u32)(dy*hscale);\r
- src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );\r
+ const u32 *src = (u32*)(job->src);\r
+ u32 *dst = (u32*)(job->dst);\r
\r
- for ( u32 dx = 0; dx < w; ++dx )\r
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
{\r
- const u32 src_x = (u32)(dx*wscale);\r
- dst[dx] = src[src_x];\r
+ src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+\r
+ f18 src_x = f18_zero;\r
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
+ {\r
+ dst[dx] = src[f18_floor(src_x)];\r
+ }\r
+ dst = (u32*)((u8*)(dst)+job->dstPitch);\r
+ }\r
+ }\r
+ else if (job->srcPixelMul == 2)\r
+ {\r
+ const u16 *src = (u16*)(job->src);\r
+ u16* dst = (u16*)(job->dst);\r
+\r
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
+ {\r
+ src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+\r
+ f18 src_x = f18_zero;\r
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
+ {\r
+ dst[dx] = src[f18_floor(src_x)];\r
+ }\r
+ dst = (u16*)((u8*)(dst)+job->dstPitch);\r
}\r
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
}\r
}\r
else\r
{\r
- const u32 widthPitch = job->width * job->dstPixelMul;\r
+ const size_t widthPitch = job->width * job->dstPixelMul;\r
const void *src = (void*) job->src;\r
void *dst = (void*) job->dst;\r
\r
- for ( u32 dy = 0; dy != h; ++dy )\r
+ for ( u32 dy = 0; dy < job->height; ++dy )\r
{\r
- memcpy( dst, src, widthPitch );\r
+ memcpy( dst, src, widthPitch);\r
\r
src = (void*) ( (u8*) (src) + job->srcPitch );\r
dst = (void*) ( (u8*) (dst) + job->dstPitch );\r
\r
if (job->stretch)\r
{\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const float wscale = job->x_stretch;\r
+ const float hscale = job->y_stretch;\r
\r
for ( u32 dy = 0; dy < h; ++dy )\r
{\r
\r
if (job->stretch)\r
{\r
- const float wscale = 3.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const float wscale = job->x_stretch * 3.f;\r
+ const float hscale = job->y_stretch;\r
\r
for ( u32 dy = 0; dy < h; ++dy )\r
{\r
\r
if (job->stretch)\r
{\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const float wscale = job->x_stretch;\r
+ const float hscale = job->y_stretch;\r
\r
for ( u32 dy = 0; dy < h; ++dy )\r
{\r
\r
if (job->stretch)\r
{\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const float wscale = job->x_stretch;\r
+ const float hscale = job->y_stretch;\r
\r
for ( u32 dy = 0; dy < h; ++dy )\r
{\r
\r
if (job->stretch)\r
{\r
- const float wscale = 3.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const float wscale = job->x_stretch * 3.f;\r
+ const float hscale = job->y_stretch;\r
\r
for ( u32 dy = 0; dy < h; ++dy )\r
{\r
}\r
else\r
{\r
- for ( s32 dy = 0; dy != job->height; ++dy )\r
+ for ( u32 dy = 0; dy < job->height; ++dy )\r
{\r
const u8* s = src;\r
\r
- for ( s32 dx = 0; dx != job->width; ++dx )\r
+ for ( u32 dx = 0; dx < job->width; ++dx )\r
{\r
dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2];\r
s += 3;\r
\r
if (job->stretch)\r
{\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const float wscale = job->x_stretch;\r
+ const float hscale = job->y_stretch;\r
\r
for ( u32 dy = 0; dy < h; ++dy )\r
{\r
*/\r
static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )\r
{\r
- const u32 w = job->width;\r
- const u32 h = job->height;\r
- const u32 rdx = w>>1;\r
+ const f18 wscale = f32_to_f18(job->x_stretch);\r
+ const f18 hscale = f32_to_f18(job->y_stretch);\r
\r
- const u32 *src = (u32*) job->src;\r
- u32 *dst = (u32*) job->dst;\r
+ f18 src_y = f18_zero;\r
+ u16 *dst = (u16*)job->dst;\r
\r
- if (job->stretch)\r
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
{\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
- const u32 off = core::if_c_a_else_b(w&1, (u32)((w-1)*wscale), 0);\r
- for ( u32 dy = 0; dy < h; ++dy )\r
+ const u16* src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+ f18 src_x = f18_zero;\r
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
{\r
- const u32 src_y = (u32)(dy*hscale);\r
- src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );\r
-\r
- for ( u32 dx = 0; dx < rdx; ++dx )\r
- {\r
- const u32 src_x = (u32)(dx*wscale);\r
- dst[dx] = PixelBlend16_simd( dst[dx], src[src_x] );\r
- }\r
- if ( off )\r
- {\r
- ((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );\r
- }\r
-\r
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
- }\r
- }\r
- else\r
- {\r
- const u32 off = core::if_c_a_else_b(w&1, w-1, 0);\r
- for (u32 dy = 0; dy != h; ++dy )\r
- {\r
- for (u32 dx = 0; dx != rdx; ++dx )\r
- {\r
- dst[dx] = PixelBlend16_simd( dst[dx], src[dx] );\r
- }\r
-\r
- if ( off )\r
- {\r
- ((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );\r
- }\r
-\r
- src = (u32*) ( (u8*) (src) + job->srcPitch );\r
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
+ dst[dx] = PixelBlend16(dst[dx], src[f18_floor(src_x)]);\r
}\r
+ dst = (u16*)((u8*)(dst)+job->dstPitch);\r
}\r
}\r
\r
*/\r
static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job )\r
{\r
- const u32 w = job->width;\r
- const u32 h = job->height;\r
- const u32 *src = (u32*) job->src;\r
- u32 *dst = (u32*) job->dst;\r
+ const f18 wscale = f32_to_f18(job->x_stretch);\r
+ const f18 hscale = f32_to_f18(job->y_stretch);\r
\r
- if (job->stretch)\r
+ f18 src_y = f18_zero;\r
+ u32 *dst = (u32*)job->dst;\r
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
{\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
- for ( u32 dy = 0; dy < h; ++dy )\r
- {\r
- const u32 src_y = (u32)(dy*hscale);\r
- src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );\r
-\r
- for ( u32 dx = 0; dx < w; ++dx )\r
- {\r
- const u32 src_x = (u32)(dx*wscale);\r
- dst[dx] = PixelBlend32( dst[dx], src[src_x] );\r
- }\r
+ const u32* src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
\r
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
- }\r
- }\r
- else\r
- {\r
- for ( u32 dy = 0; dy != h; ++dy )\r
+ f18 src_x = f18_zero;\r
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
{\r
- for ( u32 dx = 0; dx != w; ++dx )\r
- {\r
- dst[dx] = PixelBlend32( dst[dx], src[dx] );\r
- }\r
- src = (u32*) ( (u8*) (src) + job->srcPitch );\r
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
+ dst[dx] = PixelBlend32(dst[dx], src[f18_floor(src_x)]);\r
}\r
+ dst = (u32*)((u8*)(dst)+job->dstPitch);\r
}\r
}\r
\r
*/\r
static void executeBlit_TextureBlendColor_16_to_16( const SBlitJob * job )\r
{\r
- u16 *src = (u16*) job->src;\r
- u16 *dst = (u16*) job->dst;\r
+ const u16 blend = video::A8R8G8B8toA1R5G5B5(job->argb);\r
+\r
+ const f18 wscale = f32_to_f18(job->x_stretch);\r
+ const f18 hscale = f32_to_f18(job->y_stretch);\r
\r
- u16 blend = video::A8R8G8B8toA1R5G5B5 ( job->argb );\r
- for ( s32 dy = 0; dy != job->height; ++dy )\r
+ f18 src_y = f18_zero;\r
+ u16 *dst = (u16*)job->dst;\r
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
{\r
- for ( s32 dx = 0; dx != job->width; ++dx )\r
+ const u16* src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+ f18 src_x = f18_zero;\r
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
{\r
- if ( 0 == (src[dx] & 0x8000) )\r
+ register u16 c0 = src[f18_floor(src_x)];\r
+ if (0 == (c0 & 0x8000))\r
continue;\r
\r
- dst[dx] = PixelMul16_2( src[dx], blend );\r
+ dst[dx] = PixelMul16_2(c0, blend);\r
}\r
- src = (u16*) ( (u8*) (src) + job->srcPitch );\r
- dst = (u16*) ( (u8*) (dst) + job->dstPitch );\r
+ dst = (u16*)((u8*)(dst)+job->dstPitch);\r
}\r
}\r
\r
*/\r
static void executeBlit_TextureBlendColor_32_to_32( const SBlitJob * job )\r
{\r
- u32 *src = (u32*) job->src;\r
- u32 *dst = (u32*) job->dst;\r
+ const f18 wscale = f32_to_f18(job->x_stretch);\r
+ const f18 hscale = f32_to_f18(job->y_stretch);\r
\r
- for ( s32 dy = 0; dy != job->height; ++dy )\r
+ u32* dst = (u32*)job->dst;\r
+ f18 src_y = f18_zero;\r
+ for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
{\r
- for ( s32 dx = 0; dx != job->width; ++dx )\r
+ const u32* src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+\r
+ f18 src_x = f18_zero;\r
+ for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
{\r
- dst[dx] = PixelBlend32( dst[dx], PixelMul32_2( src[dx], job->argb ) );\r
+ dst[dx] = PixelBlend32(dst[dx], PixelMul32_2(src[f18_floor(src_x)], job->argb));\r
}\r
- src = (u32*) ( (u8*) (src) + job->srcPitch );\r
- dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
+ dst = (u32*)((u8*)(dst)+job->dstPitch);\r
}\r
}\r
\r
const u16 c = video::A8R8G8B8toA1R5G5B5(job->argb);\r
u16 *dst = (u16*) job->dst;\r
\r
- for ( s32 dy = 0; dy != job->height; ++dy )\r
+ for ( u32 dy = 0; dy < job->height; ++dy )\r
{\r
memset16(dst, c, job->srcPitch);\r
dst = (u16*) ( (u8*) (dst) + job->dstPitch );\r
{\r
u32 *dst = (u32*) job->dst;\r
\r
- for ( s32 dy = 0; dy != job->height; ++dy )\r
+ for ( u32 dy = 0; dy < job->height; ++dy )\r
{\r
memset32( dst, job->argb, job->srcPitch );\r
dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
return;\r
const u32 src = video::A8R8G8B8toA1R5G5B5( job->argb );\r
\r
- for ( s32 dy = 0; dy != job->height; ++dy )\r
+ for ( u32 dy = 0; dy != job->height; ++dy )\r
{\r
- for ( s32 dx = 0; dx != job->width; ++dx )\r
+ for ( u32 dx = 0; dx != job->width; ++dx )\r
{\r
- dst[dx] = 0x8000 | PixelBlend16( dst[dx], src, alpha );\r
+ dst[dx] = PixelBlend16( dst[dx], src, alpha );\r
}\r
dst = (u16*) ( (u8*) (dst) + job->dstPitch );\r
}\r
*/\r
static void executeBlit_ColorAlpha_32_to_32( const SBlitJob * job )\r
{\r
- u32 *dst = (u32*) job->dst;\r
-\r
const u32 alpha = extractAlpha( job->argb );\r
- const u32 src = job->argb;\r
+ if (0 == alpha)\r
+ return;\r
\r
- for ( s32 dy = 0; dy != job->height; ++dy )\r
+ u32 *dst = (u32*)job->dst;\r
+ for ( u32 dy = 0; dy < job->height; ++dy )\r
{\r
- for ( s32 dx = 0; dx != job->width; ++dx )\r
+ for ( u32 dx = 0; dx < job->width; ++dx )\r
{\r
- dst[dx] = (job->argb & 0xFF000000 ) | PixelBlend32( dst[dx], src, alpha );\r
+ dst[dx] = PixelBlend32( dst[dx], job->argb, alpha );\r
}\r
dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
}\r
+\r
+}\r
+\r
+/*!\r
+ Pixel =>\r
+ color = sourceAlpha > 0 ? source, else dest\r
+ alpha = max(destAlpha, sourceAlpha)\r
+*/\r
+inline u16 PixelCombine16(const u16 c2, const u16 c1)\r
+{\r
+ if (video::getAlpha(c1) > 0)\r
+ return c1;\r
+ else\r
+ return c2;\r
}\r
\r
/*!\r
\r
if (job->stretch)\r
{\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const float wscale = job->x_stretch;\r
+ const float hscale = job->y_stretch;\r
\r
for ( u32 dy = 0; dy < h; ++dy )\r
{\r
}\r
}\r
\r
+/*!\r
+ Pixel =>\r
+ color = dest * ( 1 - SourceAlpha ) + source * SourceAlpha,\r
+ alpha = destAlpha * ( 1 - SourceAlpha ) + sourceAlpha\r
+\r
+ where "1" means "full scale" (255)\r
+*/\r
+inline u32 PixelCombine32(const u32 c2, const u32 c1)\r
+{\r
+ // alpha test\r
+ u32 alpha = c1 & 0xFF000000;\r
+\r
+ if (0 == alpha)\r
+ return c2;\r
+ if (0xFF000000 == alpha)\r
+ {\r
+ return c1;\r
+ }\r
+\r
+ alpha >>= 24;\r
+\r
+ // add highbit alpha, if ( alpha > 127 ) alpha += 1;\r
+ // stretches [0;255] to [0;256] to avoid division by 255. use division 256 == shr 8\r
+ alpha += (alpha >> 7);\r
+\r
+ u32 srcRB = c1 & 0x00FF00FF;\r
+ u32 srcXG = c1 & 0x0000FF00;\r
+\r
+ u32 dstRB = c2 & 0x00FF00FF;\r
+ u32 dstXG = c2 & 0x0000FF00;\r
+\r
+\r
+ u32 rb = srcRB - dstRB;\r
+ u32 xg = srcXG - dstXG;\r
+\r
+ rb *= alpha;\r
+ xg *= alpha;\r
+ rb >>= 8;\r
+ xg >>= 8;\r
+\r
+ rb += dstRB;\r
+ xg += dstXG;\r
+\r
+ rb &= 0x00FF00FF;\r
+ xg &= 0x0000FF00;\r
+\r
+ u32 sa = c1 >> 24;\r
+ u32 da = c2 >> 24;\r
+ u32 blendAlpha_fix8 = (sa * 256 + da * (256 - alpha)) >> 8;\r
+ return blendAlpha_fix8 << 24 | rb | xg;\r
+}\r
+\r
/*!\r
Combine alpha channels (increases alpha / reduces transparency)\r
Destination alpha is treated as full 255\r
\r
if (job->stretch)\r
{\r
- const float wscale = 1.f/job->x_stretch;\r
- const float hscale = 1.f/job->y_stretch;\r
+ const float wscale = job->x_stretch;\r
+ const float hscale = job->y_stretch;\r
\r
for ( u32 dy = 0; dy < h; ++dy )\r
{\r
u32 *src = (u32*) job->src;\r
u32 *dst = (u32*) job->dst;\r
\r
- for ( s32 dy = 0; dy != job->height; ++dy )\r
+ for ( u32 dy = 0; dy != job->height; ++dy )\r
{\r
- for ( s32 dx = 0; dx != job->width; ++dx )\r
+ for (u32 dx = 0; dx != job->width; ++dx )\r
{\r
dst[dx] = PixelCombine32( dst[dx], PixelMul32_2( src[dx], job->argb ) );\r
}\r
\r
\r
// bounce clipping to texture\r
-inline void setClip ( AbsRectangle &out, const core::rect<s32> *clip,\r
- const video::IImage * tex, s32 passnative )\r
+inline void setClip(AbsRectangle &out, const core::rect<s32> *clip,\r
+ const video::IImage* tex, s32 passnative, const core::dimension2d<u32>* tex_org)\r
{\r
- if ( clip && 0 == tex && passnative )\r
+ if (0 == tex)\r
{\r
- out.x0 = clip->UpperLeftCorner.X;\r
- out.x1 = clip->LowerRightCorner.X;\r
- out.y0 = clip->UpperLeftCorner.Y;\r
- out.y1 = clip->LowerRightCorner.Y;\r
+ if (clip && passnative)\r
+ {\r
+ out.x0 = clip->UpperLeftCorner.X;\r
+ out.x1 = clip->LowerRightCorner.X;\r
+ out.y0 = clip->UpperLeftCorner.Y;\r
+ out.y1 = clip->LowerRightCorner.Y;\r
+ }\r
+ else\r
+ {\r
+ out.x0 = 0;\r
+ out.x1 = 0;\r
+ out.y0 = 0;\r
+ out.y1 = 0;\r
+ }\r
return;\r
}\r
\r
- const s32 w = tex ? tex->getDimension().Width : 0;\r
- const s32 h = tex ? tex->getDimension().Height : 0;\r
- if ( clip )\r
+ const s32 w = tex->getDimension().Width;\r
+ const s32 h = tex->getDimension().Height;\r
+\r
+ //driver could have changed texture size.\r
+ if (clip && tex_org && ((u32)w != tex_org->Width || (u32)h != tex_org->Height))\r
{\r
- out.x0 = core::s32_clamp ( clip->UpperLeftCorner.X, 0, w );\r
- out.x1 = core::s32_clamp ( clip->LowerRightCorner.X, out.x0, w );\r
- out.y0 = core::s32_clamp ( clip->UpperLeftCorner.Y, 0, h );\r
- out.y1 = core::s32_clamp ( clip->LowerRightCorner.Y, out.y0, h );\r
+ out.x0 = core::s32_clamp((clip->UpperLeftCorner.X*w) / tex_org->Width, 0, w - 1);\r
+ out.x1 = core::s32_clamp((clip->LowerRightCorner.X*w) / tex_org->Width, out.x0, w);\r
+ out.y0 = core::s32_clamp((clip->UpperLeftCorner.Y*h) / tex_org->Height, 0, h - 1);\r
+ out.y1 = core::s32_clamp((clip->LowerRightCorner.Y*h) / tex_org->Height, out.y0, h);\r
+ }\r
+ else if (clip)\r
+ {\r
+ //y-1 to prevent starting on illegal memory (not ideal!).\r
+ out.x0 = core::s32_clamp(clip->UpperLeftCorner.X, 0, w - 1);\r
+ out.x1 = core::s32_clamp(clip->LowerRightCorner.X, passnative ? 0 : out.x0, w);\r
+ out.y0 = core::s32_clamp(clip->UpperLeftCorner.Y, 0, h - 1);\r
+ out.y1 = core::s32_clamp(clip->LowerRightCorner.Y, passnative ? 0 : out.y0, h);\r
}\r
else\r
{\r
\r
SBlitJob job;\r
\r
- setClip ( sourceClip, sourceClipping, source, 1 );\r
- setClip ( destClip, destClipping, dest, 0 );\r
+ setClip ( sourceClip, sourceClipping, source, 1,0 );\r
+ setClip ( destClip, destClipping, dest, 0,0 );\r
\r
v.x0 = destPos ? destPos->X : 0;\r
v.y0 = destPos ? destPos->Y : 0;\r
\r
job.argb = argb;\r
\r
+ job.stretch = false;\r
+ job.x_stretch = 1.f;\r
+ job.y_stretch = 1.f;\r
+\r
if ( source )\r
{\r
job.srcPitch = source->getPitch();\r
return 1;\r
}\r
\r
+#if defined(SOFTWARE_DRIVER_2_2D_AS_2D)\r
static s32 StretchBlit(eBlitter operation,\r
- video::IImage* dest, const core::rect<s32> *destRect,\r
- const core::rect<s32> *srcRect, video::IImage* const source,\r
+ video::IImage* dest, const core::rect<s32>* destClipping,const core::rect<s32> *destRect,\r
+ video::IImage* const source,const core::rect<s32> *srcRect, const core::dimension2d<u32>* source_org,\r
u32 argb)\r
{\r
tExecuteBlit blitter = getBlitter2( operation, dest, source );\r
\r
SBlitJob job;\r
\r
+ AbsRectangle destClip;\r
+ AbsRectangle v;\r
+ setClip(destClip, destClipping, dest, 0, 0);\r
+ setClip(v, destRect, 0, 1, 0);\r
+ if (!intersect(job.Dest, destClip, v))\r
+ return 0;\r
+\r
// Clipping\r
- setClip ( job.Source, srcRect, source, 1 );\r
- setClip ( job.Dest, destRect, dest, 0 );\r
+ setClip ( job.Source, srcRect, source, 1, source_org);\r
\r
job.width = job.Dest.x1-job.Dest.x0;\r
job.height = job.Dest.y1-job.Dest.y0;\r
job.argb = argb;\r
\r
// use original dest size, despite any clipping\r
- job.x_stretch = (float)destRect->getWidth() / (float)(job.Source.x1-job.Source.x0);\r
- job.y_stretch = (float)destRect->getHeight() / (float)(job.Source.y1-job.Source.y0);\r
- job.stretch = (job.x_stretch != 1.f) || (job.y_stretch != 1.f);\r
+ const int dst_w = v.x1 - v.x0; // destRect->getWidth();\r
+ const int dst_h = v.y1 - v.y0; // destRect->getHeight();\r
+ const int src_w = job.Source.x1 - job.Source.x0;\r
+ const int src_h = job.Source.y1 - job.Source.y0;\r
+\r
+ job.stretch = dst_w != src_w || dst_h != src_h;\r
+ job.x_stretch = dst_w ? (float)src_w / (float)dst_w : 1.f;\r
+ job.y_stretch = dst_h ? (float)src_h / (float)dst_h : 1.f;\r
+\r
\r
if ( source )\r
{\r
job.srcPitch = source->getPitch();\r
job.srcPixelMul = source->getBytesPerPixel();\r
+\r
+ //dest-clippling. advance source. loosing subpixel precision\r
+ job.Source.x0 += (s32)floorf(job.x_stretch * (job.Dest.x0 - v.x0));\r
+ job.Source.y0 += (s32)floorf(job.y_stretch * (job.Dest.y0 - v.y0));\r
+\r
job.src = (void*) ( (u8*) source->getData() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) );\r
}\r
else\r
\r
return 1;\r
}\r
-\r
+#endif\r
\r
// Methods for Software drivers\r
//! draws a rectangle\r
#include "IrrCompileConfig.h"\r
#include "IBurningShader.h"\r
\r
-#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+#if defined(_IRR_COMPILE_WITH_BURNINGSVIDEO_) && 0\r
\r
\r
namespace irr\r
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );\r
\r
\r
- pShader.dst[pShader.i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+ pShader.dst[pShader.i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
);\r
ty0 = tofix ( line.t[0][0].y, inversew );\r
\r
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );\r
- pShader.dst[pShader.i] = fix_to_color ( r0, g0, b0 );\r
+ pShader.dst[pShader.i] = fix_to_sample( r0, g0, b0 );\r
\r
}\r
\r
REALINLINE void CBurningShader_Raster_Reference::scanline2()\r
{\r
// apply top-left fill-convention, left\r
- pShader.xStart = core::ceil32_fast( line.x[0] );\r
- pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ pShader.xStart = fill_convention_left( line.x[0] );\r
+ pShader.xEnd = fill_convention_right( line.x[1] );\r
\r
pShader.dx = pShader.xEnd - pShader.xStart;\r
if ( pShader.dx < 0 )\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];\r
\r
// store slopes in endpoint, and correct first pixel\r
\r
u32 i;\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;\r
line.t[i][0] += line.t[i][1] * subPixel;\r
}\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK_REF;\r
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );\r
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );\r
\r
// advance next pixel\r
line.w[0] += line.w[1];\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
line.c[i][0] += line.c[i][1];\r
u32 i;\r
\r
// apply top-left fill-convention, left\r
- pShader.xStart = core::ceil32_fast( line.x[0] );\r
- pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ pShader.xStart = fill_convention_left( line.x[0] );\r
+ pShader.xEnd = fill_convention_right( line.x[1] );\r
\r
pShader.dx = pShader.xEnd - pShader.xStart;\r
if ( pShader.dx < 0 )\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
// search z-buffer for first not occulled pixel\r
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );\r
case BD3DCMP_EQUAL:\r
condition = a != pShader.z[pShader.i];\r
break;\r
+ default:\r
+ condition = 0;\r
+ break;\r
}\r
while ( a < pShader.z[pShader.i] )\r
{\r
\r
a = (f32) pShader.i + subPixel;\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;\r
\r
line.w[0] += line.w[1];\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
line.c[i][0] += line.c[i][1];\r
}\r
\r
\r
-void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
sScanConvertData scan;\r
u32 i;\r
\r
\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y );\r
- scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y );\r
- scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y );\r
+ scan.invDeltaY[0] = reciprocal_zero2( c->Pos.y - a->Pos.y );\r
+ scan.invDeltaY[1] = reciprocal_zero2( b->Pos.y - a->Pos.y );\r
+ scan.invDeltaY[2] = reciprocal_zero2( c->Pos.y - b->Pos.y );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];\r
scan.w[0] = a->Pos.w;\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
scan.c[i][0] = a->Color[i];\r
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];\r
scan.w[1] = a->Pos.w;\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
scan.c[i][1] = a->Color[i];\r
}\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
\r
scan.w[0] += scan.slopeW[0] * subPixel;\r
scan.w[1] += scan.slopeW[1] * subPixel;\r
\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
scan.c[i][0] += scan.slopeC[i][0] * subPixel;\r
scan.c[i][1] += scan.slopeC[i][1] * subPixel;\r
}\r
-\r
+#endif\r
for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
{\r
scan.t[i][0] += scan.slopeT[i][0] * subPixel;\r
line.x[scan.right] = scan.x[1];\r
line.w[scan.right] = scan.w[1];\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
line.c[i][scan.left] = scan.c[i][0];\r
scan.w[0] += scan.slopeW[0];\r
scan.w[1] += scan.slopeW[1];\r
\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
scan.c[i][0] += scan.slopeC[i][0];\r
scan.c[i][1] += scan.slopeC[i][1];\r
}\r
-\r
+#endif\r
for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
{\r
scan.t[i][0] += scan.slopeT[i][0];\r
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];\r
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
scan.c[i][0] = a->Color[i] + scan.slopeC[i][0] * temp[0];\r
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];\r
scan.w[1] = b->Pos.w;\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
scan.c[i][1] = b->Color[i];\r
}\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
\r
subPixel = ( (f32) yStart ) - b->Pos.y;\r
scan.w[0] += scan.slopeW[0] * subPixel;\r
scan.w[1] += scan.slopeW[1] * subPixel;\r
\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
scan.c[i][0] += scan.slopeC[i][0] * subPixel;\r
scan.c[i][1] += scan.slopeC[i][1] * subPixel;\r
}\r
-\r
+#endif\r
for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
{\r
scan.t[i][0] += scan.slopeT[i][0] * subPixel;\r
line.x[scan.right] = scan.x[1];\r
line.w[scan.right] = scan.w[1];\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
line.c[i][scan.left] = scan.c[i][0];\r
scan.w[0] += scan.slopeW[0];\r
scan.w[1] += scan.slopeW[1];\r
\r
- for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+ for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
{\r
scan.c[i][0] += scan.slopeC[i][0];\r
scan.c[i][1] += scan.slopeC[i][1];\r
}\r
-\r
+#endif\r
for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
{\r
scan.t[i][0] += scan.slopeT[i][0];\r
//! destructor\r
CDepthBuffer::~CDepthBuffer()\r
{\r
- delete [] Buffer;\r
+ if (Buffer)\r
+ {\r
+ delete[] Buffer;\r
+ Buffer = 0;\r
+ }\r
}\r
\r
\r
\r
//! clears the zbuffer\r
-void CDepthBuffer::clear()\r
+void CDepthBuffer::clear(f32 value)\r
{\r
+ ieee754 zMaxValue;\r
\r
#ifdef SOFTWARE_DRIVER_2_USE_WBUFFER\r
- f32 zMax = 0.f;\r
+ zMaxValue.f = 1.f-value;\r
#else\r
- f32 zMax = 1.f;\r
+ zMaxValue.f = value;\r
#endif\r
\r
- u32 zMaxValue;\r
- zMaxValue = IR(zMax);\r
-\r
- memset32 ( Buffer, zMaxValue, TotalSize );\r
+ memset32 ( Buffer, zMaxValue.u, TotalSize );\r
}\r
\r
\r
\r
-//! sets the new size of the zbuffer\r
+//! sets the new size of the buffer\r
void CDepthBuffer::setSize(const core::dimension2d<u32>& size)\r
{\r
if (size == Size)\r
\r
Pitch = size.Width * sizeof ( fp24 );\r
TotalSize = Pitch * size.Height;\r
- Buffer = new u8[TotalSize];\r
+ Buffer = new u8[align_next(TotalSize,16)];\r
clear ();\r
}\r
\r
\r
\r
-//! returns the size of the zbuffer\r
+//! returns the size of the buffer\r
const core::dimension2d<u32>& CDepthBuffer::getSize() const\r
{\r
return Size;\r
// -----------------------------------------------------------------\r
\r
//! constructor\r
-CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size)\r
-: Buffer(0), Size(0,0)\r
+CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size, unsigned bit)\r
+: Buffer(0), Size(0,0),Bit(bit)\r
{\r
#ifdef _DEBUG\r
- setDebugName("CDepthBuffer");\r
+ setDebugName("CStencilBuffer");\r
#endif\r
\r
setSize(size);\r
//! destructor\r
CStencilBuffer::~CStencilBuffer()\r
{\r
- delete [] Buffer;\r
+ if (Buffer)\r
+ {\r
+ delete[] Buffer;\r
+ Buffer = 0;\r
+ }\r
}\r
\r
\r
\r
-//! clears the zbuffer\r
-void CStencilBuffer::clear()\r
+//! clears the buffer\r
+void CStencilBuffer::clear(u8 value)\r
{\r
- memset32 ( Buffer, 0, TotalSize );\r
+ u32 set = value;\r
+ if (Bit == 8)\r
+ {\r
+ set |= set << 8;\r
+ set |= set << 16;\r
+ }\r
+ memset32 ( Buffer, set, TotalSize );\r
}\r
\r
\r
\r
-//! sets the new size of the zbuffer\r
+//! sets the new size of the buffer\r
void CStencilBuffer::setSize(const core::dimension2d<u32>& size)\r
{\r
if (size == Size)\r
\r
delete [] Buffer;\r
\r
- Pitch = size.Width * sizeof ( u32 );\r
+ Pitch = size.Width * sizeof (tStencilSample);\r
TotalSize = Pitch * size.Height;\r
- Buffer = new u8[TotalSize];\r
+ Buffer = new u8[align_next(TotalSize,16)];\r
clear ();\r
}\r
\r
\r
\r
-//! returns the size of the zbuffer\r
+//! returns the size of the buffer\r
const core::dimension2d<u32>& CStencilBuffer::getSize() const\r
{\r
return Size;\r
}\r
\r
\r
-//! creates a ZBuffer\r
-IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size)\r
+//! creates a Stencil Buffer\r
+IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size, u32 bit)\r
{\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
- return new CStencilBuffer(size);\r
+ return new CStencilBuffer(size,bit);\r
#else\r
return 0;\r
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
virtual ~CDepthBuffer();\r
\r
//! clears the zbuffer\r
- virtual void clear() _IRR_OVERRIDE_;\r
+ virtual void clear(f32 value=1.f) _IRR_OVERRIDE_;\r
\r
//! sets the new size of the zbuffer\r
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;\r
public:\r
\r
//! constructor\r
- CStencilBuffer(const core::dimension2d<u32>& size);\r
+ CStencilBuffer(const core::dimension2d<u32>& size, unsigned bit);\r
\r
//! destructor\r
virtual ~CStencilBuffer();\r
\r
//! clears the zbuffer\r
- virtual void clear() _IRR_OVERRIDE_;\r
+ virtual void clear(u8 value=0) _IRR_OVERRIDE_;\r
\r
//! sets the new size of the zbuffer\r
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;\r
\r
\r
private:\r
-\r
u8* Buffer;\r
core::dimension2d<u32> Size;\r
u32 TotalSize;\r
u32 Pitch;\r
+ u32 Bit;\r
};\r
\r
} // end namespace video\r
s.IsSeparator = (text == 0);\r
s.SubMenu = 0;\r
s.CommandId = commandId;\r
+ s.PosY = 0;\r
\r
if (hasSubMenu)\r
{\r
#include "CColorConverter.h"\r
#include "CBlit.h"\r
#include "os.h"\r
+#include "SoftwareDriver2_helper.h"\r
\r
namespace irr\r
{\r
{\r
const u32 dataSize = getDataSizeFromFormat(Format, Size.Width, Size.Height);\r
\r
- Data = new u8[dataSize];\r
+ Data = new u8[align_next(dataSize,16)];\r
memcpy(Data, data, dataSize);\r
DeleteMemory = true;\r
}\r
//! Constructor of empty image\r
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) : IImage(format, size, true)\r
{\r
- Data = new u8[getDataSizeFromFormat(Format, Size.Width, Size.Height)];\r
+ Data = new u8[align_next(getDataSizeFromFormat(Format, Size.Width, Size.Height),16)];\r
DeleteMemory = true;\r
}\r
\r
return;\r
}\r
\r
- if ( !Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)\r
+ if (!Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)\r
&& target && pos.X == 0 && pos.Y == 0 &&\r
- CColorConverter::canConvertFormat(Format, target->getColorFormat()) )\r
+ CColorConverter::canConvertFormat(Format, target->getColorFormat()))\r
{\r
// No fast blitting, but copyToScaling uses other color conversions and might work\r
irr::core::dimension2du dim(target->getDimension());\r
return;\r
}\r
\r
- if ( combineAlpha )\r
- {\r
- Blit(BLITTER_TEXTURE_COMBINE_ALPHA, target, clipRect, &pos, this, &sourceRect, color.color);\r
- }\r
- else\r
- {\r
- // color blend only necessary on not full spectrum aka. color.color != 0xFFFFFFFF\r
- Blit(color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND: BLITTER_TEXTURE_ALPHA_COLOR_BLEND,\r
- target, clipRect, &pos, this, &sourceRect, color.color);\r
- }\r
+ eBlitter op = combineAlpha ? BLITTER_TEXTURE_COMBINE_ALPHA :\r
+ color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND;\r
+ Blit(op,target, clipRect, &pos, this, &sourceRect, color.color);\r
}\r
\r
\r
}\r
\r
\r
+\r
} // end namespace video\r
} // end namespace irr\r
// limit the count value to the remaining row size\r
if (oPtr + count*rgb.Header.BPC > buf + rgb.Header.Xsize * rgb.Header.BPC)\r
{\r
- count = ( (buf + rgb.Header.Xsize * rgb.Header.BPC) - oPtr ) / rgb.Header.BPC;\r
+ count = (s32)( (buf + rgb.Header.Xsize * rgb.Header.BPC) - oPtr ) / rgb.Header.BPC;\r
}\r
\r
if (count<=0)\r
{\r
SMyMaterialEntry ()\r
: Texture1FileName("null"), Texture2FileName("null"),\r
- Texture1(0), Texture2(0), MaterialType(video::EMT_SOLID) {}\r
+ Texture1(0), Texture2(0), MaterialType(video::EMT_SOLID) {\r
+ Header.Name[0] = 0;\r
+ }\r
\r
SMyMaterialHeader Header;\r
core::stringc Texture1FileName;\r
smoothingGroup=0;\r
else\r
smoothingGroup=core::strtoul10(smooth);\r
+\r
+ (void)smoothingGroup; // disable unused variable warnings\r
}\r
break;\r
\r
if (file)\r
{\r
char buffer[1024];\r
- fread(buffer, 1, 1024, file);\r
+ size_t r = fread(buffer, 1, 1023, file);\r
+ buffer[r] = 0;\r
buffer[1023]=0;\r
core::stringc str(buffer);\r
s32 pos = str.find("cpu MHz");\r
{\r
}\r
\r
+ virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,\r
+ bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_\r
+ {\r
+ if (Driver)\r
+ Driver->setFallback_Material(material.MaterialType);\r
+ }\r
+\r
protected:\r
\r
video::CBurningVideoDriver* Driver;\r
};\r
\r
\r
-\r
//! Transparent material renderer\r
class CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR : public CSoftware2MaterialRenderer\r
{\r
\r
};\r
\r
-//! unsupported material renderer\r
-class CBurningShader_REFERENCE : public CSoftware2MaterialRenderer\r
-{\r
-public:\r
- CBurningShader_REFERENCE ( video::CBurningVideoDriver* driver )\r
- : CSoftware2MaterialRenderer ( driver ) {}\r
-\r
- virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,\r
- bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_\r
- {\r
- }\r
-\r
- virtual void OnUnsetMaterial() _IRR_OVERRIDE_\r
- {\r
- }\r
-\r
- virtual bool isTransparent() const _IRR_OVERRIDE_\r
- {\r
- return false;\r
- }\r
-\r
- virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_\r
- {\r
- return true;\r
- };\r
-\r
-\r
- virtual s32 getRenderCapability() const _IRR_OVERRIDE_\r
- {\r
- return 1;\r
- }\r
-\r
-};\r
-\r
\r
\r
} // end namespace video\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
\r
#include "SoftwareDriver2_helper.h"\r
+#include "CSoftwareTexture.h"\r
#include "CSoftwareTexture2.h"\r
#include "CSoftware2MaterialRenderer.h"\r
#include "S3DVertex.h"\r
#include "CBlit.h"\r
\r
\r
-#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( tex ) )\r
+// Matrix now here\r
+\r
+template <class T>\r
+bool mat44_transposed_inverse(irr::core::CMatrix4<T>& out, const irr::core::CMatrix4<T>& M)\r
+{\r
+ const T* burning_restrict m = M.pointer();\r
+\r
+ double d =\r
+ (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) -\r
+ (m[0] * m[6] - m[2] * m[4]) * (m[9] * m[15] - m[11] * m[13]) +\r
+ (m[0] * m[7] - m[3] * m[4]) * (m[9] * m[14] - m[10] * m[13]) +\r
+ (m[1] * m[6] - m[2] * m[5]) * (m[8] * m[15] - m[11] * m[12]) -\r
+ (m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) +\r
+ (m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]);\r
+\r
+ if (fabs(d) < DBL_MIN)\r
+ {\r
+ out.makeIdentity();\r
+ return false;\r
+ }\r
+\r
+ d = 1.0 / d;\r
+ T* burning_restrict o = out.pointer();\r
+ o[0] = (T)(d*(m[5] * (m[10] * m[15] - m[11] * m[14]) + m[6] * (m[11] * m[13] - m[9] * m[15]) + m[7] * (m[9] * m[14] - m[10] * m[13])));\r
+ o[4] = (T)(d*(m[9] * (m[2] * m[15] - m[3] * m[14]) + m[10] * (m[3] * m[13] - m[1] * m[15]) + m[11] * (m[1] * m[14] - m[2] * m[13])));\r
+ o[8] = (T)(d*(m[13] * (m[2] * m[7] - m[3] * m[6]) + m[14] * (m[3] * m[5] - m[1] * m[7]) + m[15] * (m[1] * m[6] - m[2] * m[5])));\r
+ o[12] = (T)(d*(m[1] * (m[7] * m[10] - m[6] * m[11]) + m[2] * (m[5] * m[11] - m[7] * m[9]) + m[3] * (m[6] * m[9] - m[5] * m[10])));\r
+\r
+ o[1] = (T)(d*(m[6] * (m[8] * m[15] - m[11] * m[12]) + m[7] * (m[10] * m[12] - m[8] * m[14]) + m[4] * (m[11] * m[14] - m[10] * m[15])));\r
+ o[5] = (T)(d*(m[10] * (m[0] * m[15] - m[3] * m[12]) + m[11] * (m[2] * m[12] - m[0] * m[14]) + m[8] * (m[3] * m[14] - m[2] * m[15])));\r
+ o[9] = (T)(d*(m[14] * (m[0] * m[7] - m[3] * m[4]) + m[15] * (m[2] * m[4] - m[0] * m[6]) + m[12] * (m[3] * m[6] - m[2] * m[7])));\r
+ o[13] = (T)(d*(m[2] * (m[7] * m[8] - m[4] * m[11]) + m[3] * (m[4] * m[10] - m[6] * m[8]) + m[0] * (m[6] * m[11] - m[7] * m[10])));\r
+\r
+ o[2] = (T)(d*(m[7] * (m[8] * m[13] - m[9] * m[12]) + m[4] * (m[9] * m[15] - m[11] * m[13]) + m[5] * (m[11] * m[12] - m[8] * m[15])));\r
+ o[6] = (T)(d*(m[11] * (m[0] * m[13] - m[1] * m[12]) + m[8] * (m[1] * m[15] - m[3] * m[13]) + m[9] * (m[3] * m[12] - m[0] * m[15])));\r
+ o[10] = (T)(d*(m[15] * (m[0] * m[5] - m[1] * m[4]) + m[12] * (m[1] * m[7] - m[3] * m[5]) + m[13] * (m[3] * m[4] - m[0] * m[7])));\r
+ o[14] = (T)(d*(m[3] * (m[5] * m[8] - m[4] * m[9]) + m[0] * (m[7] * m[9] - m[5] * m[11]) + m[1] * (m[4] * m[11] - m[7] * m[8])));\r
+\r
+ o[3] = (T)(d*(m[4] * (m[10] * m[13] - m[9] * m[14]) + m[5] * (m[8] * m[14] - m[10] * m[12]) + m[6] * (m[9] * m[12] - m[8] * m[13])));\r
+ o[7] = (T)(d*(m[8] * (m[2] * m[13] - m[1] * m[14]) + m[9] * (m[0] * m[14] - m[2] * m[12]) + m[10] * (m[1] * m[12] - m[0] * m[13])));\r
+ o[11] = (T)(d*(m[12] * (m[2] * m[5] - m[1] * m[6]) + m[13] * (m[0] * m[6] - m[2] * m[4]) + m[14] * (m[1] * m[4] - m[0] * m[5])));\r
+ o[15] = (T)(d*(m[0] * (m[5] * m[10] - m[6] * m[9]) + m[1] * (m[6] * m[8] - m[4] * m[10]) + m[2] * (m[4] * m[9] - m[5] * m[8])));\r
+\r
+ return true;\r
+}\r
+\r
+#if 0\r
+// difference to CMatrix4<T>::getInverse . higher precision in determinant. return identity on failure\r
+template <class T>\r
+bool mat44_inverse(CMatrix4<T>& out, const CMatrix4<T>& M)\r
+{\r
+ const T* m = M.pointer();\r
+\r
+ double d =\r
+ (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) -\r
+ (m[0] * m[6] - m[2] * m[4]) * (m[9] * m[15] - m[11] * m[13]) +\r
+ (m[0] * m[7] - m[3] * m[4]) * (m[9] * m[14] - m[10] * m[13]) +\r
+ (m[1] * m[6] - m[2] * m[5]) * (m[8] * m[15] - m[11] * m[12]) -\r
+ (m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) +\r
+ (m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]);\r
+\r
+ if (fabs(d) < DBL_MIN)\r
+ {\r
+ out.makeIdentity();\r
+ return false;\r
+ }\r
+\r
+ d = 1.0 / d;\r
+ T* o = out.pointer();\r
+ o[0] = (T)(d*(m[5] * (m[10] * m[15] - m[11] * m[14]) + m[6] * (m[11] * m[13] - m[9] * m[15]) + m[7] * (m[9] * m[14] - m[10] * m[13])));\r
+ o[1] = (T)(d*(m[9] * (m[2] * m[15] - m[3] * m[14]) + m[10] * (m[3] * m[13] - m[1] * m[15]) + m[11] * (m[1] * m[14] - m[2] * m[13])));\r
+ o[2] = (T)(d*(m[13] * (m[2] * m[7] - m[3] * m[6]) + m[14] * (m[3] * m[5] - m[1] * m[7]) + m[15] * (m[1] * m[6] - m[2] * m[5])));\r
+ o[3] = (T)(d*(m[1] * (m[7] * m[10] - m[6] * m[11]) + m[2] * (m[5] * m[11] - m[7] * m[9]) + m[3] * (m[6] * m[9] - m[5] * m[10])));\r
+\r
+ o[4] = (T)(d*(m[6] * (m[8] * m[15] - m[11] * m[12]) + m[7] * (m[10] * m[12] - m[8] * m[14]) + m[4] * (m[11] * m[14] - m[10] * m[15])));\r
+ o[5] = (T)(d*(m[10] * (m[0] * m[15] - m[3] * m[12]) + m[11] * (m[2] * m[12] - m[0] * m[14]) + m[8] * (m[3] * m[14] - m[2] * m[15])));\r
+ o[6] = (T)(d*(m[14] * (m[0] * m[7] - m[3] * m[4]) + m[15] * (m[2] * m[4] - m[0] * m[6]) + m[12] * (m[3] * m[6] - m[2] * m[7])));\r
+ o[7] = (T)(d*(m[2] * (m[7] * m[8] - m[4] * m[11]) + m[3] * (m[4] * m[10] - m[6] * m[8]) + m[0] * (m[6] * m[11] - m[7] * m[10])));\r
+\r
+ o[8] = (T)(d*(m[7] * (m[8] * m[13] - m[9] * m[12]) + m[4] * (m[9] * m[15] - m[11] * m[13]) + m[5] * (m[11] * m[12] - m[8] * m[15])));\r
+ o[9] = (T)(d*(m[11] * (m[0] * m[13] - m[1] * m[12]) + m[8] * (m[1] * m[15] - m[3] * m[13]) + m[9] * (m[3] * m[12] - m[0] * m[15])));\r
+ o[10] = (T)(d*(m[15] * (m[0] * m[5] - m[1] * m[4]) + m[12] * (m[1] * m[7] - m[3] * m[5]) + m[13] * (m[3] * m[4] - m[0] * m[7])));\r
+ o[11] = (T)(d*(m[3] * (m[5] * m[8] - m[4] * m[9]) + m[0] * (m[7] * m[9] - m[5] * m[11]) + m[1] * (m[4] * m[11] - m[7] * m[8])));\r
+\r
+ o[12] = (T)(d*(m[4] * (m[10] * m[13] - m[9] * m[14]) + m[5] * (m[8] * m[14] - m[10] * m[12]) + m[6] * (m[9] * m[12] - m[8] * m[13])));\r
+ o[13] = (T)(d*(m[8] * (m[2] * m[13] - m[1] * m[14]) + m[9] * (m[0] * m[14] - m[2] * m[12]) + m[10] * (m[1] * m[12] - m[0] * m[13])));\r
+ o[14] = (T)(d*(m[12] * (m[2] * m[5] - m[1] * m[6]) + m[13] * (m[0] * m[6] - m[2] * m[4]) + m[14] * (m[1] * m[4] - m[0] * m[5])));\r
+ o[15] = (T)(d*(m[0] * (m[5] * m[10] - m[6] * m[9]) + m[1] * (m[6] * m[8] - m[4] * m[10]) + m[2] * (m[4] * m[9] - m[5] * m[8])));\r
+\r
+ return true;\r
+}\r
+#endif\r
+\r
+// void CMatrix4<T>::transformVec4(T *out, const T * in) const\r
+template <class T>\r
+inline void transformVec4Vec4(const irr::core::CMatrix4<T>& m, T* burning_restrict out, const T* burning_restrict in)\r
+{\r
+ const T* burning_restrict M = m.pointer();\r
+\r
+ out[0] = in[0] * M[0] + in[1] * M[4] + in[2] * M[8] + in[3] * M[12];\r
+ out[1] = in[0] * M[1] + in[1] * M[5] + in[2] * M[9] + in[3] * M[13];\r
+ out[2] = in[0] * M[2] + in[1] * M[6] + in[2] * M[10] + in[3] * M[14];\r
+ out[3] = in[0] * M[3] + in[1] * M[7] + in[2] * M[11] + in[3] * M[15];\r
+}\r
+\r
+#if 0\r
+// void CMatrix4<T>::transformVect(T *out, const core::vector3df &in) const\r
+template <class T>\r
+inline void transformVec3Vec4(const irr::core::CMatrix4<T>& m,T* burning_restrict out, const core::vector3df &in)\r
+{\r
+ const T* burning_restrict M = m.pointer();\r
+ out[0] = in.X*M[0] + in.Y*M[4] + in.Z*M[8] + M[12];\r
+ out[1] = in.X*M[1] + in.Y*M[5] + in.Z*M[9] + M[13];\r
+ out[2] = in.X*M[2] + in.Y*M[6] + in.Z*M[10] + M[14];\r
+ out[3] = in.X*M[3] + in.Y*M[7] + in.Z*M[11] + M[15];\r
+}\r
+#endif\r
+\r
+template <class T>\r
+inline void rotateVec3Vec4(const irr::core::CMatrix4<T>& m, T* burning_restrict out, const T* burning_restrict in)\r
+{\r
+ const T* burning_restrict M = m.pointer();\r
+\r
+ out[0] = in[0] * M[0] + in[1] * M[4] + in[2] * M[8];\r
+ out[1] = in[0] * M[1] + in[1] * M[5] + in[2] * M[9];\r
+ out[2] = in[0] * M[2] + in[1] * M[6] + in[2] * M[10];\r
+ out[3] = 0.f;\r
+}\r
+\r
+//based on https://github.com/ekmett/approximate/blob/master/cbits/fast.c powf_fast_precise\r
+static inline float powf_limit(const float a, const float b)\r
+{\r
+ if (a <= 0.0000001f) return 0.f;\r
+ else if (a >= 1.f) return 1.f;\r
+\r
+ /* calculate approximation with fraction of the exponent */\r
+ int e = (int)b;\r
+ union { float f; int x; } u = { a };\r
+ u.x = (int)((b - e) * (u.x - 1065353216) + 1065353216);\r
+\r
+ float r = 1.0f;\r
+ float ua = a;\r
+ while (e) {\r
+ if (e & 1) {\r
+ r *= ua;\r
+ }\r
+ if (ua < 0.00000001f)\r
+ break;\r
+ ua *= ua;\r
+ e >>= 1;\r
+ }\r
+\r
+ r *= u.f;\r
+ return r;\r
+}\r
+\r
+\r
+#if defined(Tweak_Burning)\r
+\r
+// run time parameter\r
+struct tweakBurning\r
+{\r
+ tweakBurning()\r
+ {\r
+ current = 11;\r
+ step = 0.0001f;\r
+\r
+ ndc_shrink_x = -0.75f;\r
+ ndc_scale_x = 0.5f;\r
+ ndc_trans_x = -0.5f;\r
+\r
+ ndc_shrink_y = -0.75f;\r
+ ndc_scale_y = -0.5f;\r
+ ndc_trans_y = -0.5f;\r
+\r
+ tex_w_add = 0.f;\r
+ tex_h_add = 0.f;\r
+ tex_cx_add = 0.f;\r
+ tex_cy_add = 0.f;\r
+\r
+ AreaMinDrawSize = 0.001f;\r
+ }\r
+ int current;\r
+\r
+ union\r
+ {\r
+ struct {\r
+ f32 step;\r
+\r
+ f32 ndc_shrink_x;\r
+ f32 ndc_scale_x;\r
+ f32 ndc_trans_x;\r
+\r
+ f32 ndc_shrink_y;\r
+ f32 ndc_scale_y;\r
+ f32 ndc_trans_y;\r
+\r
+ f32 tex_w_add;\r
+ f32 tex_cx_add;\r
+ f32 tex_h_add;\r
+ f32 tex_cy_add;\r
+\r
+ f32 AreaMinDrawSize; //! minimal visible covered area for primitive\r
+ };\r
+ f32 val[16];\r
+ };\r
+ static const char* const name[16];\r
+ void postEventFromUser(const SEvent& e);\r
+};\r
+\r
+const char* const tweakBurning::name[] = { "step",\r
+ "ndc_shrink_x","ndc_scale_x","ndc_trans_x",\r
+ "ndc_shrink_y","ndc_scale_y","ndc_trans_y",\r
+ "tex_w_add","tex_cx_add","tex_h_add","tex_cy_add",\r
+ "dc_area",0 };\r
+\r
+void tweakBurning::postEventFromUser(const SEvent& e)\r
+{\r
+ int show = 0;\r
+ if (e.EventType == EET_KEY_INPUT_EVENT)\r
+ {\r
+ switch (e.KeyInput.Key)\r
+ {\r
+ case KEY_KEY_1: step *= 0.9f; if (step < 0.00001f) step = 0.0001f; show = 2; break;\r
+ case KEY_KEY_2: step *= 1.1f; show = 2; break;\r
+\r
+ case KEY_KEY_3: if (!e.KeyInput.PressedDown) { current -= 1; if (current < 1) current = 11; show = 1; } break;\r
+ case KEY_KEY_4: if (!e.KeyInput.PressedDown) { current += 1; if (current > 11) current = 1; show = 1; } break;\r
+\r
+ case KEY_KEY_5: val[current] -= e.KeyInput.Shift ? step * 100.f : step; show = 1; break;\r
+ case KEY_KEY_6: val[current] += e.KeyInput.Shift ? step * 100.f : step; show = 1; break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ if (show)\r
+ {\r
+ if (step < 0.0001f) step = 0.0001f;\r
+ char buf[256];\r
+ if (show == 2) sprintf(buf, "%s %f\n", name[0], val[0]);\r
+ else sprintf(buf, "%s %f\n", name[current], val[current]);\r
+ os::Printer::print(buf);\r
+ }\r
+}\r
+\r
+void CBurningVideoDriver::postEventFromUser(const void* sevent)\r
+{\r
+ if (sevent) Tweak.postEventFromUser(*(const SEvent*)sevent);\r
+}\r
+\r
+tweakBurning Tweak;\r
+#endif //defined(Tweak_Burning)\r
+\r
\r
\r
namespace irr\r
: CNullDriver(io, params.WindowSize), BackBuffer(0), Presenter(presenter),\r
WindowId(0), SceneSourceRect(0),\r
RenderTargetTexture(0), RenderTargetSurface(0), CurrentShader(0),\r
- DepthBuffer(0), StencilBuffer ( 0 ),\r
- CurrentOut ( 16 * 2, 256 ), Temp ( 16 * 2, 256 )\r
+ DepthBuffer(0), StencilBuffer ( 0 )\r
{\r
+ //enable fpu exception\r
+ //unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM);\r
+\r
#ifdef _DEBUG\r
setDebugName("CBurningVideoDriver");\r
#endif\r
\r
+ VertexCache_map_source_format();\r
+\r
// create backbuffer\r
BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, params.WindowSize);\r
if (BackBuffer)\r
\r
// create stencil buffer\r
if ( params.Stencilbuffer )\r
- StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension());\r
+ StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension(),8);\r
}\r
\r
- DriverAttributes->setAttribute("MaxTextures", 2);\r
DriverAttributes->setAttribute("MaxIndices", 1<<16);\r
- DriverAttributes->setAttribute("MaxTextureSize", SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE);\r
+ DriverAttributes->setAttribute("MaxTextures", BURNING_MATERIAL_MAX_TEXTURES);\r
+ DriverAttributes->setAttribute("MaxTextureSize", SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1<<20);\r
DriverAttributes->setAttribute("MaxLights", 1024 ); //glsl::gl_MaxLights);\r
DriverAttributes->setAttribute("MaxTextureLODBias", 16.f);\r
- DriverAttributes->setAttribute("Version", 49);\r
+ DriverAttributes->setAttribute("Version", 50);\r
\r
// create triangle renderers\r
\r
- irr::memset32 ( BurningShader, 0, sizeof ( BurningShader ) );\r
+ memset( BurningShader, 0, sizeof ( BurningShader ) );\r
//BurningShader[ETR_FLAT] = createTRFlat2(DepthBuffer);\r
//BurningShader[ETR_FLAT_WIRE] = createTRFlatWire2(DepthBuffer);\r
BurningShader[ETR_GOURAUD] = createTriangleRendererGouraud2(this);\r
- BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(this );\r
- BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(this );\r
+ BurningShader[ETR_GOURAUD_NOZ] = createTriangleRendererGouraudNoZ2(this);\r
+ //BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(this );\r
+ BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(this ); // 2D\r
//BurningShader[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire2(DepthBuffer);\r
//BurningShader[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat2(DepthBuffer);\r
//BurningShader[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire2(DepthBuffer);\r
BurningShader[ETR_STENCIL_SHADOW] = createTRStencilShadow ( this );\r
BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend( this );\r
\r
- BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this );\r
+ BurningShader[ETR_TRANSPARENT_REFLECTION_2_LAYER] = createTriangleRendererTexture_transparent_reflection_2_layer(this);\r
+ //BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this );\r
\r
+ BurningShader[ETR_COLOR] = create_burning_shader_color(this);\r
\r
// add the same renderer for all solid types\r
CSoftware2MaterialRenderer_SOLID* smr = new CSoftware2MaterialRenderer_SOLID( this);\r
CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR* tmr = new CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR( this);\r
- CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this );\r
+ //CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this );\r
\r
//!TODO: addMaterialRenderer depends on pushing order....\r
addMaterialRenderer ( smr ); // EMT_SOLID\r
addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M2,\r
addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M4,\r
addMaterialRenderer ( smr ); // EMT_DETAIL_MAP,\r
- addMaterialRenderer ( umr ); // EMT_SPHERE_MAP,\r
+ addMaterialRenderer ( smr ); // EMT_SPHERE_MAP,\r
addMaterialRenderer ( smr ); // EMT_REFLECTION_2_LAYER,\r
addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ADD_COLOR,\r
addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_ALPHA_CHANNEL,\r
addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_VERTEX_ALPHA,\r
addMaterialRenderer ( smr ); // EMT_TRANSPARENT_REFLECTION_2_LAYER,\r
addMaterialRenderer ( smr ); // EMT_NORMAL_MAP_SOLID,\r
- addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR,\r
+ addMaterialRenderer ( tmr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR,\r
addMaterialRenderer ( tmr ); // EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA,\r
addMaterialRenderer ( smr ); // EMT_PARALLAX_MAP_SOLID,\r
addMaterialRenderer ( tmr ); // EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR,\r
\r
smr->drop ();\r
tmr->drop ();\r
- umr->drop ();\r
+ //umr->drop ();\r
\r
// select render target\r
setRenderTargetImage(BackBuffer);\r
\r
//reset Lightspace\r
- LightSpace.reset ();\r
+ EyeSpace.reset();\r
+ EyeSpace.resetFog();\r
\r
// select the right renderer\r
- setCurrentShader();\r
+ setMaterial(Material.org);\r
}\r
\r
\r
{\r
// delete Backbuffer\r
if (BackBuffer)\r
+ {\r
BackBuffer->drop();\r
+ BackBuffer = 0;\r
+ }\r
\r
// delete triangle renderers\r
-\r
for (s32 i=0; i<ETR2_COUNT; ++i)\r
{\r
if (BurningShader[i])\r
+ {\r
BurningShader[i]->drop();\r
+ BurningShader[i] = 0;\r
+ }\r
}\r
\r
// delete Additional buffer\r
if (StencilBuffer)\r
- StencilBuffer->drop();\r
-\r
- if (DepthBuffer)\r
- DepthBuffer->drop();\r
-\r
- if (RenderTargetTexture)\r
- RenderTargetTexture->drop();\r
-\r
- if (RenderTargetSurface)\r
- RenderTargetSurface->drop();\r
-}\r
-\r
-\r
-/*!\r
- selects the right triangle renderer based on the render states.\r
-*/\r
-void CBurningVideoDriver::setCurrentShader()\r
-{\r
- ITexture *texture0 = Material.org.getTexture(0);\r
- ITexture *texture1 = Material.org.getTexture(1);\r
-\r
- bool zMaterialTest = Material.org.ZBuffer != ECFN_DISABLED &&\r
- Material.org.ZWriteEnable != video::EZW_OFF &&\r
- ( AllowZWriteOnTransparent || !Material.org.isTransparent() );\r
-\r
- EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ;\r
-\r
- TransformationFlag[ ETS_TEXTURE_0] &= ~(ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION);\r
- LightSpace.Flags &= ~VERTEXTRANSFORM;\r
-\r
- switch ( Material.org.MaterialType )\r
{\r
- case EMT_ONETEXTURE_BLEND:\r
- shader = ETR_TEXTURE_BLEND;\r
- break;\r
-\r
- case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:\r
- Material.org.MaterialTypeParam = 0.5f;\r
- // fall through\r
- case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
- if ( texture0 && texture0->hasAlpha () )\r
- {\r
- shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ;\r
- break;\r
- }\r
- else\r
- {\r
- shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;\r
- }\r
- break;\r
-\r
- case EMT_TRANSPARENT_ADD_COLOR:\r
- shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z;\r
- break;\r
-\r
- case EMT_TRANSPARENT_VERTEX_ALPHA:\r
- shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;\r
- break;\r
-\r
- case EMT_LIGHTMAP:\r
- case EMT_LIGHTMAP_LIGHTING:\r
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;\r
- break;\r
-\r
- case EMT_LIGHTMAP_M2:\r
- case EMT_LIGHTMAP_LIGHTING_M2:\r
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2;\r
- break;\r
-\r
- case EMT_LIGHTMAP_LIGHTING_M4:\r
- if ( texture1 )\r
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4;\r
- break;\r
- case EMT_LIGHTMAP_M4:\r
- if ( texture1 )\r
- shader = ETR_TEXTURE_LIGHTMAP_M4;\r
- break;\r
-\r
- case EMT_LIGHTMAP_ADD:\r
- if ( texture1 )\r
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD;\r
- break;\r
-\r
- case EMT_DETAIL_MAP:\r
- if ( texture1 )\r
- shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP;\r
- break;\r
-\r
- case EMT_SPHERE_MAP:\r
- TransformationFlag[ ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_REFLECTION; // ETF_TEXGEN_CAMERA_NORMAL;\r
- LightSpace.Flags |= VERTEXTRANSFORM;\r
- break;\r
- case EMT_REFLECTION_2_LAYER:\r
- shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;\r
- TransformationFlag[ ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION;\r
- LightSpace.Flags |= VERTEXTRANSFORM;\r
- break;\r
-\r
- case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:\r
- case EMT_NORMAL_MAP_SOLID:\r
- case EMT_PARALLAX_MAP_SOLID:\r
- case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:\r
- shader = ETR_NORMAL_MAP_SOLID;\r
- LightSpace.Flags |= VERTEXTRANSFORM;\r
- break;\r
-\r
- default:\r
- break;\r
-\r
+ StencilBuffer->drop();\r
+ StencilBuffer = 0;\r
}\r
\r
- if ( !texture0 )\r
+ if (DepthBuffer)\r
{\r
- shader = ETR_GOURAUD;\r
+ DepthBuffer->drop();\r
+ DepthBuffer = 0;\r
}\r
\r
- if ( Material.org.Wireframe )\r
+ if (RenderTargetTexture)\r
{\r
- shader = ETR_TEXTURE_GOURAUD_WIRE;\r
+ RenderTargetTexture->drop();\r
+ RenderTargetTexture = 0;\r
}\r
\r
- //shader = ETR_REFERENCE;\r
-\r
- // switchToTriangleRenderer\r
- CurrentShader = BurningShader[shader];\r
- if ( CurrentShader )\r
+ if (RenderTargetSurface)\r
{\r
- CurrentShader->setZCompareFunc ( Material.org.ZBuffer );\r
- CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);\r
- CurrentShader->setMaterial ( Material );\r
-\r
- switch ( shader )\r
- {\r
- case ETR_TEXTURE_GOURAUD_ALPHA:\r
- case ETR_TEXTURE_GOURAUD_ALPHA_NOZ:\r
- case ETR_TEXTURE_BLEND:\r
- CurrentShader->setParam ( 0, Material.org.MaterialTypeParam );\r
- break;\r
- default:\r
- break;\r
- }\r
+ RenderTargetSurface->drop();\r
+ RenderTargetSurface = 0;\r
}\r
-\r
}\r
\r
\r
//! queries the features of the driver, returns true if feature is available\r
bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const\r
{\r
- if (!FeatureEnabled[feature])\r
- return false;\r
-\r
+ int on = 0;\r
switch (feature)\r
{\r
#ifdef SOFTWARE_DRIVER_2_BILINEAR\r
case EVDF_BILINEAR_FILTER:\r
- return true;\r
+ on = 1;\r
+ break;\r
#endif\r
#ifdef SOFTWARE_DRIVER_2_MIPMAPPING\r
case EVDF_MIP_MAP:\r
- return true;\r
+ on = 1;\r
+ break;\r
#endif\r
case EVDF_STENCIL_BUFFER:\r
- return StencilBuffer != 0;\r
+ on = StencilBuffer != 0;\r
+ break;\r
\r
case EVDF_RENDER_TO_TARGET:\r
case EVDF_MULTITEXTURE:\r
case EVDF_HARDWARE_TL:\r
case EVDF_TEXTURE_NSQUARE:\r
- return true;\r
+ case EVDF_TEXTURE_MATRIX:\r
+ on = 1;\r
+ break;\r
+\r
+ case EVDF_DEPTH_CLAMP: // shadow\r
+ on = 1;\r
+ break;\r
+\r
+ case EVDF_TEXTURE_NPOT: // for 2D\r
+ on = 0;\r
+ break;\r
\r
+ case EVDF_ARB_FRAGMENT_PROGRAM_1:\r
+ case EVDF_ARB_VERTEX_PROGRAM_1:\r
+ on = 1;\r
+ break;\r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
+ case EVDF_TEXTURE_NPOT:\r
+ case EVDF_ARB_GLSL:\r
+ on = 1;\r
+ break;\r
+#endif\r
+\r
+#if defined(SOFTWARE_DRIVER_2_2D_AS_3D)\r
+#if defined(IRRLICHT_FREE_CANVAS)\r
+ case EVDF_VIEWPORT_SCALE_GUI:\r
+ on = 1;\r
+ break;\r
+#endif\r
+#endif\r
default:\r
- return false;\r
+ on = 0;\r
+ break;\r
}\r
+\r
+ return on && FeatureEnabled[feature];\r
}\r
\r
\r
}\r
\r
\r
-\r
-//! sets transformation\r
-void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)\r
+//matrix multiplication\r
+void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state)\r
{\r
- Transformation[state] = mat;\r
- core::setbit_cond ( TransformationFlag[state], mat.isIdentity(), ETF_IDENTITY );\r
+ size_t* flag = TransformationFlag[TransformationStack];\r
+ if (flag[state] & ETF_VALID ) return;\r
\r
+ //check\r
+ int ok = 0;\r
switch ( state )\r
{\r
- case ETS_VIEW:\r
- Transformation[ETS_VIEW_PROJECTION].setbyproduct_nocheck (\r
- Transformation[ETS_PROJECTION],\r
- Transformation[ETS_VIEW]\r
- );\r
- getCameraPosWorldSpace ();\r
+ case ETS_PROJ_MODEL_VIEW:\r
+ if ( 0 == (flag[ETS_VIEW_PROJECTION] & ETF_VALID) ) transform_calc (ETS_VIEW_PROJECTION);\r
+ ok = flag[ETS_WORLD] & flag[ETS_VIEW] & flag[ETS_PROJECTION] & flag[ETS_VIEW_PROJECTION] & ETF_VALID;\r
+ break;\r
+ case ETS_VIEW_PROJECTION:\r
+ ok = flag[ETS_VIEW] & flag[ETS_PROJECTION] & ETF_VALID;\r
break;\r
+ case ETS_MODEL_VIEW:\r
+ ok = flag[ETS_WORLD] & flag[ETS_VIEW] & ETF_VALID;\r
+ break;\r
+ case ETS_NORMAL:\r
+ ok = flag[ETS_MODEL_VIEW] & ETF_VALID;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
\r
- case ETS_WORLD:\r
- if ( TransformationFlag[state] & ETF_IDENTITY )\r
+ if ( !ok )\r
+ {\r
+ char buf[256];\r
+ sprintf(buf,"transform_calc not valid for %d\n",state);\r
+ os::Printer::log(buf, ELL_WARNING);\r
+ }\r
+\r
+ core::matrix4* matrix = Transformation[TransformationStack];\r
+\r
+ switch ( state )\r
+ {\r
+ case ETS_PROJ_MODEL_VIEW:\r
+ if (flag[ETS_WORLD] & ETF_IDENTITY )\r
{\r
- Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD];\r
- TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY;\r
- Transformation[ETS_CURRENT] = Transformation[ETS_VIEW_PROJECTION];\r
+ matrix[state] = matrix[ETS_VIEW_PROJECTION];\r
}\r
else\r
{\r
- //Transformation[ETS_WORLD].getInversePrimitive ( Transformation[ETS_WORLD_INVERSE] );\r
- Transformation[ETS_CURRENT].setbyproduct_nocheck (\r
- Transformation[ETS_VIEW_PROJECTION],\r
- Transformation[ETS_WORLD]\r
- );\r
+ matrix[state].setbyproduct_nocheck(matrix[ETS_VIEW_PROJECTION], matrix[ETS_WORLD]);\r
}\r
- TransformationFlag[ETS_CURRENT] = 0;\r
- //getLightPosObjectSpace ();\r
break;\r
- case ETS_TEXTURE_0:\r
- case ETS_TEXTURE_1:\r
- case ETS_TEXTURE_2:\r
- case ETS_TEXTURE_3:\r
- if ( 0 == (TransformationFlag[state] & ETF_IDENTITY ) )\r
- LightSpace.Flags |= VERTEXTRANSFORM;\r
+\r
+ case ETS_VIEW_PROJECTION:\r
+ matrix[state].setbyproduct_nocheck (matrix[ETS_PROJECTION], matrix[ETS_VIEW]);\r
+ break;\r
+ case ETS_MODEL_VIEW:\r
+ if ( flag[ETS_WORLD] & ETF_IDENTITY )\r
+ {\r
+ matrix[state] = matrix[ETS_VIEW];\r
+ }\r
+ else\r
+ {\r
+ matrix[state].setbyproduct_nocheck(matrix[ETS_VIEW], matrix[ETS_WORLD]);\r
+ }\r
+ break;\r
+ case ETS_NORMAL:\r
+ mat44_transposed_inverse(matrix[state], matrix[ETS_MODEL_VIEW]);\r
+ break;\r
+\r
default:\r
break;\r
}\r
+ flag[state] |= ETF_VALID;\r
}\r
\r
-bool CBurningVideoDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, const SExposedVideoData& videoData, core::rect<s32>* sourceRect)\r
-{\r
- CNullDriver::beginScene(clearFlag, clearColor, clearDepth, clearStencil, videoData, sourceRect);\r
- WindowId = videoData.D3D9.HWnd;\r
- SceneSourceRect = sourceRect;\r
-\r
- clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);\r
-\r
- memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) );\r
- return true;\r
-}\r
-\r
-bool CBurningVideoDriver::endScene()\r
-{\r
- CNullDriver::endScene();\r
-\r
- return Presenter->present(BackBuffer, WindowId, SceneSourceRect);\r
-}\r
\r
-bool CBurningVideoDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)\r
+//! sets transformation\r
+void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)\r
{\r
- if (target && target->getDriverType() != EDT_BURNINGSVIDEO)\r
- {\r
- os::Printer::log("Fatal Error: Tried to set a render target not owned by this driver.", ELL_ERROR);\r
- return false;\r
- }\r
-\r
- if (RenderTargetTexture)\r
- RenderTargetTexture->drop();\r
-\r
- CSoftwareRenderTarget2* renderTarget = static_cast<CSoftwareRenderTarget2*>(target);\r
- RenderTargetTexture = (renderTarget) ? renderTarget->getTexture() : 0;\r
+ size_t* flag = TransformationFlag[TransformationStack];\r
+ core::matrix4* matrix = Transformation[TransformationStack];\r
\r
- if (RenderTargetTexture)\r
+#if 0\r
+ int changed = 1;\r
+ if (flag[state] & ETF_VALID)\r
{\r
- RenderTargetTexture->grab();\r
- setRenderTargetImage(((CSoftwareTexture2*)RenderTargetTexture)->getTexture());\r
+ changed = memcmp(mat.pointer(), matrix[state].pointer(), sizeof(mat));\r
}\r
- else\r
+ if (changed)\r
+#endif\r
{\r
- setRenderTargetImage(BackBuffer);\r
+ matrix[state] = mat;\r
+ flag[state] |= ETF_VALID;\r
}\r
\r
+ //maybe identity (mostly for texturematrix to avoid costly multiplication)\r
+#if defined ( USE_MATRIX_TEST )\r
+ burning_setbit( TransformationFlag[state], mat.getDefinitelyIdentityMatrix(), ETF_IDENTITY );\r
+#else\r
+ burning_setbit(flag[state],\r
+ !memcmp(mat.pointer(), core::IdentityMatrix.pointer(),sizeof(mat)),ETF_IDENTITY\r
+ );\r
+#endif\r
+\r
+#if 0\r
+ if ( changed )\r
+#endif\r
+ switch ( state )\r
+ {\r
+ case ETS_PROJECTION:\r
+ flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;\r
+ flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID;\r
+ break;\r
+ case ETS_VIEW:\r
+ flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;\r
+ flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID;\r
+ flag[ETS_MODEL_VIEW] &= ~ETF_VALID;\r
+ flag[ETS_NORMAL] &= ~ETF_VALID;\r
+ break;\r
+ case ETS_WORLD:\r
+ flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;\r
+ flag[ETS_MODEL_VIEW] &= ~ETF_VALID;\r
+ flag[ETS_NORMAL] &= ~ETF_VALID;\r
+ break;\r
+ case ETS_TEXTURE_0:\r
+ case ETS_TEXTURE_1:\r
+ case ETS_TEXTURE_2:\r
+ case ETS_TEXTURE_3:\r
+#if _IRR_MATERIAL_MAX_TEXTURES_>4\r
+ case ETS_TEXTURE_4:\r
+#endif\r
+#if _IRR_MATERIAL_MAX_TEXTURES_>5\r
+ case ETS_TEXTURE_5:\r
+#endif\r
+#if _IRR_MATERIAL_MAX_TEXTURES_>6\r
+ case ETS_TEXTURE_6:\r
+#endif\r
+#if _IRR_MATERIAL_MAX_TEXTURES_>7\r
+ case ETS_TEXTURE_7:\r
+#endif\r
+ if ( 0 == (flag[state] & ETF_IDENTITY ) )\r
+ {\r
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;\r
+ }\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+\r
+}\r
+\r
+//! Returns the transformation set by setTransform\r
+const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const\r
+{\r
+ return Transformation[TransformationStack][state];\r
+}\r
+\r
+\r
+bool CBurningVideoDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, const SExposedVideoData& videoData, core::rect<s32>* sourceRect)\r
+{\r
+ CNullDriver::beginScene(clearFlag, clearColor, clearDepth, clearStencil, videoData, sourceRect);\r
+ WindowId = videoData.D3D9.HWnd;\r
+ SceneSourceRect = sourceRect;\r
+\r
clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);\r
\r
+ //memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) );\r
return true;\r
}\r
\r
+bool CBurningVideoDriver::endScene()\r
+{\r
+ CNullDriver::endScene();\r
+\r
+ return Presenter->present(BackBuffer, WindowId, SceneSourceRect);\r
+}\r
+\r
+bool CBurningVideoDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)\r
+{\r
+ if (target && target->getDriverType() != EDT_BURNINGSVIDEO)\r
+ {\r
+ os::Printer::log("Fatal Error: Tried to set a render target not owned by this driver.", ELL_ERROR);\r
+ return false;\r
+ }\r
+\r
+ if (RenderTargetTexture)\r
+ RenderTargetTexture->drop();\r
+\r
+ CSoftwareRenderTarget2* renderTarget = static_cast<CSoftwareRenderTarget2*>(target);\r
+ RenderTargetTexture = (renderTarget) ? renderTarget->getTexture() : 0;\r
+\r
+ if (RenderTargetTexture)\r
+ {\r
+ RenderTargetTexture->grab();\r
+ setRenderTargetImage(((CSoftwareTexture2*)RenderTargetTexture)->getTexture());\r
+ }\r
+ else\r
+ {\r
+ setRenderTargetImage(BackBuffer);\r
+ }\r
+\r
+ clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);\r
+\r
+ return true;\r
+}\r
\r
//! sets a render target\r
void CBurningVideoDriver::setRenderTargetImage(video::CImage* image)\r
if (RenderTargetSurface)\r
RenderTargetSurface->drop();\r
\r
+ core::dimension2d<u32> current = RenderTargetSize;\r
RenderTargetSurface = image;\r
RenderTargetSize.Width = 0;\r
RenderTargetSize.Height = 0;\r
RenderTargetSize = RenderTargetSurface->getDimension();\r
}\r
\r
- setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height));\r
+ int not_changed = current == RenderTargetSize;\r
+ burning_setbit(TransformationFlag[0][ETS_PROJECTION], not_changed, ETF_VALID);\r
+ burning_setbit(TransformationFlag[1][ETS_PROJECTION], not_changed, ETF_VALID);\r
+\r
+ setViewPort(core::recti(RenderTargetSize));\r
\r
if (DepthBuffer)\r
DepthBuffer->setSize(RenderTargetSize);\r
}\r
\r
\r
+//--------- Transform from NDC to DC, transform TexCoo ----------------------------------------------\r
+\r
+// controls subtexel and fill convention\r
+#if defined(SOFTWARE_DRIVER_2_SUBTEXEL)\r
+#define SOFTWARE_DRIVER_2_PIXEL_CENTER -0.5f\r
+#else\r
+#define SOFTWARE_DRIVER_2_PIXEL_CENTER -0.5f\r
+#endif\r
+\r
+#if 1\r
+\r
+// used to scale <-1,-1><1,1> to viewport\r
+void buildNDCToDCMatrix(f32* m, const core::rect<s32>& viewport, f32 tx)\r
+{\r
+ m[0] = (viewport.getWidth() + tx) * 0.5f;\r
+ m[1] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ((viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X) * 0.5f);\r
+\r
+ m[2] = (viewport.getHeight() + tx) * -0.5f;\r
+ m[3] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ((viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y) * 0.5f);\r
+}\r
+\r
+\r
+#else\r
+// used to scale <-1,-1><1,1> to viewport\r
+void buildNDCToDCMatrix( core::matrix4& out, const core::rect<s32>& viewport)\r
+{\r
+ //guard band to stay in screen bounds.(empirical). get holes left side otherwise or out of screen\r
+ //TODO: match openGL or D3D.\r
+ //assumption pixel center, top-left rule and rounding error projection deny exact match without additional clipping\r
+ //or triangle render scanline doesn't step on correct texel center\r
+ //or sampler is not on texel center\r
+\r
+ f32* m = out.pointer();\r
+#if defined(Tweak_Burning) && 0\r
+ m[0] = (viewport.getWidth() + Tweak.ndc_shrink_x ) * Tweak.ndc_scale_x;\r
+ m[5] = (viewport.getHeight() + Tweak.ndc_shrink_y ) * Tweak.ndc_scale_y;\r
+ m[12] = Tweak.ndc_trans_x + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) * 0.5f );\r
+ m[13] = Tweak.ndc_trans_y + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) * 0.5f );\r
+#endif\r
+\r
+ m[0] = (viewport.getWidth() - 0.75f ) * 0.5f;\r
+ m[1] = 0.f;\r
+ m[2] = 0.f;\r
+ m[3] = 0.f;\r
+ m[4] = 0.f;\r
+ m[5] = (viewport.getHeight() - 0.75f ) * -0.5f;\r
+ m[6] = 0.f;\r
+ m[7] = 0.f;\r
+ m[8] = 0.f;\r
+ m[9] = 0.f;\r
+ m[10] = 1.f;\r
+ m[11] = 0.f;\r
+ m[12] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) * 0.5f );\r
+ m[13] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) * 0.5f );\r
+ m[14] = 0.f;\r
+ m[15] = 1.f;\r
+}\r
+#endif\r
+\r
+\r
+//--------- Transform from NCD to DC ----------------------------------------------\r
\r
//! sets a viewport\r
void CBurningVideoDriver::setViewPort(const core::rect<s32>& area)\r
core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height);\r
ViewPort.clipAgainst(rendert);\r
\r
- Transformation [ ETS_CLIPSCALE ].buildNDCToDCMatrix ( ViewPort, 1 );\r
+ buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[0], ViewPort,-0.375f);\r
+ buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[1], ViewPort, 0.f); // OverrideMaterial2DEnabled ? -0.375f : 0.f);\r
\r
if (CurrentShader)\r
CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);\r
}\r
\r
+void CBurningVideoDriver::setScissor(int x, int y, int width, int height)\r
+{\r
+ AbsRectangle v0;\r
+ v0.x0 = x;\r
+ v0.y0 = y;\r
+ v0.x1 = x+width;\r
+ v0.y1 = y+width;\r
+\r
+ const core::dimension2d<u32>& rt = getCurrentRenderTargetSize();\r
+ AbsRectangle v1;\r
+ v1.x0 = 0;\r
+ v1.y0 = 0;\r
+ v1.x1 = rt.Width;\r
+ v1.y1 = rt.Height;\r
+\r
+ intersect(Scissor, v0, v1);\r
+}\r
+\r
/*\r
generic plane clipping in homogenous coordinates\r
special case ndc frustum <-w,w>,<-w,w>,<-w,w>\r
can be rewritten with compares e.q near plane, a.z < -a.w and b.z < -b.w\r
+\r
+ cam is (0,0,-1)\r
*/\r
\r
-const sVec4 CBurningVideoDriver::NDCPlane[6] =\r
+const sVec4 CBurningVideoDriver::NDCPlane[6+2] =\r
{\r
sVec4( 0.f, 0.f, -1.f, -1.f ), // near\r
sVec4( 0.f, 0.f, 1.f, -1.f ), // far\r
};\r
\r
\r
-\r
/*\r
test a vertex if it's inside the standard frustum\r
\r
for ( u32 i = 0; i!= 6; ++i )\r
{\r
dotPlane = v->Pos.dotProduct ( NDCPlane[i] );\r
- core::setbit_cond( flag, dotPlane <= 0.f, 1 << i );\r
+ burning_setbit32( flag, dotPlane <= 0.f, 1 << i );\r
}\r
\r
// this is the base for ndc frustum <-w,w>,<-w,w>,<-w,w>\r
- core::setbit_cond( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 );\r
- core::setbit_cond( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 );\r
- core::setbit_cond( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 );\r
- core::setbit_cond( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 );\r
- core::setbit_cond( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 );\r
- core::setbit_cond( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 );\r
+ burning_setbit32( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 );\r
+ burning_setbit32( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 );\r
+ burning_setbit32( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 );\r
+ burning_setbit32( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 );\r
+ burning_setbit32( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 );\r
+ burning_setbit32( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 );\r
\r
*/\r
#ifdef IRRLICHT_FAST_MATH\r
\r
-REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const\r
+REALINLINE size_t CBurningVideoDriver::clipToFrustumTest ( const s4DVertex* v ) const\r
{\r
- f32 test[6];\r
- u32 flag;\r
+ register size_t flag;\r
+ f32 test[8];\r
const f32 w = - v->Pos.w;\r
\r
// a conditional move is needed....FCOMI ( but we don't have it )\r
test[4] = v->Pos.y + w;\r
test[5] = -v->Pos.y + w;\r
\r
+ const u32* a = F32_AS_U32_POINTER(test);\r
+ flag = (a[0] ) >> 31;\r
+ flag |= (a[1] & 0x80000000) >> 30;\r
+ flag |= (a[2] & 0x80000000) >> 29;\r
+ flag |= (a[3] & 0x80000000) >> 28;\r
+ flag |= (a[4] & 0x80000000) >> 27;\r
+ flag |= (a[5] & 0x80000000) >> 26;\r
+\r
+/*\r
flag = (IR ( test[0] ) ) >> 31;\r
flag |= (IR ( test[1] ) & 0x80000000 ) >> 30;\r
flag |= (IR ( test[2] ) & 0x80000000 ) >> 29;\r
flag |= (IR ( test[3] ) & 0x80000000 ) >> 28;\r
flag |= (IR ( test[4] ) & 0x80000000 ) >> 27;\r
flag |= (IR ( test[5] ) & 0x80000000 ) >> 26;\r
-\r
+*/\r
/*\r
flag = F32_LOWER_EQUAL_0 ( test[0] );\r
flag |= F32_LOWER_EQUAL_0 ( test[1] ) << 1;\r
#else\r
\r
\r
-REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v ) const\r
+REALINLINE size_t clipToFrustumTest ( const s4DVertex* v )\r
{\r
- u32 flag = 0;\r
-\r
- flag |= v->Pos.z <= v->Pos.w ? 1 : 0;\r
- flag |= -v->Pos.z <= v->Pos.w ? 2 : 0;\r
+ size_t flag = 0;\r
\r
- flag |= v->Pos.x <= v->Pos.w ? 4 : 0;\r
- flag |= -v->Pos.x <= v->Pos.w ? 8 : 0;\r
+ flag |= v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_NEAR : 0;\r
+ flag |= -v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_FAR : 0;\r
\r
- flag |= v->Pos.y <= v->Pos.w ? 16 : 0;\r
- flag |= -v->Pos.y <= v->Pos.w ? 32 : 0;\r
+ flag |= v->Pos.x <= v->Pos.w ? VERTEX4D_CLIP_LEFT : 0;\r
+ flag |= -v->Pos.x <= v->Pos.w ? VERTEX4D_CLIP_RIGHT : 0;\r
\r
-/*\r
- if ( v->Pos.z <= v->Pos.w ) flag |= 1;\r
- if (-v->Pos.z <= v->Pos.w ) flag |= 2;\r
+ flag |= v->Pos.y <= v->Pos.w ? VERTEX4D_CLIP_BOTTOM : 0;\r
+ flag |= -v->Pos.y <= v->Pos.w ? VERTEX4D_CLIP_TOP : 0;\r
\r
- if ( v->Pos.x <= v->Pos.w ) flag |= 4;\r
- if (-v->Pos.x <= v->Pos.w ) flag |= 8;\r
\r
- if ( v->Pos.y <= v->Pos.w ) flag |= 16;\r
- if (-v->Pos.y <= v->Pos.w ) flag |= 32;\r
-*/\r
/*\r
- for ( u32 i = 0; i!= 6; ++i )\r
+ for ( u32 i = 0; i <= 6; ++i )\r
{\r
- core::setbit_cond( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i );\r
+ if (v->Pos.dot_xyzw(NDCPlane[i]) <= 0.f) flag |= ((size_t)1) << i;\r
}\r
*/\r
return flag;\r
\r
#endif // _MSC_VER\r
\r
-u32 CBurningVideoDriver::clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane )\r
-{\r
- u32 outCount = 0;\r
- s4DVertex * out = dest;\r
\r
- const s4DVertex * a;\r
- const s4DVertex * b = source;\r
+size_t clipToHyperPlane (\r
+ s4DVertexPair* burning_restrict dest,\r
+ const s4DVertexPair* burning_restrict source,\r
+ const size_t inCount,\r
+ const sVec4& plane\r
+)\r
+{\r
+ size_t outCount = 0;\r
+ s4DVertexPair* out = dest;\r
\r
- f32 bDotPlane;\r
+ const s4DVertex* a;\r
+ const s4DVertex* b = source;\r
\r
- bDotPlane = b->Pos.dotProduct ( plane );\r
+ ipoltype bDotPlane;\r
+ bDotPlane = b->Pos.dot_xyzw( plane );\r
\r
+/*\r
for( u32 i = 1; i < inCount + 1; ++i)\r
{\r
- // i really have problem\r
+#if 0\r
+ a = source + (i%inCount)*2;\r
+#else\r
const s32 condition = i - inCount;\r
const s32 index = (( ( condition >> 31 ) & ( i ^ condition ) ) ^ condition ) << 1;\r
-\r
- a = &source[ index ];\r
+ a = source + index;\r
+#endif\r
+*/\r
+ //Sutherland\96Hodgman\r
+ for(size_t i = 0; i < inCount; ++i)\r
+ {\r
+ a = source + (i == inCount-1 ? 0 : s4DVertex_ofs(i+1));\r
\r
// current point inside\r
- if ( a->Pos.dotProduct ( plane ) <= 0.f )\r
+ if (ipol_lower_equal_0(a->Pos.dot_xyzw( plane )) )\r
{\r
// last point outside\r
- if ( F32_GREATER_0 ( bDotPlane ) )\r
+ if (ipol_greater_0( bDotPlane ) )\r
{\r
// intersect line segment with plane\r
- out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) );\r
- out += 2;\r
+ out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane) );\r
+ out += sizeof_s4DVertexPairRel;\r
outCount += 1;\r
}\r
\r
// copy current to out\r
//*out = *a;\r
- irr::memcpy32_small ( out, a, SIZEOF_SVERTEX * 2 );\r
+ memcpy_s4DVertexPair( out, a);\r
b = out;\r
\r
- out += 2;\r
+ out += sizeof_s4DVertexPairRel;\r
outCount += 1;\r
}\r
else\r
{\r
// current point outside\r
-\r
- if ( F32_LOWER_EQUAL_0 ( bDotPlane ) )\r
+ if (ipol_lower_equal_0( bDotPlane ) )\r
{\r
// previous was inside\r
// intersect line segment with plane\r
- out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) );\r
- out += 2;\r
+ out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane) );\r
+ out += sizeof_s4DVertexPairRel;\r
outCount += 1;\r
}\r
// pointer\r
b = a;\r
}\r
\r
- bDotPlane = b->Pos.dotProduct ( plane );\r
-\r
+ bDotPlane = b->Pos.dot_xyzw( plane );\r
}\r
\r
return outCount;\r
}\r
\r
\r
-u32 CBurningVideoDriver::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u32 vIn )\r
+/*\r
+ Clip on all planes. Clipper.data\r
+ clipmask per face\r
+*/\r
+size_t CBurningVideoDriver::clipToFrustum(const size_t vIn /*, const size_t clipmask_for_face*/ )\r
{\r
- u32 vOut = vIn;\r
+ s4DVertexPair* v0 = Clipper.data;\r
+ s4DVertexPair* v1 = Clipper_temp.data;\r
+ size_t vOut = vIn;\r
+\r
+ //clear all clipping & projected flags\r
+ const u32 flag = v0[0].flag & VERTEX4D_FORMAT_MASK;\r
+ for (size_t g = 0; g != Clipper.ElementSize; ++g)\r
+ {\r
+ v0[g].flag = flag;\r
+ v1[g].flag = flag;\r
+ }\r
+\r
+#if 0\r
+ for (size_t i = 0; i < 6; ++i)\r
+ {\r
+ v0 = i & 1 ? Clipper_temp.data : Clipper.data;\r
+ v1 = i & 1 ? Clipper.data : Clipper_temp.data;\r
+\r
+ //clipMask checked outside - always clip all planes\r
+#if 0\r
+ if (0 == (clipMask & ((size_t)1<<i)))\r
+ {\r
+ vOut = vIn;\r
+ memcpy_s4DVertexPair(v1, v0);\r
+ }\r
+ else\r
+#endif\r
+ {\r
+ vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[i]);\r
+ if (vOut < vIn) return vOut;\r
+ }\r
+ }\r
+#endif\r
+\r
+\r
+ vOut = clipToHyperPlane( v1, v0, vOut, NDCPlane[0] ); if ( vOut < vIn) return vOut;\r
+ vOut = clipToHyperPlane( v0, v1, vOut, NDCPlane[1] ); if ( vOut < vIn ) return vOut;\r
+ vOut = clipToHyperPlane( v1, v0, vOut, NDCPlane[2] ); if ( vOut < vIn ) return vOut;\r
+ vOut = clipToHyperPlane( v0, v1, vOut, NDCPlane[3] ); if ( vOut < vIn ) return vOut;\r
+ vOut = clipToHyperPlane( v1, v0, vOut, NDCPlane[4] ); if ( vOut < vIn ) return vOut;\r
+ vOut = clipToHyperPlane( v0, v1, vOut, NDCPlane[5] );\r
\r
- vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[0] ); if ( vOut < vIn ) return vOut;\r
- vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[1] ); if ( vOut < vIn ) return vOut;\r
- vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[2] ); if ( vOut < vIn ) return vOut;\r
- vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[3] ); if ( vOut < vIn ) return vOut;\r
- vOut = clipToHyperPlane ( v1, v0, vOut, NDCPlane[4] ); if ( vOut < vIn ) return vOut;\r
- vOut = clipToHyperPlane ( v0, v1, vOut, NDCPlane[5] );\r
return vOut;\r
}\r
\r
/*!\r
Part I:\r
apply Clip Scale matrix\r
- From Normalized Device Coordiante ( NDC ) Space to Device Coordinate Space ( DC )\r
+ From Normalized Device Coordiante ( NDC ) Space to Device Coordinate ( DC ) Space\r
\r
Part II:\r
Project homogeneous vector\r
Incoming: ( xw, yw, zw, w, u, v, 1, R, G, B, A )\r
Outgoing: ( xw/w, yw/w, zw/w, w/w, u/w, v/w, 1/w, R/w, G/w, B/w, A/w )\r
\r
-\r
replace w/w by 1/w\r
*/\r
-inline void CBurningVideoDriver::ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const\r
+//aliasing problems! [dest = source + 1]\r
+inline void CBurningVideoDriver::ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair *source, const size_t vIn ) const\r
{\r
- u32 g;\r
+ const f32* dc = Transformation_ETS_CLIPSCALE[TransformationStack];\r
\r
- for ( g = 0; g != vIn; g += 2 )\r
+ for ( size_t g = 0; g != vIn; g += sizeof_s4DVertexPairRel)\r
{\r
- if ( (dest[g].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED )\r
- continue;\r
+ //cache doesn't work anymore?\r
+ //if ( dest[g].flag & VERTEX4D_PROJECTED )\r
+ // continue;\r
+ //dest[g].flag = source[g].flag | VERTEX4D_PROJECTED;\r
\r
- dest[g].flag = source[g].flag | VERTEX4D_PROJECTED;\r
-\r
- const f32 w = source[g].Pos.w;\r
- const f32 iw = core::reciprocal ( w );\r
+ const f32 iw = reciprocal_zero (source[g].Pos.w);\r
\r
// to device coordinates\r
- dest[g].Pos.x = iw * ( source[g].Pos.x * Transformation [ ETS_CLIPSCALE ][ 0] + w * Transformation [ ETS_CLIPSCALE ][12] );\r
- dest[g].Pos.y = iw * ( source[g].Pos.y * Transformation [ ETS_CLIPSCALE ][ 5] + w * Transformation [ ETS_CLIPSCALE ][13] );\r
+ dest[g].Pos.x = iw * source[g].Pos.x * dc[0] + dc[1];\r
+ dest[g].Pos.y = iw * source[g].Pos.y * dc[2] + dc[3];\r
+\r
+ //burning uses direct Z. for OpenGL it should be -Z,[-1;1] and texture flip\r
+#if !defined(SOFTWARE_DRIVER_2_USE_WBUFFER) || 1\r
+ dest[g].Pos.z = -iw * source[g].Pos.z * 0.5f + 0.5f;\r
+#endif\r
+ dest[g].Pos.w = iw;\r
+\r
+// Texture Coordinates will be projected after mipmap selection\r
+// satisfy write-combiner\r
+#if 1\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
+ dest[g].Tex[0] = source[g].Tex[0];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 1\r
+ dest[g].Tex[1] = source[g].Tex[1];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 2\r
+ dest[g].Tex[2] = source[g].Tex[2];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 3\r
+ dest[g].Tex[3] = source[g].Tex[3];\r
+#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER\r
- dest[g].Pos.z = iw * source[g].Pos.z;\r
#endif\r
\r
- #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
- dest[g].Color[0] = source[g].Color[0] * iw;\r
+ dest[g].Color[0] = source[g].Color[0] * iw; // alpha?\r
#else\r
dest[g].Color[0] = source[g].Color[0];\r
#endif\r
+#endif\r
\r
- #endif\r
- dest[g].LightTangent[0] = source[g].LightTangent[0] * iw;\r
- dest[g].Pos.w = iw;\r
- }\r
-}\r
-\r
-\r
-inline void CBurningVideoDriver::ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const\r
-{\r
- u32 g;\r
-\r
- for ( g = 0; g != size; g += 1 )\r
- {\r
- s4DVertex * a = (s4DVertex*) v[g];\r
-\r
- if ( (a[1].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED )\r
- continue;\r
-\r
- a[1].flag = a->flag | VERTEX4D_PROJECTED;\r
-\r
- // project homogenous vertex, store 1/w\r
- const f32 w = a->Pos.w;\r
- const f32 iw = core::reciprocal ( w );\r
-\r
- // to device coordinates\r
- const f32 * p = Transformation [ ETS_CLIPSCALE ].pointer();\r
- a[1].Pos.x = iw * ( a->Pos.x * p[ 0] + w * p[12] );\r
- a[1].Pos.y = iw * ( a->Pos.y * p[ 5] + w * p[13] );\r
+#if BURNING_MATERIAL_MAX_COLORS > 1\r
+#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+ dest[g].Color[1] = source[g].Color[1] * iw; // alpha?\r
+#else\r
+ dest[g].Color[1] = source[g].Color[1];\r
+#endif\r
+#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER\r
- a[1].Pos.z = a->Pos.z * iw;\r
+#if BURNING_MATERIAL_MAX_COLORS > 2\r
+#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+ dest[g].Color[2] = source[g].Color[2] * iw; // alpha?\r
+#else\r
+ dest[g].Color[2] = source[g].Color[2];\r
+#endif\r
#endif\r
\r
- #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
- #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
- a[1].Color[0] = a->Color[0] * iw;\r
- #else\r
- a[1].Color[0] = a->Color[0];\r
- #endif\r
- #endif\r
+#if BURNING_MATERIAL_MAX_COLORS > 3\r
+#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+ dest[g].Color[3] = source[g].Color[3] * iw; // alpha?\r
+#else\r
+ dest[g].Color[3] = source[g].Color[3];\r
+#endif\r
+#endif\r
\r
- a[1].LightTangent[0] = a[0].LightTangent[0] * iw;\r
- a[1].Pos.w = iw;\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+ dest[g].LightTangent[0] = source[g].LightTangent[0] * iw;\r
+#endif\r
\r
}\r
-\r
}\r
\r
\r
+\r
/*!\r
- crossproduct in projected 2D -> screen area triangle\r
+ crossproduct in projected 2D, face\r
*/\r
-inline f32 CBurningVideoDriver::screenarea ( const s4DVertex *v ) const\r
+REALINLINE f32 CBurningVideoDriver::screenarea_inside(const s4DVertexPair* burning_restrict const face[] ) const\r
{\r
- return ( ( v[3].Pos.x - v[1].Pos.x ) * ( v[5].Pos.y - v[1].Pos.y ) ) -\r
- ( ( v[3].Pos.y - v[1].Pos.y ) * ( v[5].Pos.x - v[1].Pos.x ) );\r
+ return ( ((face[1]+1)->Pos.x - (face[0]+1)->Pos.x) * ((face[2]+1)->Pos.y - (face[0]+1)->Pos.y) ) -\r
+ ( ((face[2]+1)->Pos.x - (face[0]+1)->Pos.x) * ((face[1]+1)->Pos.y - (face[0]+1)->Pos.y) );\r
+/*\r
+ float signedArea = 0;\r
+ for (int k = 1; k < output->count; k++) {\r
+ signedArea += (output->vertices[k - 1].values[0] * output->vertices[k - 0].values[1]);\r
+ signedArea -= (output->vertices[k - 0].values[0] * output->vertices[k - 1].values[1]);\r
+ }\r
+*/\r
}\r
\r
+#if 0\r
+static inline f32 dot(const sVec2& a,const sVec2& b) { return a.x * b.x + a.y * b.y; }\r
+sVec2 dFdx(const sVec2& v) { return v; }\r
+sVec2 dFdy(const sVec2& v) { return v; }\r
\r
-/*!\r
-*/\r
-inline f32 CBurningVideoDriver::texelarea ( const s4DVertex *v, int tex ) const\r
+f32 MipmapLevel(const sVec2& uv, const sVec2& textureSize)\r
{\r
- f32 z;\r
-\r
- z = ( (v[2].Tex[tex].x - v[0].Tex[tex].x ) * (v[4].Tex[tex].y - v[0].Tex[tex].y ) )\r
- - ( (v[4].Tex[tex].x - v[0].Tex[tex].x ) * (v[2].Tex[tex].y - v[0].Tex[tex].y ) );\r
-\r
- return MAT_TEXTURE ( tex )->getLODFactor ( z );\r
+ sVec2 dx = dFdx(uv * textureSize.x);\r
+ sVec2 dy = dFdy(uv * textureSize.y);\r
+ f32 d = core::max_(dot(dx, dx), dot(dy, dy));\r
+ return log2f(sqrtf(d));\r
}\r
+#endif\r
\r
-/*!\r
- crossproduct in projected 2D\r
-*/\r
-inline f32 CBurningVideoDriver::screenarea2 ( const s4DVertex **v ) const\r
-{\r
- return ( (( v[1] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) * ( (v[2] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) ) -\r
- ( (( v[1] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) * ( (v[2] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) );\r
-}\r
+#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( (u32)tex ) )\r
\r
/*!\r
+ calculate from unprojected.\r
+ attribute need not to follow winding rule from position.\r
+ Edge-walking problem\r
+ Texture Wrapping problem\r
+ Atlas problem\r
*/\r
-inline f32 CBurningVideoDriver::texelarea2 ( const s4DVertex **v, s32 tex ) const\r
+REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burning_restrict const face[],\r
+ const size_t m, f32 dc_area, f32 lod_bias) const\r
{\r
- f32 z;\r
- z = ( (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[2]->Tex[tex].y - v[0]->Tex[tex].y ) )\r
- - ( (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[1]->Tex[tex].y - v[0]->Tex[tex].y ) );\r
+ /*\r
+ sVec2 a(v[1]->Tex[tex].x - v[0]->Tex[tex].x,v[1]->Tex[tex].y - v[0]->Tex[tex].y);\r
+ sVec2 b(v[2]->Tex[tex].x - v[0]->Tex[tex].x,v[2]->Tex[tex].y - v[0]->Tex[tex].y);\r
+ f32 area = a.x * b.y - b.x * a.y;\r
+ */\r
\r
- return MAT_TEXTURE ( tex )->getLODFactor ( z );\r
-}\r
\r
+ /*\r
+ degenerate(A, B, C, minarea) = ((B - A).cross(C - A)).lengthSquared() < (4.0f * minarea * minarea);\r
+ check for collapsed or "long thin triangles"\r
+ */\r
+ ieee754 signedArea;\r
\r
-/*!\r
-*/\r
-inline void CBurningVideoDriver::select_polygon_mipmap ( s4DVertex *v, u32 vIn, u32 tex, const core::dimension2du& texSize ) const\r
-{\r
- f32 f[2];\r
+ ieee754 t[4];\r
+ t[0].f = face[1]->Tex[m].x - face[0]->Tex[m].x;\r
+ t[1].f = face[1]->Tex[m].y - face[0]->Tex[m].y;\r
\r
- f[0] = (f32) texSize.Width - 0.25f;\r
- f[1] = (f32) texSize.Height - 0.25f;\r
+ t[2].f = face[2]->Tex[m].x - face[0]->Tex[m].x;\r
+ t[3].f = face[2]->Tex[m].y - face[0]->Tex[m].y;\r
\r
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
- for ( u32 g = 0; g != vIn; g += 2 )\r
+ //crossproduct in projected 2D -> screen area triangle\r
+ signedArea.f = t[0].f * t[3].f - t[2].f * t[1].f;\r
+\r
+ //signedArea =\r
+ // ((face[1]->Tex[m].x - face[0]->Tex[m].x) * (face[2]->Tex[m].y - face[0]->Tex[m].y))\r
+ // - ((face[2]->Tex[m].x - face[0]->Tex[m].x) * (face[1]->Tex[m].y - face[0]->Tex[m].y));\r
+\r
+ //if (signedArea*signedArea <= 0.00000000001f)\r
+ if (signedArea.fields.exp == 0 )\r
{\r
- (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * ( v + g + 1 )->Pos.w * f[0];\r
- (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * ( v + g + 1 )->Pos.w * f[1];\r
+ ieee754 _max;\r
+ _max.u = t[0].abs.frac_exp;\r
+ if (t[1].abs.frac_exp > _max.u) _max.u = t[1].abs.frac_exp;\r
+ if (t[2].abs.frac_exp > _max.u) _max.u = t[2].abs.frac_exp;\r
+ if (t[3].abs.frac_exp > _max.u) _max.u = t[3].abs.frac_exp;\r
+\r
+ signedArea.u = _max.fields.exp ? _max.u : ieee754_one;\r
+\r
+/*\r
+ //dot,length\r
+ ieee754 v[2];\r
+ v[0].f = t[0] * t[2];\r
+ v[1].f = t[1] * t[3];\r
+\r
+ //signedArea.f = t[4] > t[5] ? t[4] : t[5];\r
+ signedArea.u = v[0].fields.frac > v[1].fields.frac ? v[0].u : v[1].u;\r
+ if (signedArea.fields.exp == 0)\r
+ {\r
+ return -1;\r
+ }\r
+*/\r
}\r
-#else\r
- for ( u32 g = 0; g != vIn; g += 2 )\r
+\r
+ //only guessing: take more detail (lower mipmap) in light+bump textures\r
+ //assume transparent add is ~50% transparent -> more detail\r
+ const u32* d = MAT_TEXTURE(m)->getMipMap0_Area();\r
+ f32 texelspace = d[0] * d[1] * lod_bias; //(m ? 0.5f : 0.5f);\r
+\r
+ ieee754 ratio;\r
+ ratio.f = (signedArea.f * texelspace) * dc_area;\r
+ ratio.fields.sign = 0;\r
+\r
+ //log2(0)==denormal [ use high lod] [ only if dc_area == 0 checked outside ]\r
+#if 0\r
+ if (ratio.fields.exp == 0)\r
{\r
- (v + g + 1 )->Tex[tex].x = (v + g + 0)->Tex[tex].x * f[0];\r
- (v + g + 1 )->Tex[tex].y = (v + g + 0)->Tex[tex].y * f[1];\r
+ int g = 1;\r
}\r
#endif\r
-}\r
+ //log2\r
+ return (ratio.fields.exp & 0x80) ? ratio.fields.exp - 127 : 0; /*denormal very high lod*/\r
\r
-inline void CBurningVideoDriver::select_polygon_mipmap2 ( s4DVertex **v, u32 tex, const core::dimension2du& texSize ) const\r
-{\r
- f32 f[2];\r
+ //return (ratio.f <= 1.f) ? 0 : 1;\r
+ //f32 texArea = MAT_TEXTURE(m)->getLODFactor(signedArea); // texelarea_inside(face, m);\r
+ //s32 lodFactor = s32_log2_f32(texArea * dc_area); /* avoid denorm */\r
+\r
+ //return MAT_TEXTURE(m)->getLODFactor(signedArea);\r
+}\r
\r
- f[0] = (f32) texSize.Width - 0.25f;\r
- f[1] = (f32) texSize.Height - 0.25f;\r
\r
+/*!\r
+ texcoo in current mipmap dimension (face, already clipped)\r
+ -> want to help fixpoint\r
+*/\r
+inline void CBurningVideoDriver::select_polygon_mipmap_inside(s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b) const\r
+{\r
#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
- (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * ( v[0] + 1 )->Pos.w * f[0];\r
- (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * ( v[0] + 1 )->Pos.w * f[1];\r
+#if defined(Tweak_Burning)\r
+ (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * (face[0] + 1)->Pos.w * (b.w + Tweak.tex_w_add) + (b.cx + Tweak.tex_cx_add);\r
+ (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * (face[0] + 1)->Pos.w * (b.h + Tweak.tex_h_add) + (b.cy + Tweak.tex_cy_add);\r
+\r
+ (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * (face[1] + 1)->Pos.w * (b.w + Tweak.tex_w_add) + (b.cx + Tweak.tex_cx_add);\r
+ (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * (face[1] + 1)->Pos.w * (b.h + Tweak.tex_h_add) + (b.cy + Tweak.tex_cy_add);\r
\r
- (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * ( v[1] + 1 )->Pos.w * f[0];\r
- (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * ( v[1] + 1 )->Pos.w * f[1];\r
+ (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * (face[2] + 1)->Pos.w * (b.w + Tweak.tex_w_add) + (b.cx + Tweak.tex_cx_add);\r
+ (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * (face[2] + 1)->Pos.w * (b.h + Tweak.tex_h_add) + (b.cy + Tweak.tex_cy_add);\r
+#else\r
+ (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * (face[0] + 1)->Pos.w * b.w + b.cx;\r
+ (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * (face[0] + 1)->Pos.w * b.h + b.cy;\r
\r
- (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * ( v[2] + 1 )->Pos.w * f[0];\r
- (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * ( v[2] + 1 )->Pos.w * f[1];\r
+ (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * (face[1] + 1)->Pos.w * b.w + b.cx;\r
+ (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * (face[1] + 1)->Pos.w * b.h + b.cy;\r
\r
+ (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * (face[2] + 1)->Pos.w * b.w + b.cx;\r
+ (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * (face[2] + 1)->Pos.w * b.h + b.cy;\r
+#endif\r
#else\r
- (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * f[0];\r
- (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * f[1];\r
+ (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * b.w;\r
+ (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * b.h;\r
\r
- (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * f[0];\r
- (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * f[1];\r
+ (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * b.w;\r
+ (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * b.h;\r
\r
- (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * f[0];\r
- (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * f[1];\r
+ (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * b.w;\r
+ (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * b.h;\r
#endif\r
-}\r
\r
-// Vertex Cache\r
-const SVSize CBurningVideoDriver::vSize[] =\r
-{\r
- { VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 1 },\r
- { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex2TCoords),2 },\r
- { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_BUMP_DOT3, sizeof(S3DVertexTangents),2 },\r
- { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 2 }, // reflection map\r
- { 0, sizeof(f32) * 3, 0 }, // core::vector3df*\r
-};\r
+}\r
\r
\r
+// Vertex Cache\r
\r
-/*!\r
- fill a cache line with transformed, light and clipp test triangles\r
-*/\r
-void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex)\r
+//! setup Vertex Format\r
+void CBurningVideoDriver::VertexCache_map_source_format()\r
{\r
- u8 * source;\r
- s4DVertex *dest;\r
+ u32 s0 = sizeof(s4DVertex);\r
+ u32 s1 = sizeof(s4DVertex_proxy);\r
\r
- source = (u8*) VertexCache.vertices + ( sourceIndex * vSize[VertexCache.vType].Pitch );\r
+ if ( s1 <= sizeof_s4DVertex /2 )\r
+ {\r
+ os::Printer::log ( "BurningVideo vertex format unnecessary to large", ELL_WARNING );\r
+ }\r
\r
- // it's a look ahead so we never hit it..\r
- // but give priority...\r
- //VertexCache.info[ destIndex ].hit = hitCount;\r
+ //memcpy_vertex\r
+ if ( s0 != sizeof_s4DVertex || ((sizeof_s4DVertex * sizeof_s4DVertexPairRel)&31))\r
+ {\r
+ os::Printer::log ( "BurningVideo vertex format compile problem", ELL_ERROR );\r
+ _IRR_DEBUG_BREAK_IF(1);\r
+ }\r
\r
- // store info\r
- VertexCache.info[ destIndex ].index = sourceIndex;\r
- VertexCache.info[ destIndex ].hit = 0;\r
+#if defined(ENV64BIT)\r
+ if (sizeof(void*) != 8)\r
+ {\r
+ os::Printer::log("BurningVideo pointer should be 8 bytes", ELL_ERROR);\r
+ _IRR_DEBUG_BREAK_IF(1);\r
+ }\r
+#endif\r
\r
- // destination Vertex\r
- dest = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( destIndex << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );\r
+ SVSize* vSize = VertexCache.vSize;\r
+ //vSize[E4VT_STANDARD].Format = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_SPECULAR;\r
+ vSize[E4VT_STANDARD].Format = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_2_FOG;\r
+ vSize[E4VT_STANDARD].Pitch = sizeof(S3DVertex);\r
+ vSize[E4VT_STANDARD].TexSize = 1;\r
+ vSize[E4VT_STANDARD].TexCooSize = 1;\r
+\r
+ vSize[E4VT_2TCOORDS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1;\r
+ vSize[E4VT_2TCOORDS].Pitch = sizeof(S3DVertex2TCoords);\r
+ vSize[E4VT_2TCOORDS].TexSize = 2;\r
+ vSize[E4VT_2TCOORDS].TexCooSize = 2;\r
+\r
+ //vSize[E4VT_TANGENTS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_BUMP_DOT3;\r
+ vSize[E4VT_TANGENTS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_2_FOG | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_BUMP_DOT3;\r
+ vSize[E4VT_TANGENTS].Pitch = sizeof(S3DVertexTangents);\r
+ vSize[E4VT_TANGENTS].TexSize = 2;\r
+ vSize[E4VT_TANGENTS].TexCooSize = 2;\r
+\r
+ // reflection map\r
+ vSize[E4VT_REFLECTION_MAP].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1;\r
+ vSize[E4VT_REFLECTION_MAP].Pitch = sizeof(S3DVertex);\r
+ vSize[E4VT_REFLECTION_MAP].TexSize = 2;\r
+ vSize[E4VT_REFLECTION_MAP].TexCooSize = 1; //TexCoo2 generated\r
+\r
+ // shadow\r
+ vSize[E4VT_SHADOW].Format = 0;\r
+ vSize[E4VT_SHADOW].Pitch = sizeof(f32) * 3; // core::vector3df*\r
+ vSize[E4VT_SHADOW].TexSize = 0;\r
+ vSize[E4VT_SHADOW].TexCooSize = 0;\r
+\r
+ // color shading only (no texture)\r
+ vSize[E4VT_NO_TEXTURE].Format = VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_SPECULAR;\r
+ vSize[E4VT_NO_TEXTURE].Pitch = sizeof(S3DVertex);\r
+ vSize[E4VT_NO_TEXTURE].TexSize = 0;\r
+ vSize[E4VT_NO_TEXTURE].TexCooSize = 0;\r
+\r
+ //Line\r
+ vSize[E4VT_LINE].Format = VERTEX4D_FORMAT_COLOR_1;\r
+ vSize[E4VT_LINE].Pitch = sizeof(S3DVertex);\r
+ vSize[E4VT_LINE].TexSize = 0;\r
+ vSize[E4VT_LINE].TexCooSize = 0;\r
+\r
+ size_t size;\r
+ for ( size_t i = 0; i < E4VT_COUNT; ++i )\r
+ {\r
+ size_t& flag = vSize[i].Format;\r
+\r
+#if !defined(SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR)\r
+ flag &= ~VERTEX4D_FORMAT_SPECULAR;\r
+#endif\r
+ if ( vSize[i].TexSize > BURNING_MATERIAL_MAX_TEXTURES )\r
+ vSize[i].TexSize = BURNING_MATERIAL_MAX_TEXTURES;\r
+\r
+ size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;\r
+ if ( size > BURNING_MATERIAL_MAX_TEXTURES )\r
+ {\r
+ flag = (flag & ~VERTEX4D_FORMAT_MASK_TEXTURE) | (BURNING_MATERIAL_MAX_TEXTURES << 16);\r
+ }\r
+\r
+ size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;\r
+ if ( size > BURNING_MATERIAL_MAX_COLORS )\r
+ {\r
+ flag = (flag & ~VERTEX4D_FORMAT_MASK_COLOR) | (BURNING_MATERIAL_MAX_COLORS << 20);\r
+ }\r
+\r
+ size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24;\r
+ if ( size > BURNING_MATERIAL_MAX_LIGHT_TANGENT)\r
+ {\r
+ flag = (flag & ~VERTEX4D_FORMAT_MASK_LIGHT) | (BURNING_MATERIAL_MAX_LIGHT_TANGENT << 24);\r
+ }\r
+ }\r
+\r
+ VertexCache.mem.resize(VERTEXCACHE_ELEMENT * 2);\r
+ VertexCache.vType = E4VT_STANDARD;\r
+\r
+ Clipper.resize(VERTEXCACHE_ELEMENT * 2);\r
+ Clipper_temp.resize(VERTEXCACHE_ELEMENT * 2);\r
+\r
+ TransformationStack = 0;\r
+ memset(TransformationFlag, 0, sizeof(TransformationFlag));\r
+ memset(Transformation_ETS_CLIPSCALE, 0, sizeof(Transformation_ETS_CLIPSCALE));\r
+\r
+ Material.resetRenderStates = true;\r
+ Material.Fallback_MaterialType = EMT_SOLID;\r
+\r
+\r
+}\r
+\r
+\r
+\r
+/*!\r
+ fill a cache line with transformed, light and clip test triangles\r
+ overhead - if primitive is outside or culled, vertexLighting and TextureTransform is still done\r
+*/\r
+void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex)\r
+{\r
+ u8* burning_restrict source;\r
+ s4DVertex* burning_restrict dest;\r
+\r
+ source = (u8*) VertexCache.vertices + ( sourceIndex * VertexCache.vSize[VertexCache.vType].Pitch );\r
+\r
+ // it's a look ahead so we never hit it..\r
+ // but give priority...\r
+ //VertexCache.info[ destIndex ].hit = hitCount;\r
+\r
+ // store info\r
+ VertexCache.info[ destIndex ].index = sourceIndex;\r
+ VertexCache.info[ destIndex ].hit = 0;\r
+\r
+ // destination Vertex\r
+ dest = VertexCache.mem.data + s4DVertex_ofs(destIndex);\r
+\r
+ //Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents\r
+ const S3DVertex* base = ((S3DVertex*)source);\r
\r
// transform Model * World * Camera * Projection * NDCSpace matrix\r
- const S3DVertex *base = ((S3DVertex*) source );\r
- Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, base->Pos );\r
+ const core::matrix4* matrix = Transformation[TransformationStack];\r
+ matrix[ETS_PROJ_MODEL_VIEW].transformVect(&dest->Pos.x, base->Pos);\r
+\r
+ //mhm ... maybe no goto\r
+ if (VertexCache.vType == E4VT_SHADOW)\r
+ {\r
+ //core::vector3df i = base->Pos;\r
+ //i.Z -= 0.5f;\r
+ //matrix[ETS_PROJ_MODEL_VIEW].transformVect(&dest->Pos.x, i);\r
\r
- //mhm ;-) maybe no goto\r
- if ( VertexCache.vType == 4 ) goto clipandproject;\r
+ //GL_DEPTH_CLAMP,EVDF_DEPTH_CLAMP\r
+ //if ( dest->Pos.z < dest->Pos.w)\r
+ // dest->Pos.z = dest->Pos.w*0.99f;\r
+\r
+ //glPolygonOffset // self shadow wanted or not?\r
+ dest->Pos.w *= 1.005f;\r
+\r
+ //flag |= v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_NEAR : 0;\r
+ //flag |= -v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_FAR : 0;\r
+\r
+ goto clipandproject;\r
+ }\r
\r
\r
#if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )\r
\r
- // vertex normal in light space\r
- if ( Material.org.Lighting || (LightSpace.Flags & VERTEXTRANSFORM) )\r
+ // vertex, normal in light(eye) space\r
+ if ( Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM|TL_FOG)) )\r
{\r
- if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY )\r
- {\r
- LightSpace.normal.set ( base->Normal.X, base->Normal.Y, base->Normal.Z, 1.f );\r
- LightSpace.vertex.set ( base->Pos.X, base->Pos.Y, base->Pos.Z, 1.f );\r
- }\r
- else\r
- {\r
- Transformation[ETS_WORLD].rotateVect ( &LightSpace.normal.x, base->Normal );\r
+ sVec4 vertex4; //eye coordinate position of vertex\r
+ matrix[ETS_MODEL_VIEW].transformVect ( &vertex4.x, base->Pos );\r
\r
- // vertex in light space\r
- if ( LightSpace.Flags & ( POINTLIGHT | FOG | SPECULAR | VERTEXTRANSFORM) )\r
- Transformation[ETS_WORLD].transformVect ( &LightSpace.vertex.x, base->Pos );\r
- }\r
+ f32 iw = reciprocal_zero(vertex4.w);\r
+ EyeSpace.vertex.x = vertex4.x * iw;\r
+ EyeSpace.vertex.y = vertex4.y * iw;\r
+ EyeSpace.vertex.z = vertex4.z * iw;\r
+ EyeSpace.vertex.w = iw;\r
+\r
+ //EyeSpace.cam_distance = EyeSpace.vertex.length_xyz();\r
+ EyeSpace.cam_dir = EyeSpace.vertex;\r
+ EyeSpace.cam_dir.normalize_dir_xyz();\r
\r
- if ( LightSpace.Flags & NORMALIZE )\r
- LightSpace.normal.normalize_xyz();\r
+ matrix[ETS_NORMAL].rotateVect(&EyeSpace.normal.x, base->Normal);\r
+ if (EyeSpace.TL_Flag & TL_NORMALIZE_NORMALS)\r
+ EyeSpace.normal.normalize_dir_xyz();\r
\r
}\r
\r
#endif\r
\r
-#if defined ( SOFTWARE_DRIVER_2_USE_VERTEX_COLOR )\r
- // apply lighting model\r
- #if defined (SOFTWARE_DRIVER_2_LIGHTING)\r
- if ( Material.org.Lighting )\r
- {\r
- lightVertex ( dest, base->Color.color );\r
- }\r
- else\r
- {\r
- dest->Color[0].setA8R8G8B8 ( base->Color.color );\r
- }\r
- #else\r
+#if BURNING_MATERIAL_MAX_COLORS > 1\r
+ dest->Color[1].a = 1.f;\r
+ dest->Color[1].r = 0.f;\r
+ dest->Color[1].g = 0.f;\r
+ dest->Color[1].b = 0.f;\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS > 2\r
+ dest->Color[2].a = 1.f;\r
+ dest->Color[2].r = 0.f;\r
+ dest->Color[2].g = 0.f;\r
+ dest->Color[2].b = 0.f;\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS > 3\r
+ dest->Color[3].a = 1.f;\r
+ dest->Color[3].r = 0.f;\r
+ dest->Color[3].g = 0.f;\r
+ dest->Color[3].b = 0.f;\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+ dest->LightTangent[0].x = 0.f;\r
+ dest->LightTangent[0].y = 0.f;\r
+ dest->LightTangent[0].z = 0.f;\r
+#endif\r
+\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+// apply lighting model\r
+#if defined (SOFTWARE_DRIVER_2_LIGHTING)\r
+ if ( Material.org.Lighting )\r
+ {\r
+ lightVertex_eye ( dest, base->Color.color );\r
+ }\r
+ else\r
+ {\r
dest->Color[0].setA8R8G8B8 ( base->Color.color );\r
- #endif\r
+ }\r
+#else\r
+ dest->Color[0].setA8R8G8B8 ( base->Color.color );\r
#endif\r
+#endif\r
+\r
+ //vertex fog\r
+ if (EyeSpace.TL_Flag & TL_FOG ) //Material.org.FogEnable\r
+ {\r
+ f32 fog_factor = 1.f;\r
+\r
+ // GL_FRAGMENT_DEPTH -> abs(EyeSpace.vertex.z)\r
+ ieee754 fog_frag_coord;\r
+ fog_frag_coord.f = EyeSpace.vertex.z;\r
+ fog_frag_coord.fields.sign = 0;\r
+\r
+ switch (FogType)\r
+ {\r
+ case EFT_FOG_LINEAR:\r
+ fog_factor = (FogEnd - fog_frag_coord.f) * EyeSpace.fog_scale;\r
+ break;\r
+ case EFT_FOG_EXP:\r
+ fog_factor = (f32)exp(-FogDensity * fog_frag_coord.f);\r
+ break;\r
+ case EFT_FOG_EXP2:\r
+ fog_factor = (f32)exp(-FogDensity * FogDensity * fog_frag_coord.f * fog_frag_coord.f);\r
+ break;\r
+ }\r
+\r
+ sVec4* a = dest->Color + ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG) ? 1 : 0);\r
+ a->a = core::clamp(fog_factor, 0.f, 1.f);\r
+ }\r
\r
// Texture Transform\r
-#if !defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )\r
- irr::memcpy32_small ( &dest->Tex[0],&base->TCoords,\r
- vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 )\r
- );\r
-#else\r
+#if defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )\r
\r
- if ( 0 == (LightSpace.Flags & VERTEXTRANSFORM) )\r
+ if ( 0 == (EyeSpace.TL_Flag & TL_TEXTURE_TRANSFORM) )\r
+#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
{\r
- irr::memcpy32_small ( &dest->Tex[0],&base->TCoords,\r
- vSize[VertexCache.vType].TexSize << 3 // * ( sizeof ( f32 ) * 2 )\r
- );\r
+ // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address!\r
+ const f32* baseTCoord = &base->TCoords.X;\r
+\r
+ switch (VertexCache.vSize[VertexCache.vType].TexCooSize)\r
+ {\r
+#if BURNING_MATERIAL_MAX_TEXTURES == 4\r
+ case 0:\r
+ dest->Tex[0].x = 0.f;\r
+ dest->Tex[0].y = 0.f;\r
+ dest->Tex[1].x = 0.f;\r
+ dest->Tex[1].y = 0.f;\r
+ dest->Tex[2].x = 0.f;\r
+ dest->Tex[2].y = 0.f;\r
+ dest->Tex[3].x = 0.f;\r
+ dest->Tex[3].y = 0.f;\r
+ break;\r
+ case 1:\r
+ dest->Tex[0].x = baseTCoord[0];\r
+ dest->Tex[0].y = baseTCoord[1];\r
+ dest->Tex[1].x = 0.f;\r
+ dest->Tex[1].y = 0.f;\r
+ dest->Tex[2].x = 0.f;\r
+ dest->Tex[2].y = 0.f;\r
+ dest->Tex[3].x = 0.f;\r
+ dest->Tex[3].y = 0.f;\r
+ break;\r
+ case 2:\r
+ dest->Tex[0].x = baseTCoord[0];\r
+ dest->Tex[0].y = baseTCoord[1];\r
+ dest->Tex[1].x = baseTCoord[2];\r
+ dest->Tex[1].y = baseTCoord[3];\r
+ dest->Tex[2].x = 0.f;\r
+ dest->Tex[2].y = 0.f;\r
+ dest->Tex[3].x = 0.f;\r
+ dest->Tex[3].y = 0.f;\r
+ break;\r
+ case 3:\r
+ dest->Tex[0].x = baseTCoord[0];\r
+ dest->Tex[0].y = baseTCoord[1];\r
+ dest->Tex[1].x = baseTCoord[2];\r
+ dest->Tex[1].y = baseTCoord[3];\r
+ dest->Tex[2].x = baseTCoord[4];\r
+ dest->Tex[2].y = baseTCoord[5];\r
+ dest->Tex[3].x = 0.f;\r
+ dest->Tex[3].y = 0.f;\r
+ break;\r
+ case 4:\r
+ dest->Tex[0].x = baseTCoord[0];\r
+ dest->Tex[0].y = baseTCoord[1];\r
+ dest->Tex[1].x = baseTCoord[2];\r
+ dest->Tex[1].y = baseTCoord[3];\r
+ dest->Tex[2].x = baseTCoord[4];\r
+ dest->Tex[2].y = baseTCoord[5];\r
+ dest->Tex[3].x = baseTCoord[6];\r
+ dest->Tex[3].y = baseTCoord[7];\r
+ break;\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_TEXTURES == 2\r
+ case 0:\r
+ dest->Tex[0].x = 0.f;\r
+ dest->Tex[0].y = 0.f;\r
+ dest->Tex[1].x = 0.f;\r
+ dest->Tex[1].y = 0.f;\r
+ break;\r
+\r
+ case 1:\r
+ dest->Tex[0].x = baseTCoord[0];\r
+ dest->Tex[0].y = baseTCoord[1];\r
+ dest->Tex[1].x = 0.f;\r
+ dest->Tex[1].y = 0.f;\r
+ break;\r
+ case 2:\r
+ dest->Tex[0].x = baseTCoord[0];\r
+ dest->Tex[0].y = baseTCoord[1];\r
+ dest->Tex[1].x = baseTCoord[2];\r
+ dest->Tex[1].y = baseTCoord[3];\r
+ break;\r
+#endif\r
+#if BURNING_MATERIAL_MAX_TEXTURES == 1\r
+ case 0:\r
+ dest->Tex[0].x = 0.f;\r
+ dest->Tex[0].y = 0.f;\r
+ break;\r
+ case 1:\r
+ dest->Tex[0].x = baseTCoord[0];\r
+ dest->Tex[0].y = baseTCoord[1];\r
+ break;\r
+#endif\r
+ default:\r
+ break;\r
+ }\r
}\r
+#if defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )\r
else\r
{\r
/*\r
Uw Vw 0 0\r
*/\r
\r
- u32 t;\r
- sVec4 n;\r
- sVec2 srcT;\r
+ const sVec4& u = EyeSpace.cam_dir; // EyeSpace.vertex.normalized\r
+ const sVec4& n = EyeSpace.normal;\r
+ sVec4 r;\r
\r
- for ( t = 0; t != vSize[VertexCache.vType].TexSize; ++t )\r
+ const size_t* flag = TransformationFlag[TransformationStack];\r
+ for ( u32 t = 0; t != VertexCache.vSize[VertexCache.vType].TexSize; ++t )\r
{\r
- const core::matrix4& M = Transformation [ ETS_TEXTURE_0 + t ];\r
-\r
// texgen\r
- if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & (ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION) )\r
+ if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_SPHERE )\r
{\r
- n.x = LightSpace.campos.x - LightSpace.vertex.x;\r
- n.y = LightSpace.campos.x - LightSpace.vertex.y;\r
- n.z = LightSpace.campos.x - LightSpace.vertex.z;\r
- n.normalize_xyz();\r
- n.x += LightSpace.normal.x;\r
- n.y += LightSpace.normal.y;\r
- n.z += LightSpace.normal.z;\r
- n.normalize_xyz();\r
-\r
- const f32 *view = Transformation[ETS_VIEW].pointer();\r
-\r
- if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & ETF_TEXGEN_CAMERA_REFLECTION )\r
- {\r
- srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[4] + n.z * view[8] ));\r
- srcT.y = 0.5f * ( 1.f + (n.x * view[1] + n.y * view[5] + n.z * view[9] ));\r
- }\r
- else\r
- {\r
- srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[1] + n.z * view[2] ));\r
- srcT.y = 0.5f * ( 1.f + (n.x * view[4] + n.y * view[5] + n.z * view[6] ));\r
- }\r
+ //reflect(u,N) u - 2.0 * dot(N, u) * N\r
+ // cam is (0,0,-1), tex flipped\r
+ f32 dot = -2.f * n.dot_xyz(u);\r
+ r.x = u.x + dot * n.x;\r
+ r.y = u.y + dot * n.y;\r
+ r.z = u.z + dot * n.z;\r
+\r
+ //openGL\r
+ f32 m = 2.f * sqrtf(r.x*r.x+r.y*r.y+(r.z+1.f)*(r.z+1.f));\r
+ dest[0].Tex[t].x = r.x / m + 0.5f;\r
+ dest[0].Tex[t].y = -r.y / m + 0.5f;\r
+\r
+/*\r
+ //~d3d with spheremap scale\r
+ f32 m = 0.25f / (0.00001f + sqrtf(r.x*r.x+r.y*r.y+r.z*r.z));\r
+ dest[0].Tex[t].x = r.x * m + 0.5f;\r
+ dest[0].Tex[t].y = -r.y * m + 0.5f;\r
+*/\r
}\r
- else\r
+ else if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_REFLECTION )\r
{\r
- irr::memcpy32_small ( &srcT,(&base->TCoords) + t,\r
- sizeof ( f32 ) * 2 );\r
+ //reflect(u,N) u - 2.0 * dot(N, u) * N\r
+ // cam is (0,0,-1), tex flipped\r
+ f32 dot = -2.f * n.dot_xyz(u);\r
+ r.x = u.x + dot * n.x;\r
+ r.y = u.y + dot * n.y;\r
+ r.z = u.z + dot * n.z;\r
+\r
+ //openGL\r
+ dest[0].Tex[t].x = r.x;\r
+ dest[0].Tex[t].y = -r.y;\r
+/*\r
+ //~d3d with spheremap scale\r
+ dest[0].Tex[t].x = r.x;\r
+ dest[0].Tex[t].y = r.y;\r
+*/\r
}\r
-\r
- switch ( Material.org.TextureLayer[t].TextureWrapU )\r
+ else if (VertexCache.vSize[VertexCache.vType].TexCooSize > t)\r
{\r
- case ETC_CLAMP:\r
- case ETC_CLAMP_TO_EDGE:\r
- case ETC_CLAMP_TO_BORDER:\r
- dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );\r
+ const f32* M = matrix[ETS_TEXTURE_0 + t].pointer();\r
+\r
+ // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address!\r
+ const f32* baseTCoord = &base->TCoords.X;\r
+\r
+ sVec4 srcT;\r
+ srcT.x = baseTCoord[(t * 2) + 0];\r
+ srcT.y = baseTCoord[(t * 2) + 1];\r
+\r
+ switch ( Material.org.TextureLayer[t].TextureWrapU )\r
+ {\r
+ case ETC_CLAMP:\r
+ case ETC_CLAMP_TO_EDGE:\r
+ case ETC_CLAMP_TO_BORDER:\r
+ dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );\r
+ break;\r
+ case ETC_MIRROR:\r
+ dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];\r
+ if (core::fract(dest->Tex[t].x)>0.5f)\r
+ dest->Tex[t].x=1.f-dest->Tex[t].x;\r
break;\r
- case ETC_MIRROR:\r
- dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];\r
- if (core::fract(dest->Tex[t].x)>0.5f)\r
- dest->Tex[t].x=1.f-dest->Tex[t].x;\r
- break;\r
- case ETC_MIRROR_CLAMP:\r
- case ETC_MIRROR_CLAMP_TO_EDGE:\r
- case ETC_MIRROR_CLAMP_TO_BORDER:\r
- dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );\r
- if (core::fract(dest->Tex[t].x)>0.5f)\r
- dest->Tex[t].x=1.f-dest->Tex[t].x;\r
- break;\r
- case ETC_REPEAT:\r
- default:\r
- dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];\r
+ case ETC_MIRROR_CLAMP:\r
+ case ETC_MIRROR_CLAMP_TO_EDGE:\r
+ case ETC_MIRROR_CLAMP_TO_BORDER:\r
+ dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );\r
+ if (core::fract(dest->Tex[t].x)>0.5f)\r
+ dest->Tex[t].x=1.f-dest->Tex[t].x;\r
break;\r
- }\r
- switch ( Material.org.TextureLayer[t].TextureWrapV )\r
- {\r
- case ETC_CLAMP:\r
- case ETC_CLAMP_TO_EDGE:\r
- case ETC_CLAMP_TO_BORDER:\r
- dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );\r
+ case ETC_REPEAT:\r
+ default:\r
+ dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];\r
+ break;\r
+ }\r
+ switch ( Material.org.TextureLayer[t].TextureWrapV )\r
+ {\r
+ case ETC_CLAMP:\r
+ case ETC_CLAMP_TO_EDGE:\r
+ case ETC_CLAMP_TO_BORDER:\r
+ dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );\r
+ break;\r
+ case ETC_MIRROR:\r
+ dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];\r
+ if (core::fract(dest->Tex[t].y)>0.5f)\r
+ dest->Tex[t].y=1.f-dest->Tex[t].y;\r
break;\r
- case ETC_MIRROR:\r
- dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];\r
- if (core::fract(dest->Tex[t].y)>0.5f)\r
- dest->Tex[t].y=1.f-dest->Tex[t].y;\r
- break;\r
- case ETC_MIRROR_CLAMP:\r
- case ETC_MIRROR_CLAMP_TO_EDGE:\r
- case ETC_MIRROR_CLAMP_TO_BORDER:\r
- dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );\r
- if (core::fract(dest->Tex[t].y)>0.5f)\r
- dest->Tex[t].y=1.f-dest->Tex[t].y;\r
- break;\r
- case ETC_REPEAT:\r
- default:\r
- dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];\r
+ case ETC_MIRROR_CLAMP:\r
+ case ETC_MIRROR_CLAMP_TO_EDGE:\r
+ case ETC_MIRROR_CLAMP_TO_BORDER:\r
+ dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );\r
+ if (core::fract(dest->Tex[t].y)>0.5f)\r
+ dest->Tex[t].y=1.f-dest->Tex[t].y;\r
break;\r
+ case ETC_REPEAT:\r
+ default:\r
+ dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];\r
+ break;\r
+ }\r
}\r
}\r
}\r
\r
-#if 0\r
- // tangent space light vector, emboss\r
- if ( Lights.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) )\r
- {\r
- const S3DVertexTangents *tangent = ((S3DVertexTangents*) source );\r
- const SBurningShaderLight &light = LightSpace.Light[0];\r
-\r
- sVec4 vp;\r
-\r
- vp.x = light.pos.x - LightSpace.vertex.x;\r
- vp.y = light.pos.y - LightSpace.vertex.y;\r
- vp.z = light.pos.z - LightSpace.vertex.z;\r
-\r
- vp.normalize_xyz();\r
-\r
- LightSpace.tangent.x = vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z;\r
- LightSpace.tangent.y = vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z;\r
- //LightSpace.tangent.z = vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z;\r
- LightSpace.tangent.z = 0.f;\r
- LightSpace.tangent.normalize_xyz();\r
-\r
- f32 scale = 1.f / 128.f;\r
- if ( Material.org.MaterialTypeParam > 0.f )\r
- scale = Material.org.MaterialTypeParam;\r
-\r
- // emboss, shift coordinates\r
- dest->Tex[1].x = dest->Tex[0].x + LightSpace.tangent.x * scale;\r
- dest->Tex[1].y = dest->Tex[0].y + LightSpace.tangent.y * scale;\r
- //dest->Tex[1].z = LightSpace.tangent.z * scale;\r
- }\r
-#endif\r
\r
- if ( LightSpace.Light.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) )\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+ if ((EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) &&\r
+ ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_MASK_TANGENT) == VERTEX4D_FORMAT_BUMP_DOT3)\r
+ )\r
{\r
const S3DVertexTangents *tangent = ((S3DVertexTangents*) source );\r
\r
sVec4 vp;\r
-\r
- dest->LightTangent[0].x = 0.f;\r
- dest->LightTangent[0].y = 0.f;\r
- dest->LightTangent[0].z = 0.f;\r
- for ( u32 i = 0; i < 2 && i < LightSpace.Light.size (); ++i )\r
+ sVec4 light_accu;\r
+ light_accu.x = 0.f;\r
+ light_accu.y = 0.f;\r
+ light_accu.z = 0.f;\r
+ light_accu.w = 0.f;\r
+ for ( u32 i = 0; i < 2 && i < EyeSpace.Light.size (); ++i )\r
{\r
- const SBurningShaderLight &light = LightSpace.Light[i];\r
-\r
+ const SBurningShaderLight &light = EyeSpace.Light[i];\r
if ( !light.LightIsOn )\r
continue;\r
\r
- vp.x = light.pos.x - LightSpace.vertex.x;\r
- vp.y = light.pos.y - LightSpace.vertex.y;\r
- vp.z = light.pos.z - LightSpace.vertex.z;\r
-\r
- /*\r
- vp.x = light.pos_objectspace.x - base->Pos.X;\r
- vp.y = light.pos_objectspace.y - base->Pos.Y;\r
- vp.z = light.pos_objectspace.z - base->Pos.Z;\r
- */\r
-\r
- vp.normalize_xyz();\r
-\r
+ // lightcolor with standard model\r
+ // but shader is different. treating light and vertex in same space\r
+#if 1\r
+ vp.x = light.pos.x - base->Pos.X;\r
+ vp.y = light.pos.y - base->Pos.Y;\r
+ vp.z = light.pos.z - base->Pos.Z;\r
+#else\r
+ vp.x = light.pos4.x - EyeSpace.vertex.x;\r
+ vp.y = light.pos4.y - EyeSpace.vertex.y;\r
+ vp.z = light.pos4.z - EyeSpace.vertex.z;\r
+#endif\r
\r
// transform by tangent matrix\r
- sVec3 l;\r
- #if 1\r
- l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z );\r
- l.y = (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z );\r
- l.z = (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z );\r
- #else\r
- l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Binormal.X + vp.z * tangent->Normal.X );\r
- l.y = (vp.x * tangent->Tangent.Y + vp.y * tangent->Binormal.Y + vp.z * tangent->Normal.Y );\r
- l.z = (vp.x * tangent->Tangent.Z + vp.y * tangent->Binormal.Z + vp.z * tangent->Normal.Z );\r
- #endif\r
-\r
-\r
- /*\r
- f32 scale = 1.f / 128.f;\r
- scale /= dest->LightTangent[0].b;\r
-\r
- // emboss, shift coordinates\r
- dest->Tex[1].x = dest->Tex[0].x + l.r * scale;\r
- dest->Tex[1].y = dest->Tex[0].y + l.g * scale;\r
- */\r
- dest->Tex[1].x = dest->Tex[0].x;\r
- dest->Tex[1].y = dest->Tex[0].y;\r
-\r
- // scale bias\r
- dest->LightTangent[0].x += l.x;\r
- dest->LightTangent[0].y += l.y;\r
- dest->LightTangent[0].z += l.z;\r
+ light_accu.x += (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z );\r
+ light_accu.y += (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z );\r
+ light_accu.z += (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z );\r
}\r
- dest->LightTangent[0].setLength ( 0.5f );\r
- dest->LightTangent[0].x += 0.5f;\r
- dest->LightTangent[0].y += 0.5f;\r
- dest->LightTangent[0].z += 0.5f;\r
- }\r
+ //normalize [-1,+1] to [0,1] -> obsolete\r
+ light_accu.normalize_pack_xyz(dest->LightTangent[0],1.f, 0.f);\r
+ dest->Tex[1].x = dest->Tex[0].x;\r
+ dest->Tex[1].y = dest->Tex[0].y;\r
\r
+ }\r
+ else if (Material.org.Lighting)\r
+ {\r
+ //dest->LightTangent[0].x = 0.f;\r
+ //dest->LightTangent[0].y = 0.f;\r
+ //dest->LightTangent[0].z = 0.f;\r
+ }\r
+#endif //if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
\r
-#endif\r
+#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
\r
clipandproject:\r
- dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format;\r
\r
- // test vertex\r
- dest[0].flag |= clipToFrustumTest ( dest);\r
+ // test vertex visible\r
+ dest[0].flag = (u32) (clipToFrustumTest(dest) | VertexCache.vSize[VertexCache.vType].Format);\r
+ dest[1].flag = dest[0].flag;\r
\r
// to DC Space, project homogenous vertex\r
if ( (dest[0].flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE )\r
{\r
- ndc_2_dc_and_project2 ( (const s4DVertex**) &dest, 1 );\r
+ ndc_2_dc_and_project ( dest+1, dest, s4DVertex_ofs(1));\r
}\r
\r
- //return dest;\r
}\r
\r
-//\r
\r
-REALINLINE s4DVertex * CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex )\r
+//todo: this should return only index\r
+s4DVertexPair* CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex ) const\r
{\r
- for ( s32 i = 0; i < VERTEXCACHE_ELEMENT; ++i )\r
+ for ( size_t i = 0; i < VERTEXCACHE_ELEMENT; ++i )\r
{\r
if ( VertexCache.info[ i ].index == sourceIndex )\r
{\r
- return (s4DVertex *) ( (u8*) VertexCache.mem.data + ( i << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );\r
+ return VertexCache.mem.data + s4DVertex_ofs(i);\r
}\r
}\r
- return 0;\r
+ return VertexCache.mem.data; //error\r
}\r
\r
\r
fill blockwise on the next 16(Cache_Size) unique vertices in indexlist\r
merge the next 16 vertices with the current\r
*/\r
-REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)\r
+void CBurningVideoDriver::VertexCache_get(s4DVertexPair* face[4])\r
{\r
- SCacheInfo info[VERTEXCACHE_ELEMENT];\r
-\r
// next primitive must be complete in cache\r
- if ( VertexCache.indicesIndex - VertexCache.indicesRun < 3 &&\r
+ if ( VertexCache.indicesIndex - VertexCache.indicesRun < VertexCache.primitiveHasVertex &&\r
VertexCache.indicesIndex < VertexCache.indexCount\r
)\r
{\r
+\r
+ size_t i;\r
+ //memset(info, VERTEXCACHE_MISS, sizeof(info));\r
+ for (i = 0; i != VERTEXCACHE_ELEMENT; ++i)\r
+ {\r
+ VertexCache.info_temp[i].hit = VERTEXCACHE_MISS;\r
+ VertexCache.info_temp[i].index = VERTEXCACHE_MISS;\r
+ }\r
+\r
// rewind to start of primitive\r
VertexCache.indicesIndex = VertexCache.indicesRun;\r
\r
- irr::memset32 ( info, VERTEXCACHE_MISS, sizeof ( info ) );\r
\r
// get the next unique vertices cache line\r
u32 fillIndex = 0;\r
u32 dIndex = 0;\r
- u32 i = 0;\r
u32 sourceIndex = 0;\r
\r
while ( VertexCache.indicesIndex < VertexCache.indexCount &&\r
{\r
switch ( VertexCache.iType )\r
{\r
- case 1:\r
+ case E4IT_16BIT:\r
sourceIndex = ((u16*)VertexCache.indices) [ VertexCache.indicesIndex ];\r
break;\r
- case 2:\r
+ case E4IT_32BIT:\r
sourceIndex = ((u32*)VertexCache.indices) [ VertexCache.indicesIndex ];\r
break;\r
- case 4:\r
+ default:\r
+ case E4IT_NONE:\r
sourceIndex = VertexCache.indicesIndex;\r
break;\r
}\r
s32 exist = 0;\r
for ( dIndex = 0; dIndex < fillIndex; ++dIndex )\r
{\r
- if ( info[ dIndex ].index == sourceIndex )\r
+ if (VertexCache.info_temp[ dIndex ].index == sourceIndex )\r
{\r
exist = 1;\r
break;\r
\r
if ( 0 == exist )\r
{\r
- info[fillIndex++].index = sourceIndex;\r
+ VertexCache.info_temp[fillIndex++].index = sourceIndex;\r
}\r
}\r
\r
{\r
for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex )\r
{\r
- if ( VertexCache.info[ dIndex ].index == info[i].index )\r
+ if ( VertexCache.info[ dIndex ].index == VertexCache.info_temp[i].index )\r
{\r
- info[i].hit = dIndex;\r
+ VertexCache.info_temp[i].hit = dIndex;\r
VertexCache.info[ dIndex ].hit = 1;\r
break;\r
}\r
// fill new\r
for ( i = 0; i!= fillIndex; ++i )\r
{\r
- if ( info[i].hit != VERTEXCACHE_MISS )\r
+ if (VertexCache.info_temp[i].hit != VERTEXCACHE_MISS )\r
continue;\r
\r
for ( dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex )\r
{\r
if ( 0 == VertexCache.info[dIndex].hit )\r
{\r
- VertexCache_fill ( info[i].index, dIndex );\r
+ VertexCache_fill (VertexCache.info_temp[i].index, dIndex );\r
VertexCache.info[dIndex].hit += 1;\r
- info[i].hit = dIndex;\r
+ VertexCache.info_temp[i].hit = dIndex;\r
break;\r
}\r
}\r
}\r
}\r
\r
- const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );\r
+ //const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );\r
+ const u32 i0 = VertexCache.pType != scene::EPT_TRIANGLE_FAN ? VertexCache.indicesRun : 0;\r
\r
switch ( VertexCache.iType )\r
{\r
- case 1:\r
+ case E4IT_16BIT:\r
{\r
- const u16 *p = (const u16 *) VertexCache.indices;\r
+ const u16* p = (const u16*) VertexCache.indices;\r
face[0] = VertexCache_getVertex ( p[ i0 ] );\r
face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] );\r
face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] );\r
}\r
break;\r
\r
- case 2:\r
+ case E4IT_32BIT:\r
{\r
- const u32 *p = (const u32 *) VertexCache.indices;\r
+ const u32* p = (const u32*) VertexCache.indices;\r
face[0] = VertexCache_getVertex ( p[ i0 ] );\r
face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] );\r
face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] );\r
}\r
break;\r
\r
- case 4:\r
+ case E4IT_NONE:\r
face[0] = VertexCache_getVertex ( VertexCache.indicesRun + 0 );\r
face[1] = VertexCache_getVertex ( VertexCache.indicesRun + 1 );\r
face[2] = VertexCache_getVertex ( VertexCache.indicesRun + 2 );\r
face[0] = face[1] = face[2] = VertexCache_getVertex(VertexCache.indicesRun + 0);\r
break;\r
}\r
-\r
- VertexCache.indicesRun += VertexCache.primitivePitch;\r
+ face[3] = face[0]; // quad unsupported\r
+ VertexCache.indicesRun += VertexCache.indicesPitch;\r
}\r
\r
-/*!\r
-*/\r
-REALINLINE void CBurningVideoDriver::VertexCache_getbypass ( s4DVertex ** face )\r
-{\r
- const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );\r
-\r
- if ( VertexCache.iType == 1 )\r
- {\r
- const u16 *p = (const u16 *) VertexCache.indices;\r
- VertexCache_fill ( p[ i0 ], 0 );\r
- VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 );\r
- VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 );\r
- }\r
- else\r
- {\r
- const u32 *p = (const u32 *) VertexCache.indices;\r
- VertexCache_fill ( p[ i0 ], 0 );\r
- VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 );\r
- VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 );\r
- }\r
-\r
- VertexCache.indicesRun += VertexCache.primitivePitch;\r
-\r
- face[0] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );\r
- face[1] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );\r
- face[2] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) );\r
-\r
-}\r
\r
/*!\r
*/\r
-void CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCount,\r
+int CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCount,\r
const void* indices, u32 primitiveCount,\r
E_VERTEX_TYPE vType,\r
scene::E_PRIMITIVE_TYPE pType,\r
E_INDEX_TYPE iType)\r
{\r
+\r
+ // These calls would lead to crashes due to wrong index usage.\r
+ // The vertex cache needs to be rewritten for these primitives.\r
+ if (0 == CurrentShader ||\r
+ pType == scene::EPT_POINTS || pType == scene::EPT_LINE_STRIP ||\r
+ pType == scene::EPT_LINE_LOOP || pType == scene::EPT_LINES ||\r
+ pType == scene::EPT_POLYGON ||\r
+ pType == scene::EPT_POINT_SPRITES)\r
+ {\r
+ return 1;\r
+ }\r
+\r
VertexCache.vertices = vertices;\r
VertexCache.vertexCount = vertexCount;\r
\r
+ switch (Material.org.MaterialType) // (Material.Fallback_MaterialType)\r
+ {\r
+ case EMT_REFLECTION_2_LAYER:\r
+ case EMT_TRANSPARENT_REFLECTION_2_LAYER:\r
+ VertexCache.vType = E4VT_REFLECTION_MAP;\r
+ break;\r
+ default:\r
+ VertexCache.vType = (e4DVertexType)vType;\r
+ break;\r
+ }\r
+\r
+ //check material\r
+ SVSize* vSize = VertexCache.vSize;\r
+ for (int m = (int)vSize[VertexCache.vType].TexSize-1; m >= 0 ; --m)\r
+ {\r
+ ITexture* tex = MAT_TEXTURE(m);\r
+ if (!tex)\r
+ {\r
+ vSize[E4VT_NO_TEXTURE] = vSize[VertexCache.vType];\r
+ vSize[E4VT_NO_TEXTURE].TexSize = m;\r
+ vSize[E4VT_NO_TEXTURE].TexCooSize = m;\r
+ VertexCache.vType = E4VT_NO_TEXTURE;\r
+ //flags downconvert?\r
+ }\r
+ }\r
+\r
VertexCache.indices = indices;\r
VertexCache.indicesIndex = 0;\r
VertexCache.indicesRun = 0;\r
\r
- if ( Material.org.MaterialType == video::EMT_REFLECTION_2_LAYER )\r
- VertexCache.vType = 3;\r
- else\r
- VertexCache.vType = vType;\r
- VertexCache.pType = pType;\r
-\r
switch ( iType )\r
{\r
- case EIT_16BIT: VertexCache.iType = 1; break;\r
- case EIT_32BIT: VertexCache.iType = 2; break;\r
+ case EIT_16BIT: VertexCache.iType = E4IT_16BIT; break;\r
+ case EIT_32BIT: VertexCache.iType = E4IT_32BIT; break;\r
default:\r
- VertexCache.iType = iType; break;\r
+ VertexCache.iType = (e4DIndexType)iType; break;\r
}\r
+ if (!VertexCache.indices)\r
+ VertexCache.iType = E4IT_NONE;\r
\r
+ VertexCache.pType = pType;\r
+ VertexCache.primitiveHasVertex = 3;\r
+ VertexCache.indicesPitch = 1;\r
switch ( VertexCache.pType )\r
{\r
// most types here will not work as expected, only triangles/triangle_fan\r
// is known to work.\r
case scene::EPT_POINTS:\r
VertexCache.indexCount = primitiveCount;\r
- VertexCache.primitivePitch = 1;\r
+ VertexCache.indicesPitch = 1;\r
+ VertexCache.primitiveHasVertex = 1;\r
break;\r
case scene::EPT_LINE_STRIP:\r
VertexCache.indexCount = primitiveCount+1;\r
- VertexCache.primitivePitch = 1;\r
+ VertexCache.indicesPitch = 1;\r
+ VertexCache.primitiveHasVertex = 2;\r
break;\r
case scene::EPT_LINE_LOOP:\r
VertexCache.indexCount = primitiveCount+1;\r
- VertexCache.primitivePitch = 1;\r
+ VertexCache.indicesPitch = 1;\r
+ VertexCache.primitiveHasVertex = 2;\r
break;\r
case scene::EPT_LINES:\r
VertexCache.indexCount = 2*primitiveCount;\r
- VertexCache.primitivePitch = 2;\r
+ VertexCache.indicesPitch = 2;\r
+ VertexCache.primitiveHasVertex = 2;\r
break;\r
case scene::EPT_TRIANGLE_STRIP:\r
VertexCache.indexCount = primitiveCount+2;\r
- VertexCache.primitivePitch = 1;\r
+ VertexCache.indicesPitch = 1;\r
+ VertexCache.primitiveHasVertex = 3;\r
break;\r
case scene::EPT_TRIANGLES:\r
VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount;\r
- VertexCache.primitivePitch = 3;\r
+ VertexCache.indicesPitch = 3;\r
+ VertexCache.primitiveHasVertex = 3;\r
break;\r
case scene::EPT_TRIANGLE_FAN:\r
VertexCache.indexCount = primitiveCount + 2;\r
- VertexCache.primitivePitch = 1;\r
+ VertexCache.indicesPitch = 1;\r
+ VertexCache.primitiveHasVertex = 3;\r
break;\r
case scene::EPT_QUAD_STRIP:\r
VertexCache.indexCount = 2*primitiveCount + 2;\r
- VertexCache.primitivePitch = 2;\r
+ VertexCache.indicesPitch = 2;\r
+ VertexCache.primitiveHasVertex = 4;\r
break;\r
case scene::EPT_QUADS:\r
VertexCache.indexCount = 4*primitiveCount;\r
- VertexCache.primitivePitch = 4;\r
+ VertexCache.indicesPitch = 4;\r
+ VertexCache.primitiveHasVertex = 4;\r
break;\r
case scene::EPT_POLYGON:\r
VertexCache.indexCount = primitiveCount+1;\r
- VertexCache.primitivePitch = 1;\r
+ VertexCache.indicesPitch = 1;\r
+ VertexCache.primitiveHasVertex = primitiveCount;\r
break;\r
case scene::EPT_POINT_SPRITES:\r
VertexCache.indexCount = primitiveCount;\r
- VertexCache.primitivePitch = 1;\r
+ VertexCache.indicesPitch = 1;\r
+ VertexCache.primitiveHasVertex = 1;\r
break;\r
}\r
\r
- irr::memset32 ( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) );\r
+ //memset( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) );\r
+ for (size_t i = 0; i != VERTEXCACHE_ELEMENT; ++i)\r
+ {\r
+ VertexCache.info[i].hit = VERTEXCACHE_MISS;\r
+ VertexCache.info[i].index = VERTEXCACHE_MISS;\r
+ }\r
+ return 0;\r
}\r
\r
\r
+//! draws a vertex primitive list\r
void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,\r
const void* indexList, u32 primitiveCount,\r
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)\r
\r
CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);\r
\r
- // These calls would lead to crashes due to wrong index usage.\r
- // The vertex cache needs to be rewritten for these primitives.\r
- if (pType==scene::EPT_POINTS || pType==scene::EPT_LINE_STRIP ||\r
- pType==scene::EPT_LINE_LOOP || pType==scene::EPT_LINES ||\r
- pType==scene::EPT_POLYGON ||\r
- pType==scene::EPT_POINT_SPRITES)\r
+ if (VertexCache_reset(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType))\r
return;\r
\r
- if ( 0 == CurrentShader )\r
- return;\r
+ if ((u32)Material.org.MaterialType < MaterialRenderers.size())\r
+ {\r
+ MaterialRenderers[Material.org.MaterialType].Renderer->OnRender(this, vType);\r
+ }\r
+\r
+ //Matrices needed for this primitive\r
+ transform_calc(ETS_PROJ_MODEL_VIEW);\r
+ if ( Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM | TL_FOG)) )\r
+ {\r
+ transform_calc(ETS_MODEL_VIEW);\r
+ transform_calc(ETS_NORMAL);\r
+ }\r
\r
- VertexCache_reset ( vertices, vertexCount, indexList, primitiveCount, vType, pType, iType );\r
\r
- const s4DVertex * face[3];\r
+ s4DVertexPair* face[4];\r
\r
- f32 dc_area;\r
- s32 lodLevel;\r
- u32 i;\r
- u32 g;\r
- u32 m;\r
- video::CSoftwareTexture2* tex;\r
+ size_t vOut;\r
+ size_t vertex_from_clipper; // from VertexCache or CurrentOut\r
+ size_t has_vertex_run;\r
\r
- for ( i = 0; i < (u32) primitiveCount; ++i )\r
+ for ( size_t primitive_run = 0; primitive_run < primitiveCount; ++primitive_run)\r
{\r
+ //collect pointer to face vertices\r
VertexCache_get(face);\r
\r
- // if fully outside or outside on same side\r
- if ( ( (face[0]->flag | face[1]->flag | face[2]->flag) & VERTEX4D_CLIPMASK )\r
- != VERTEX4D_INSIDE\r
- )\r
- continue;\r
+ register size_t clipMask_i;\r
+ register size_t clipMask_o;\r
\r
- // if fully inside\r
- if ( ( face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE )\r
- {\r
- dc_area = screenarea2 ( face );\r
- if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0( dc_area ) )\r
- continue;\r
- else\r
- if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) )\r
- continue;\r
+ clipMask_i = face[0]->flag;\r
+ clipMask_o = face[0]->flag;\r
\r
- // select mipmap\r
- dc_area = core::reciprocal ( dc_area );\r
- for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m )\r
- {\r
- if ( 0 == (tex = MAT_TEXTURE ( m )) )\r
- {\r
- CurrentShader->setTextureParam(m, 0, 0);\r
- continue;\r
- }\r
+ for (has_vertex_run = 1; has_vertex_run < VertexCache.primitiveHasVertex; ++has_vertex_run)\r
+ {\r
+ clipMask_i |= face[has_vertex_run]->flag; // if fully outside or outside on same side\r
+ clipMask_o &= face[has_vertex_run]->flag; // if fully inside\r
+ }\r
\r
- lodLevel = s32_log2_f32 ( texelarea2 ( face, m ) * dc_area );\r
- CurrentShader->setTextureParam(m, tex, lodLevel );\r
- select_polygon_mipmap2 ( (s4DVertex**) face, m, tex->getSize() );\r
- }\r
+ clipMask_i &= VERTEX4D_CLIPMASK;\r
+ clipMask_o &= VERTEX4D_CLIPMASK;\r
\r
- // rasterize\r
- CurrentShader->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 );\r
+ if (clipMask_i != VERTEX4D_INSIDE )\r
+ {\r
+ // if primitive fully outside or outside on same side\r
continue;\r
+ vOut = 0;\r
+ vertex_from_clipper = 0;\r
}\r
+ else if (clipMask_o == VERTEX4D_INSIDE )\r
+ {\r
+ // if primitive fully inside\r
+ vOut = VertexCache.primitiveHasVertex;\r
+ vertex_from_clipper = 0;\r
+ }\r
+ else\r
+#if defined(SOFTWARE_DRIVER_2_CLIPPING)\r
+ {\r
+ // else if not complete inside clipping necessary\r
+ // check: clipping should reuse vertexcache (try to minimize clipping)\r
+ for (has_vertex_run = 0; has_vertex_run < VertexCache.primitiveHasVertex; ++has_vertex_run)\r
+ {\r
+ memcpy_s4DVertexPair(Clipper.data + s4DVertex_ofs(has_vertex_run), face[has_vertex_run]);\r
+ }\r
\r
- // else if not complete inside clipping necessary\r
- irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[0], SIZEOF_SVERTEX * 2 );\r
- irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[1], SIZEOF_SVERTEX * 2 );\r
- irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[2], SIZEOF_SVERTEX * 2 );\r
-\r
- const u32 flag = CurrentOut.data->flag & VERTEX4D_FORMAT_MASK;\r
+ vOut = clipToFrustum(VertexCache.primitiveHasVertex);\r
+ vertex_from_clipper = 1;\r
\r
- for ( g = 0; g != CurrentOut.ElementSize; ++g )\r
+ // to DC Space, project homogenous vertex\r
+ ndc_2_dc_and_project(Clipper.data + s4DVertex_proj(0), Clipper.data, s4DVertex_ofs(vOut));\r
+ }\r
+#else\r
{\r
- CurrentOut.data[g].flag = flag;\r
- Temp.data[g].flag = flag;\r
+ continue;\r
+ vOut = 0;\r
+ vertex_from_clipper = 0;\r
}\r
+#endif\r
+ // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )\r
+ for (has_vertex_run = 0; (has_vertex_run + VertexCache.primitiveHasVertex) <= vOut; has_vertex_run += 1)\r
+ {\r
+ // set from clipped geometry\r
+ if (vertex_from_clipper)\r
+ {\r
+ face[0] = Clipper.data + s4DVertex_ofs(0);\r
+ face[1] = Clipper.data + s4DVertex_ofs(has_vertex_run + 1);\r
+ face[2] = Clipper.data + s4DVertex_ofs(has_vertex_run + 2);\r
+ }\r
\r
- u32 vOut;\r
- vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 );\r
- if ( vOut < 3 )\r
- continue;\r
+ //area of primitive in device space\r
+ f32 dc_area = screenarea_inside(face);\r
\r
- vOut <<= 1;\r
+ //geometric clipping has problem with invisible or very small Triangles\r
+ //size_t sign = dc_area < 0.001f ? CULL_BACK : dc_area > 0.001f ? CULL_FRONT : CULL_INVISIBLE;\r
+ ieee754 t;\r
+ t.f = dc_area;\r
+ size_t sign = t.fields.sign ? CULL_BACK : CULL_FRONT;\r
+ sign |= t.abs.frac_exp < 981668463 /*0.01f*/ ? CULL_INVISIBLE : 0;\r
+ if (Material.CullFlag & sign)\r
+ break; //continue;\r
\r
- // to DC Space, project homogenous vertex\r
- ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );\r
+ //select mipmap ratio between drawing space and texture space\r
+ dc_area = reciprocal_zero(dc_area);\r
\r
- // check 2d backface culling on first\r
- dc_area = screenarea ( CurrentOut.data );\r
- if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) )\r
- continue;\r
- else if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) )\r
- continue;\r
-\r
- // select mipmap\r
- dc_area = core::reciprocal ( dc_area );\r
- for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m )\r
- {\r
- if ( 0 == (tex = MAT_TEXTURE ( m )) )\r
+ // select mipmap\r
+ for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m)\r
{\r
- CurrentShader->setTextureParam(m, 0, 0);\r
- continue;\r
- }\r
+ video::CSoftwareTexture2* tex = MAT_TEXTURE(m);\r
\r
- lodLevel = s32_log2_f32 ( texelarea ( CurrentOut.data, m ) * dc_area );\r
- CurrentShader->setTextureParam(m, tex, lodLevel );\r
- select_polygon_mipmap ( CurrentOut.data, vOut, m, tex->getSize() );\r
- }\r
+ //only guessing: take more detail (lower mipmap) in light+bump textures\r
+ //assume transparent add is ~50% transparent -> more detail\r
+ f32 lod_bias = Material.org.MaterialType == EMT_TRANSPARENT_ADD_COLOR ? 0.1f : 0.33f;\r
+ lod_bias *= tex->get_lod_bias();\r
+ s32 lodFactor = lodFactor_inside(face, m, dc_area, lod_bias);\r
\r
+ CurrentShader->setTextureParam(m, tex, lodFactor);\r
+ //currently shader receives texture coordinate as Pixelcoo of 1 Texture\r
+ select_polygon_mipmap_inside(face, m, tex->getTexBound());\r
+ }\r
\r
- // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )\r
- for ( g = 0; g <= vOut - 6; g += 2 )\r
- {\r
- // rasterize\r
- CurrentShader->drawTriangle ( CurrentOut.data + 0 + 1,\r
- CurrentOut.data + g + 3,\r
- CurrentOut.data + g + 5);\r
+ CurrentShader->drawWireFrameTriangle(face[0] + 1, face[1] + 1, face[2] + 1);\r
+ vertex_from_clipper = 1;\r
}\r
\r
}\r
\r
- // dump statistics\r
-/*\r
- char buf [64];\r
- sprintf ( buf,"VCount:%d PCount:%d CacheMiss: %d",\r
- vertexCount, primitiveCount,\r
- VertexCache.CacheMiss\r
- );\r
- os::Printer::log( buf );\r
-*/\r
+ //release texture\r
+ for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m)\r
+ {\r
+ CurrentShader->setTextureParam(m, 0, 0);\r
+ }\r
\r
}\r
\r
//! \param color: New color of the ambient light.\r
void CBurningVideoDriver::setAmbientLight(const SColorf& color)\r
{\r
- CNullDriver::setAmbientLight(color);\r
- LightSpace.Global_AmbientLight.setColorf ( color );\r
+ EyeSpace.Global_AmbientLight.setColorf ( color );\r
}\r
\r
\r
l.DiffuseColor.setColorf ( dl.DiffuseColor );\r
l.SpecularColor.setColorf ( dl.SpecularColor );\r
\r
+ //should always be valid?\r
+ sVec4 nDirection;\r
+ nDirection.x = dl.Direction.X;\r
+ nDirection.y = dl.Direction.Y;\r
+ nDirection.z = dl.Direction.Z;\r
+ nDirection.normalize_dir_xyz();\r
+\r
+\r
switch ( dl.Type )\r
{\r
- case video::ELT_DIRECTIONAL:\r
- l.pos.x = -dl.Direction.X;\r
- l.pos.y = -dl.Direction.Y;\r
- l.pos.z = -dl.Direction.Z;\r
- l.pos.w = 1.f;\r
+ case ELT_DIRECTIONAL:\r
+ l.pos.x = dl.Position.X;\r
+ l.pos.y = dl.Position.Y;\r
+ l.pos.z = dl.Position.Z;\r
+ l.pos.w = 0.f;\r
+\r
+ l.constantAttenuation = 1.f;\r
+ l.linearAttenuation = 0.f;\r
+ l.quadraticAttenuation = 0.f;\r
+\r
+ l.spotDirection.x = -nDirection.x;\r
+ l.spotDirection.y = -nDirection.y;\r
+ l.spotDirection.z = -nDirection.z;\r
+ l.spotDirection.w = 0.f;\r
+ l.spotCosCutoff = -1.f;\r
+ l.spotCosInnerCutoff = 1.f;\r
+ l.spotExponent = 0.f;\r
break;\r
+\r
case ELT_POINT:\r
- case ELT_SPOT:\r
- LightSpace.Flags |= POINTLIGHT;\r
l.pos.x = dl.Position.X;\r
l.pos.y = dl.Position.Y;\r
l.pos.z = dl.Position.Z;\r
l.pos.w = 1.f;\r
-/*\r
- l.radius = (1.f / dl.Attenuation.Y) * (1.f / dl.Attenuation.Y);\r
+\r
l.constantAttenuation = dl.Attenuation.X;\r
l.linearAttenuation = dl.Attenuation.Y;\r
l.quadraticAttenuation = dl.Attenuation.Z;\r
-*/\r
- l.radius = dl.Radius * dl.Radius;\r
+\r
+ l.spotDirection.x = -nDirection.x;\r
+ l.spotDirection.y = -nDirection.y;\r
+ l.spotDirection.z = -nDirection.z;\r
+ l.spotDirection.w = 0.f;\r
+ l.spotCosCutoff = -1.f;\r
+ l.spotCosInnerCutoff = 1.f;\r
+ l.spotExponent = 0.f;\r
+ break;\r
+\r
+ case ELT_SPOT:\r
+ l.pos.x = dl.Position.X;\r
+ l.pos.y = dl.Position.Y;\r
+ l.pos.z = dl.Position.Z;\r
+ l.pos.w = 1.f;\r
+\r
l.constantAttenuation = dl.Attenuation.X;\r
- l.linearAttenuation = 1.f / dl.Radius;\r
+ l.linearAttenuation = dl.Attenuation.Y;\r
l.quadraticAttenuation = dl.Attenuation.Z;\r
\r
+ l.spotDirection.x = nDirection.x;\r
+ l.spotDirection.y = nDirection.y;\r
+ l.spotDirection.z = nDirection.z;\r
+ l.spotDirection.w = 0.0f;\r
+ l.spotCosCutoff = cosf(dl.OuterCone * 2.0f * core::DEGTORAD * 0.5f);\r
+ l.spotCosInnerCutoff = cosf(dl.InnerCone * 2.0f * core::DEGTORAD * 0.5f);\r
+ l.spotExponent = dl.Falloff;\r
break;\r
default:\r
break;\r
}\r
\r
- LightSpace.Light.push_back ( l );\r
- return LightSpace.Light.size() - 1;\r
+ //which means ETS_VIEW\r
+ setTransform(ETS_WORLD,irr::core::IdentityMatrix);\r
+ transform_calc(ETS_MODEL_VIEW);\r
+\r
+ const core::matrix4* matrix = Transformation[TransformationStack];\r
+ transformVec4Vec4(matrix[ETS_MODEL_VIEW], &l.pos4.x, &l.pos.x );\r
+ rotateVec3Vec4(matrix[ETS_MODEL_VIEW], &l.spotDirection4.x, &l.spotDirection.x );\r
+\r
+ EyeSpace.Light.push_back ( l );\r
+ return EyeSpace.Light.size() - 1;\r
}\r
\r
+\r
//! Turns a dynamic light on or off\r
void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn)\r
{\r
- if(lightIndex > -1 && lightIndex < (s32)LightSpace.Light.size())\r
+ if((u32)lightIndex < EyeSpace.Light.size())\r
{\r
- LightSpace.Light[lightIndex].LightIsOn = turnOn;\r
+ EyeSpace.Light[lightIndex].LightIsOn = turnOn;\r
}\r
}\r
\r
//! deletes all dynamic lights there are\r
void CBurningVideoDriver::deleteAllDynamicLights()\r
{\r
- LightSpace.reset ();\r
+ EyeSpace.reset ();\r
CNullDriver::deleteAllDynamicLights();\r
\r
}\r
//! returns the maximal amount of dynamic lights the device can handle\r
u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const\r
{\r
- return 8;\r
+ return 8; //no limit 8 only for convenience\r
}\r
\r
\r
//! sets a material\r
void CBurningVideoDriver::setMaterial(const SMaterial& material)\r
{\r
+// ---------- Override\r
Material.org = material;\r
+ OverrideMaterial.apply(Material.org);\r
+\r
+ const SMaterial& in = Material.org;\r
+\r
+// ---------- Notify Shader\r
+ // unset old material\r
+ u32 mi;\r
+ mi = (u32)Material.lastMaterial.MaterialType;\r
+ if (mi != material.MaterialType && mi < MaterialRenderers.size())\r
+ MaterialRenderers[mi].Renderer->OnUnsetMaterial();\r
+\r
+ // set new material.\r
+ mi = (u32)in.MaterialType;\r
+ if (mi < MaterialRenderers.size())\r
+ MaterialRenderers[mi].Renderer->OnSetMaterial(\r
+ in, Material.lastMaterial, Material.resetRenderStates, this);\r
+\r
+ Material.lastMaterial = in;\r
+ Material.resetRenderStates = false;\r
+\r
+ //CSoftware2MaterialRenderer sets Material.Fallback_MaterialType\r
+\r
+ //Material.Fallback_MaterialType = material.MaterialType;\r
+\r
+//-----------------\r
+\r
+ //Material.org = material;\r
+ Material.CullFlag = CULL_INVISIBLE | (in.BackfaceCulling ? CULL_BACK : 0) | (in.FrontfaceCulling ? CULL_FRONT : 0);\r
+\r
+ size_t* flag = TransformationFlag[TransformationStack];\r
\r
#ifdef SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
- for (u32 i = 0; i < 2; ++i)\r
+ for (u32 m = 0; m < BURNING_MATERIAL_MAX_TEXTURES /*&& m < vSize[VertexCache.vType].TexSize*/; ++m)\r
{\r
- setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + i),\r
- material.getTextureMatrix(i));\r
+ setTransform((E_TRANSFORMATION_STATE) (ETS_TEXTURE_0 + m),in.getTextureMatrix(m));\r
+ flag[ETS_TEXTURE_0+m] &= ~ETF_TEXGEN_MASK;\r
}\r
#endif\r
\r
#ifdef SOFTWARE_DRIVER_2_LIGHTING\r
- Material.AmbientColor.setR8G8B8 ( Material.org.AmbientColor.color );\r
- Material.DiffuseColor.setR8G8B8 ( Material.org.DiffuseColor.color );\r
- Material.EmissiveColor.setR8G8B8 ( Material.org.EmissiveColor.color );\r
- Material.SpecularColor.setR8G8B8 ( Material.org.SpecularColor.color );\r
\r
- core::setbit_cond ( LightSpace.Flags, Material.org.Shininess != 0.f, SPECULAR );\r
- core::setbit_cond ( LightSpace.Flags, Material.org.FogEnable, FOG );\r
- core::setbit_cond ( LightSpace.Flags, Material.org.NormalizeNormals, NORMALIZE );\r
+ Material.AmbientColor.setA8R8G8B8( in.AmbientColor.color );\r
+ Material.DiffuseColor.setA8R8G8B8( in.ColorMaterial ? 0xFFFFFFFF : in.DiffuseColor.color );\r
+ Material.EmissiveColor.setA8R8G8B8(in.EmissiveColor.color );\r
+ Material.SpecularColor.setA8R8G8B8( in.SpecularColor.color );\r
+\r
+ burning_setbit(EyeSpace.TL_Flag, in.Lighting, TL_LIGHT);\r
+ burning_setbit( EyeSpace.TL_Flag, (in.Shininess != 0.f) & (in.SpecularColor.color & 0x00ffffff), TL_SPECULAR );\r
+ burning_setbit( EyeSpace.TL_Flag, in.FogEnable, TL_FOG );\r
+ burning_setbit( EyeSpace.TL_Flag, in.NormalizeNormals, TL_NORMALIZE_NORMALS );\r
+ //if (EyeSpace.Flags & SPECULAR ) EyeSpace.Flags |= NORMALIZE_NORMALS;\r
+\r
#endif\r
\r
- setCurrentShader();\r
+ //--------------- setCurrentShader\r
+\r
+ ITexture* texture0 = in.getTexture(0);\r
+ ITexture* texture1 = in.getTexture(1);\r
+ //ITexture* texture2 = in.getTexture(2);\r
+ //ITexture* texture3 = in.getTexture(3);\r
+\r
+ //visual studio code analysis\r
+ u32 maxTex = BURNING_MATERIAL_MAX_TEXTURES;\r
+ if (maxTex < 1) texture0 = 0;\r
+ if (maxTex < 2) texture1 = 0;\r
+ //if (maxTex < 3) texture2 = 0;\r
+ //if (maxTex < 4) texture3 = 0;\r
+\r
+ EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP);\r
+\r
+ //todo: seperate depth test from depth write\r
+ Material.depth_write = getWriteZBuffer(in);\r
+ Material.depth_test = in.ZBuffer != ECFN_DISABLED && Material.depth_write;\r
+\r
+ EBurningFFShader shader = Material.depth_test ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ;\r
+\r
+ switch (Material.Fallback_MaterialType) //(Material.org.MaterialType)\r
+ {\r
+ case EMT_ONETEXTURE_BLEND:\r
+ shader = ETR_TEXTURE_BLEND;\r
+ break;\r
+\r
+ case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:\r
+ Material.org.MaterialTypeParam = 0.5f;\r
+ //fallthrough\r
+\r
+ case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
+ if (texture0 && texture0->hasAlpha())\r
+ {\r
+ shader = Material.depth_test ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ;\r
+ }\r
+ else\r
+ {\r
+ //fall back to EMT_TRANSPARENT_VERTEX_ALPHA\r
+ shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;\r
+ }\r
+ break;\r
+\r
+ case EMT_TRANSPARENT_ADD_COLOR:\r
+ shader = Material.depth_test ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z;\r
+ break;\r
+\r
+ case EMT_TRANSPARENT_VERTEX_ALPHA:\r
+ shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;\r
+ break;\r
+\r
+ case EMT_LIGHTMAP:\r
+ case EMT_LIGHTMAP_LIGHTING:\r
+ if (texture1)\r
+ shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;\r
+ break;\r
+\r
+ case EMT_LIGHTMAP_M2:\r
+ case EMT_LIGHTMAP_LIGHTING_M2:\r
+ if (texture1)\r
+ shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2;\r
+ break;\r
+\r
+ case EMT_LIGHTMAP_LIGHTING_M4:\r
+ if (texture1)\r
+ shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4;\r
+ break;\r
+ case EMT_LIGHTMAP_M4:\r
+ if (texture1)\r
+ shader = ETR_TEXTURE_LIGHTMAP_M4;\r
+ break;\r
+\r
+ case EMT_LIGHTMAP_ADD:\r
+ if (texture1)\r
+ shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD;\r
+ break;\r
+\r
+ case EMT_DETAIL_MAP:\r
+ if (texture1)\r
+ shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP;\r
+ break;\r
+\r
+ case EMT_SPHERE_MAP:\r
+ flag[ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_SPHERE;\r
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;\r
+ break;\r
+ case EMT_REFLECTION_2_LAYER:\r
+ case EMT_TRANSPARENT_REFLECTION_2_LAYER:\r
+ if (texture1)\r
+ {\r
+ shader = ETR_TRANSPARENT_REFLECTION_2_LAYER;\r
+ flag[ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION;\r
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;\r
+ }\r
+ break;\r
+\r
+ case EMT_NORMAL_MAP_SOLID:\r
+ case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:\r
+ case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:\r
+ if (texture1)\r
+ {\r
+ shader = ETR_NORMAL_MAP_SOLID;\r
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP;\r
+ }\r
+ break;\r
+ case EMT_PARALLAX_MAP_SOLID:\r
+ case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:\r
+ case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:\r
+ if (texture1)\r
+ {\r
+ shader = ETR_NORMAL_MAP_SOLID;\r
+ EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP;\r
+ }\r
+ break;\r
+\r
+ default:\r
+ break;\r
+\r
+ }\r
+\r
+ if (!texture0)\r
+ {\r
+ shader = Material.depth_test ? ETR_GOURAUD :\r
+ shader == ETR_TEXTURE_GOURAUD_VERTEX_ALPHA ?\r
+ ETR_GOURAUD_ALPHA_NOZ: // 2D Gradient\r
+ ETR_GOURAUD_NOZ;\r
+\r
+ shader = ETR_COLOR;\r
+ }\r
+\r
+ if (in.Wireframe)\r
+ {\r
+ IBurningShader* candidate = BurningShader[shader];\r
+ if (!candidate || (candidate && !candidate->canWireFrame()))\r
+ {\r
+ shader = ETR_TEXTURE_GOURAUD_WIRE;\r
+ }\r
+ }\r
+\r
+ if (in.PointCloud)\r
+ {\r
+ IBurningShader* candidate = BurningShader[shader];\r
+ if (!candidate || (candidate && !candidate->canPointCloud()))\r
+ {\r
+ shader = ETR_TEXTURE_GOURAUD_WIRE;\r
+ }\r
+ }\r
+\r
+ //shader = ETR_REFERENCE;\r
+\r
+ // switchToTriangleRenderer\r
+ CurrentShader = BurningShader[shader];\r
+ if (CurrentShader)\r
+ {\r
+ CurrentShader->setTLFlag(EyeSpace.TL_Flag);\r
+ if (EyeSpace.TL_Flag & TL_FOG) CurrentShader->setFog(FogColor);\r
+ if (EyeSpace.TL_Flag & TL_SCISSOR) CurrentShader->setScissor(Scissor);\r
+ CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);\r
+ CurrentShader->OnSetMaterial(Material);\r
+ CurrentShader->pushEdgeTest(in.Wireframe, in.PointCloud, 0);\r
+ }\r
+\r
+\r
+/*\r
+ mi = (u32)Material.org.MaterialType;\r
+ if (mi < MaterialRenderers.size())\r
+ MaterialRenderers[mi].Renderer->OnRender(this, (video::E_VERTEX_TYPE)VertexCache.vType);\r
+*/\r
+}\r
+\r
+\r
+//! Sets the fog mode.\r
+void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start,\r
+ f32 end, f32 density, bool pixelFog, bool rangeFog)\r
+{\r
+ CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog);\r
+\r
+ EyeSpace.fog_scale = reciprocal_zero2(FogEnd - FogStart);\r
}\r
\r
\r
+\r
+#if defined(SOFTWARE_DRIVER_2_LIGHTING) && BURNING_MATERIAL_MAX_COLORS > 0\r
+\r
+\r
/*!\r
- Camera Position in World Space\r
+ applies lighting model\r
*/\r
-void CBurningVideoDriver::getCameraPosWorldSpace ()\r
+void CBurningVideoDriver::lightVertex_eye(s4DVertex *dest, u32 vertexargb)\r
{\r
- Transformation[ETS_VIEW_INVERSE] = Transformation[ ETS_VIEW ];\r
- Transformation[ETS_VIEW_INVERSE].makeInverse ();\r
- TransformationFlag[ETS_VIEW_INVERSE] = 0;\r
+ //gl_FrontLightModelProduct.sceneColor = gl_FrontMaterial.emission + gl_FrontMaterial.ambient * gl_LightModel.ambient\r
\r
- const f32 *M = Transformation[ETS_VIEW_INVERSE].pointer ();\r
+ sVec3Color ambient;\r
+ sVec3Color diffuse;\r
+ sVec3Color specular;\r
\r
- /* The viewpoint is at (0., 0., 0.) in eye space.\r
- Turning this into a vector [0 0 0 1] and multiply it by\r
- the inverse of the view matrix, the resulting vector is the\r
- object space location of the camera.\r
- */\r
\r
- LightSpace.campos.x = M[12];\r
- LightSpace.campos.y = M[13];\r
- LightSpace.campos.z = M[14];\r
- LightSpace.campos.w = 1.f;\r
+ // the universe started in darkness..\r
+ ambient = EyeSpace.Global_AmbientLight;\r
+ diffuse.set(0.f);\r
+ specular.set(0.f);\r
+\r
+\r
+ u32 i;\r
+ f32 dot;\r
+ f32 distance;\r
+ f32 attenuation;\r
+ sVec4 vp; // unit vector vertex to light\r
+ sVec4 lightHalf; // blinn-phong reflection\r
+\r
+ f32 spotDot; // cos of angle between spotlight and point on surface\r
+\r
+ for (i = 0; i < EyeSpace.Light.size(); ++i)\r
+ {\r
+ const SBurningShaderLight& light = EyeSpace.Light[i];\r
+ if (!light.LightIsOn)\r
+ continue;\r
+\r
+ switch (light.Type)\r
+ {\r
+ case ELT_DIRECTIONAL:\r
+\r
+ //angle between normal and light vector\r
+ dot = EyeSpace.normal.dot_xyz(light.spotDirection4);\r
+\r
+ // accumulate ambient\r
+ ambient.add_rgb(light.AmbientColor);\r
+\r
+ // diffuse component\r
+ if (dot > 0.f)\r
+ diffuse.mad_rgb(light.DiffuseColor, dot);\r
+ break;\r
+\r
+ case ELT_POINT:\r
+ // surface to light\r
+ vp.x = light.pos4.x - EyeSpace.vertex.x;\r
+ vp.y = light.pos4.y - EyeSpace.vertex.y;\r
+ vp.z = light.pos4.z - EyeSpace.vertex.z;\r
+\r
+ distance = vp.length_xyz();\r
+\r
+ attenuation = light.constantAttenuation\r
+ + light.linearAttenuation * distance\r
+ + light.quadraticAttenuation * (distance * distance);\r
+ attenuation = reciprocal_one(attenuation);\r
+\r
+ //att = clamp(1.0 - dist/radius, 0.0, 1.0); att *= att\r
+\r
+ // accumulate ambient\r
+ ambient.mad_rgb(light.AmbientColor, attenuation);\r
+\r
+ // build diffuse reflection\r
+\r
+ //angle between normal and light vector\r
+ vp.mul_xyz(reciprocal_zero(distance)); //normalize\r
+ dot = EyeSpace.normal.dot_xyz(vp);\r
+ if (dot <= 0.f) continue;\r
+\r
+ // diffuse component\r
+ diffuse.mad_rgb(light.DiffuseColor, dot * attenuation);\r
+\r
+ if (!(EyeSpace.TL_Flag & TL_SPECULAR))\r
+ continue;\r
+\r
+ lightHalf.x = vp.x + 0.f; // EyeSpace.cam_eye_pos.x;\r
+ lightHalf.y = vp.y + 0.f; // EyeSpace.cam_eye_pos.y;\r
+ lightHalf.z = vp.z - 1.f; // EyeSpace.cam_eye_pos.z;\r
+ lightHalf.normalize_dir_xyz();\r
+\r
+ //specular += light.SpecularColor * pow(max(dot(Eyespace.normal,lighthalf),0,Material.org.Shininess)*attenuation\r
+ specular.mad_rgb(light.SpecularColor,\r
+ powf_limit(EyeSpace.normal.dot_xyz(lightHalf), Material.org.Shininess)*attenuation\r
+ );\r
+ break;\r
+\r
+ case ELT_SPOT:\r
+ // surface to light\r
+ vp.x = light.pos4.x - EyeSpace.vertex.x;\r
+ vp.y = light.pos4.y - EyeSpace.vertex.y;\r
+ vp.z = light.pos4.z - EyeSpace.vertex.z;\r
+\r
+ distance = vp.length_xyz();\r
+\r
+ //normalize\r
+ vp.mul_xyz(reciprocal_zero(distance));\r
+\r
+ // point on surface inside cone of illumination\r
+ spotDot = vp.dot_minus_xyz(light.spotDirection4);\r
+ if (spotDot < light.spotCosCutoff)\r
+ continue;\r
+\r
+ attenuation = light.constantAttenuation\r
+ + light.linearAttenuation * distance\r
+ + light.quadraticAttenuation * distance * distance;\r
+ attenuation = reciprocal_one(attenuation);\r
+ attenuation *= powf_limit(spotDot, light.spotExponent);\r
+\r
+ // accumulate ambient\r
+ ambient.mad_rgb(light.AmbientColor, attenuation);\r
+\r
+\r
+ // build diffuse reflection\r
+ //angle between normal and light vector\r
+ dot = EyeSpace.normal.dot_xyz(vp);\r
+ if (dot < 0.f) continue;\r
+\r
+ // diffuse component\r
+ diffuse.mad_rgb(light.DiffuseColor, dot * attenuation);\r
+\r
+ if (!(EyeSpace.TL_Flag & TL_SPECULAR))\r
+ continue;\r
+\r
+ lightHalf.x = vp.x + 0.f; // EyeSpace.cam_eye_pos.x;\r
+ lightHalf.y = vp.y + 0.f; // EyeSpace.cam_eye_pos.y;\r
+ lightHalf.z = vp.z - 1.f; // EyeSpace.cam_eye_pos.z;\r
+ lightHalf.normalize_dir_xyz();\r
+\r
+ //specular += light.SpecularColor * pow(max(dot(Eyespace.normal,lighthalf),0,Material.org.Shininess)*attenuation\r
+ specular.mad_rgb(light.SpecularColor,\r
+ powf_limit(EyeSpace.normal.dot_xyz(lightHalf), Material.org.Shininess)*attenuation\r
+ );\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+\r
+ }\r
+\r
+ // sum up lights\r
+ sVec3Color dColor;\r
+ dColor.set(0.f);\r
+ dColor.mad_rgbv(diffuse, Material.DiffuseColor);\r
+\r
+ //diffuse * vertex color.\r
+ //has to move to shader (for vertex color only this will fit [except clamping])\r
+\r
+ sVec3Color c;\r
+ c.setA8R8G8B8(vertexargb);\r
+ dColor.r *= c.r;\r
+ dColor.g *= c.g;\r
+ dColor.b *= c.b;\r
+\r
+ //separate specular\r
+#if defined(SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR)\r
+ if ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG))\r
+ {\r
+ specular.sat_xyz(dest->Color[1], Material.SpecularColor);\r
+ }\r
+ else\r
+ if ( !(EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) &&\r
+ (VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_MASK_LIGHT)\r
+ )\r
+ {\r
+ specular.sat_xyz(dest->LightTangent[0], Material.SpecularColor);\r
+ }\r
+ else\r
+#endif\r
+ {\r
+ dColor.mad_rgbv(specular, Material.SpecularColor);\r
+ }\r
+\r
+\r
+ dColor.mad_rgbv(ambient, Material.AmbientColor);\r
+ dColor.add_rgb(Material.EmissiveColor);\r
+\r
+\r
+ dColor.sat(dest->Color[0], vertexargb);\r
+\r
}\r
\r
-void CBurningVideoDriver::getLightPosObjectSpace ()\r
+#endif\r
+\r
+CImage* getImage(const video::ITexture* texture)\r
{\r
- if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY )\r
+ if (!texture) return 0;\r
+\r
+ CImage* img = 0;\r
+ switch (texture->getDriverType())\r
{\r
- Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD];\r
- TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY;\r
+ case EDT_BURNINGSVIDEO:\r
+ img = ((CSoftwareTexture2*)texture)->getImage();\r
+ break;\r
+ case EDT_SOFTWARE:\r
+ img = ((CSoftwareTexture*)texture)->getImage();\r
+ break;\r
+ default:\r
+ os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);\r
+ break;\r
+ }\r
+ return img;\r
+}\r
+\r
+/*\r
+ draw2DImage with single color scales into destination quad & cliprect(more like viewport)\r
+ draw2DImage with 4 color scales on destination and cliprect is scissor\r
+*/\r
+\r
+static const u16 quad_triangle_indexList[6] = { 0,1,2,0,2,3 };\r
+\r
+\r
+#if defined(SOFTWARE_DRIVER_2_2D_AS_2D)\r
+\r
+//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.\r
+void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,\r
+ const core::rect<s32>& sourceRect,\r
+ const core::rect<s32>* clipRect, SColor color,\r
+ bool useAlphaChannelOfTexture)\r
+{\r
+ if (texture)\r
+ {\r
+ if (texture->getOriginalSize() != texture->getSize())\r
+ {\r
+ core::rect<s32> destRect(destPos, sourceRect.getSize());\r
+ SColor c4[4] = { color,color,color,color };\r
+ draw2DImage(texture, destRect, sourceRect, clipRect, c4, useAlphaChannelOfTexture);\r
+ return;\r
+ }\r
+\r
+ if (texture->getDriverType() != EDT_BURNINGSVIDEO)\r
+ {\r
+ os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);\r
+ return;\r
+ }\r
+\r
+ if (useAlphaChannelOfTexture)\r
+ ((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha(\r
+ RenderTargetSurface, destPos, sourceRect, color, clipRect);\r
+ else\r
+ ((CSoftwareTexture2*)texture)->getImage()->copyTo(\r
+ RenderTargetSurface, destPos, sourceRect, clipRect);\r
+ }\r
+}\r
+\r
+\r
+//! Draws a part of the texture into the rectangle.\r
+void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,\r
+ const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,\r
+ const video::SColor* const colors, bool useAlphaChannelOfTexture)\r
+{\r
+ if (texture)\r
+ {\r
+ if (texture->getDriverType() != EDT_BURNINGSVIDEO)\r
+ {\r
+ os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);\r
+ return;\r
+ }\r
+\r
+ u32 argb = (colors ? colors[0].color : 0xFFFFFFFF);\r
+ eBlitter op = useAlphaChannelOfTexture ?\r
+ (argb == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND) : BLITTER_TEXTURE;\r
+\r
+ StretchBlit(op, RenderTargetSurface, clipRect, &destRect,\r
+ ((CSoftwareTexture2*)texture)->getImage(), &sourceRect, &texture->getOriginalSize(), argb);\r
+\r
+ }\r
+}\r
+\r
+//!Draws an 2d rectangle with a gradient.\r
+void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position,\r
+ SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,\r
+ const core::rect<s32>* clip)\r
+{\r
+ core::rect<s32> p(position);\r
+ if (clip) p.clipAgainst(*clip);\r
+ if (p.isValid()) drawRectangle(RenderTargetSurface, p, colorLeftUp);\r
+}\r
+\r
+#endif //defined(SOFTWARE_DRIVER_2_2D_AS_2D)\r
+\r
+\r
+\r
+\r
+\r
+#if 0\r
+void transform_for_BlitJob2D( SBlitJob& out,\r
+ const S3DVertex quad2DVertices[4], const core::dimension2d<u32>& renderTargetSize,\r
+ CBurningVideoDriver* driver\r
+)\r
+{\r
+ //assume. z = 0.f, w = 1.f\r
+ //MVP 2D\r
+ core::matrix4 m;\r
+ m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f);\r
+ m.setTranslation(core::vector3df(-1.f, 1.f, 0));\r
+\r
+ //setTransform(ETS_WORLD, m);\r
+ //m.setTranslation(core::vector3df(0.375f, 0.375f, 0.0f));\r
+ //setTransform(ETS_VIEW, m);\r
+\r
+ s4DVertexPair v[4*sizeof_s4DVertexPairRel];\r
+ for (int i = 0; i < 4; ++i)\r
+ {\r
+ m.transformVect(&v[s4DVertex_ofs(i)].Pos.x, quad2DVertices[i].Pos);\r
+ v[s4DVertex_ofs(i)].Tex[0].x = quad2DVertices[i].TCoords.X;\r
+ v[s4DVertex_ofs(i)].Tex[0].y = quad2DVertices[i].TCoords.Y;\r
+ v[s4DVertex_ofs(i)].Color[0].setA8R8G8B8(quad2DVertices[i].Color.color);\r
+ v[s4DVertex_ofs(i)].flag = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1;\r
+ v[s4DVertex_ofs(i)].flag |= clipToFrustumTest(v + i);\r
+ }\r
+\r
+ size_t vOut = driver->clipToFrustum(4);\r
+\r
+ struct s2DVertex\r
+ {\r
+ union\r
+ {\r
+ struct {\r
+ f32 x, y;\r
+ f32 u, v;\r
+ f32 a, r, g, b;\r
+ };\r
+ f32 attr[8];\r
+ };\r
+\r
+ // f = a * t + b * ( 1 - t )\r
+ void interpolate(const s2DVertex& b, const s2DVertex& a, const f32 t)\r
+ {\r
+ for (int i = 0; i < 8; ++i)\r
+ {\r
+ attr[i] = b.attr[i] + ((a.attr[i] - b.attr[i]) * t);\r
+ }\r
+ }\r
+\r
+ };\r
+\r
+ // 0 5\r
+ f32 m2[2];\r
+ m2[0] = renderTargetSize.Width ? 2.f / renderTargetSize.Width : 0.f;\r
+ m2[1] = renderTargetSize.Height ? -2.f / renderTargetSize.Height : 0.f;\r
+\r
+ s2DVertex p[4];\r
+ for (int i = 0; i < 4; ++i)\r
+ {\r
+ p[i].x = quad2DVertices[i].Pos.X*m2[0] - 1.f;\r
+ p[i].y = quad2DVertices[i].Pos.Y*m2[1] + 1.f;\r
+ p[i].u = quad2DVertices[i].TCoords.X;\r
+ p[i].v = quad2DVertices[i].TCoords.Y;\r
+\r
+ p[i].a = quad2DVertices[i].Color.getAlpha() * (1.f / 255.f);\r
+ p[i].r = quad2DVertices[i].Color.getRed() * (1.f / 255.f);\r
+ p[i].g = quad2DVertices[i].Color.getBlue() * (1.f / 255.f);\r
+ p[i].b = quad2DVertices[i].Color.getGreen() * (1.f / 255.f);\r
+\r
+ }\r
+\r
+}\r
+#endif\r
+\r
+\r
+//! Enable the 2d override material\r
+void CBurningVideoDriver::enableMaterial2D(bool enable)\r
+{\r
+ CNullDriver::enableMaterial2D(enable);\r
+ burning_setbit(TransformationFlag[1][ETS_PROJECTION], 0, ETF_VALID);\r
+}\r
+\r
+size_t compare_2d_material(const SMaterial& a, const SMaterial& b)\r
+{\r
+ size_t flag = 0;\r
+ flag |= a.MaterialType == b.MaterialType ? 0 : 1;\r
+ flag |= a.ZBuffer == b.ZBuffer ? 0 : 2;\r
+ flag |= a.TextureLayer[0].Texture == b.TextureLayer[0].Texture ? 0 : 4;\r
+ flag |= a.TextureLayer[0].BilinearFilter == b.TextureLayer[0].BilinearFilter ? 0 : 8;\r
+ flag |= a.MaterialTypeParam == b.MaterialTypeParam ? 0 : 16;\r
+ if (flag) return flag;\r
+\r
+ flag |= a.TextureLayer[1].Texture == b.TextureLayer[1].Texture ? 0 : 32;\r
+ flag |= a.ZWriteEnable == b.ZWriteEnable ? 0 : 64;\r
+\r
+ return flag;\r
+}\r
+\r
+void CBurningVideoDriver::setRenderStates2DMode(const video::SColor& color, video::ITexture* texture, bool useAlphaChannelOfTexture)\r
+{\r
+ //save current 3D Material\r
+ //Material.save3D = Material.org;\r
+\r
+ //build new 2D Material\r
+\r
+ bool vertexAlpha = color.getAlpha() < 255;\r
+\r
+ //2D uses textureAlpa*vertexAlpha 3D not..\r
+ if (useAlphaChannelOfTexture && texture && texture->hasAlpha())\r
+ {\r
+ Material.mat2D.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;\r
+ }\r
+ else if (vertexAlpha)\r
+ {\r
+ Material.mat2D.MaterialType = EMT_TRANSPARENT_VERTEX_ALPHA;\r
}\r
else\r
{\r
- Transformation[ETS_WORLD].getInverse ( Transformation[ETS_WORLD_INVERSE] );\r
- TransformationFlag[ETS_WORLD_INVERSE] &= ~ETF_IDENTITY;\r
+ Material.mat2D.MaterialType = EMT_SOLID;\r
}\r
\r
- for ( u32 i = 0; i < 1 && i < LightSpace.Light.size(); ++i )\r
+ Material.mat2D.ZBuffer = ECFN_DISABLED;\r
+ Material.mat2D.ZWriteEnable = EZW_OFF;\r
+ Material.mat2D.Lighting = false;\r
+\r
+ Material.mat2D.setTexture(0, (video::ITexture*)texture);\r
+\r
+ //used for text. so stay as sharp as possible (like HW Driver)\r
+ bool mip = false;\r
+\r
+ const SMaterial& currentMaterial = (!OverrideMaterial2DEnabled) ? InitMaterial2D : OverrideMaterial2D;\r
+ mip = currentMaterial.TextureLayer[0].BilinearFilter;\r
+\r
+ Material.mat2D.setFlag(video::EMF_BILINEAR_FILTER, mip);\r
+\r
+\r
+ //switch to 2D Matrix Stack [ Material set Texture Matrix ]\r
+ TransformationStack = 1;\r
+\r
+ //2D GUI Matrix\r
+ if (!(TransformationFlag[TransformationStack][ETS_PROJECTION] & ETF_VALID))\r
{\r
- SBurningShaderLight &l = LightSpace.Light[i];\r
+ const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();\r
+ core::matrix4 m(core::matrix4::EM4CONST_NOTHING);\r
+ m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f);\r
+ m.setTranslation(core::vector3df(-1.f, 1.f, 0));\r
+ setTransform(ETS_PROJECTION, m);\r
+\r
+ m.makeIdentity();\r
+ setTransform(ETS_WORLD, m);\r
+\r
+ if ( mip ) m.setTranslation(core::vector3df(0.375f, 0.375f, 0.0f));\r
\r
- Transformation[ETS_WORLD_INVERSE].transformVec3 ( &l.pos_objectspace.x, &l.pos.x );\r
+ setTransform(ETS_VIEW, m);\r
+\r
+ buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[TransformationStack], ViewPort, mip ? -0.187f : 0.f);\r
+\r
+ }\r
+\r
+ //compare\r
+ if (compare_2d_material(Material.org,Material.mat2D))\r
+ {\r
+ setMaterial(Material.mat2D);\r
+ }\r
+ if (CurrentShader)\r
+ {\r
+ CurrentShader->setPrimitiveColor(color.color);\r
}\r
+\r
}\r
\r
+void CBurningVideoDriver::setRenderStates3DMode()\r
+{\r
+ //restoreRenderStates3DMode\r
\r
-#ifdef SOFTWARE_DRIVER_2_LIGHTING\r
+ //setMaterial(Material.save3D);\r
+ //switch to 3D Matrix Stack\r
+ TransformationStack = 0;\r
+}\r
\r
-//! Sets the fog mode.\r
-void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start,\r
- f32 end, f32 density, bool pixelFog, bool rangeFog)\r
+//! draws a vertex primitive list in 2d\r
+void CBurningVideoDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,\r
+ const void* indexList, u32 primitiveCount,\r
+ E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)\r
{\r
- CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog);\r
- LightSpace.FogColor.setA8R8G8B8 ( color.color );\r
+ if (!checkPrimitiveCount(primitiveCount))\r
+ return;\r
+\r
+ CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);\r
+\r
+ bool useAlphaChannelOfTexture = false;\r
+ video::SColor color(0xFFFFFFFF);\r
+ switch (Material.org.MaterialType)\r
+ {\r
+ case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
+ useAlphaChannelOfTexture = true;\r
+ break;\r
+ case EMT_TRANSPARENT_VERTEX_ALPHA:\r
+ color.setAlpha(127);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ setRenderStates2DMode(color, Material.org.getTexture(0), useAlphaChannelOfTexture);\r
+\r
+ drawVertexPrimitiveList(vertices, vertexCount,\r
+ indexList, primitiveCount,\r
+ vType, pType, iType);\r
+\r
+ setRenderStates3DMode();\r
+\r
}\r
\r
-/*!\r
- applies lighting model\r
-*/\r
-void CBurningVideoDriver::lightVertex ( s4DVertex *dest, u32 vertexargb )\r
+//setup a quad\r
+#if defined(SOFTWARE_DRIVER_2_2D_AS_3D)\r
+\r
+//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.\r
+void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,\r
+ const core::rect<s32>& sourceRect,\r
+ const core::rect<s32>* clipRect, SColor color,\r
+ bool useAlphaChannelOfTexture)\r
{\r
- sVec3 dColor;\r
+ if (!texture)\r
+ return;\r
+\r
+ if (!sourceRect.isValid())\r
+ return;\r
+\r
+ // clip these coordinates\r
+ core::rect<s32> targetRect(destPos, sourceRect.getSize());\r
+ if (clipRect)\r
+ {\r
+ targetRect.clipAgainst(*clipRect);\r
+ if (targetRect.getWidth() < 0 || targetRect.getHeight() < 0)\r
+ return;\r
+ }\r
+\r
+ const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();\r
+ targetRect.clipAgainst(core::rect<s32>(0, 0, (s32)renderTargetSize.Width, (s32)renderTargetSize.Height));\r
+ if (targetRect.getWidth() < 0 || targetRect.getHeight() < 0)\r
+ return;\r
+\r
+ // ok, we've clipped everything.\r
+ // now draw it.\r
+ const core::dimension2d<s32> sourceSize(targetRect.getSize());\r
+ const core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner + (targetRect.UpperLeftCorner - destPos));\r
+\r
+ const core::dimension2d<u32>& tex_orgsize = texture->getOriginalSize();\r
+ const f32 invW = 1.f / static_cast<f32>(tex_orgsize.Width);\r
+ const f32 invH = 1.f / static_cast<f32>(tex_orgsize.Height);\r
+ const core::rect<f32> tcoords(\r
+ sourcePos.X * invW,\r
+ sourcePos.Y * invH,\r
+ (sourcePos.X + sourceSize.Width) * invW,\r
+ (sourcePos.Y + sourceSize.Height) * invH);\r
+\r
+\r
+ Quad2DVertices[0].Color = color;\r
+ Quad2DVertices[1].Color = color;\r
+ Quad2DVertices[2].Color = color;\r
+ Quad2DVertices[3].Color = color;\r
+\r
+ Quad2DVertices[0].Pos = core::vector3df((f32)targetRect.UpperLeftCorner.X, (f32)targetRect.UpperLeftCorner.Y, 0.0f);\r
+ Quad2DVertices[1].Pos = core::vector3df((f32)targetRect.LowerRightCorner.X, (f32)targetRect.UpperLeftCorner.Y, 0.0f);\r
+ Quad2DVertices[2].Pos = core::vector3df((f32)targetRect.LowerRightCorner.X, (f32)targetRect.LowerRightCorner.Y, 0.0f);\r
+ Quad2DVertices[3].Pos = core::vector3df((f32)targetRect.UpperLeftCorner.X, (f32)targetRect.LowerRightCorner.Y, 0.0f);\r
+\r
+ Quad2DVertices[0].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);\r
+ Quad2DVertices[1].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);\r
+ Quad2DVertices[2].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);\r
+ Quad2DVertices[3].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);\r
+\r
+ //SBlitJob job;\r
+ //transform_for_BlitJob2D(job, Quad2DVertices, renderTargetSize,this);\r
+\r
+ setRenderStates2DMode(color, (video::ITexture*) texture, useAlphaChannelOfTexture);\r
+\r
+ drawVertexPrimitiveList(Quad2DVertices, 4,\r
+ quad_triangle_indexList, 2,\r
+ EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);\r
+\r
+ setRenderStates3DMode();\r
+\r
+}\r
+\r
+\r
+//! Draws a part of the texture into the rectangle.\r
+void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,\r
+ const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,\r
+ const video::SColor* const colors, bool useAlphaChannelOfTexture)\r
+{\r
+ const core::dimension2d<u32>& st = texture->getOriginalSize();\r
+ const f32 invW = 1.f / static_cast<f32>(st.Width);\r
+ const f32 invH = 1.f / static_cast<f32>(st.Height);\r
+ const core::rect<f32> tcoords(\r
+ sourceRect.UpperLeftCorner.X * invW,\r
+ sourceRect.UpperLeftCorner.Y * invH,\r
+ sourceRect.LowerRightCorner.X * invW,\r
+ sourceRect.LowerRightCorner.Y *invH);\r
+\r
+ const video::SColor temp[4] =\r
+ {\r
+ 0xFFFFFFFF,\r
+ 0xFFFFFFFF,\r
+ 0xFFFFFFFF,\r
+ 0xFFFFFFFF\r
+ };\r
\r
- dColor = LightSpace.Global_AmbientLight;\r
- dColor.add ( Material.EmissiveColor );\r
+ const video::SColor* const useColor = colors ? colors : temp;\r
\r
- if ( Lights.size () == 0 )\r
- {\r
- dColor.saturate( dest->Color[0], vertexargb);\r
- return;\r
- }\r
\r
- sVec3 ambient;\r
- sVec3 diffuse;\r
- sVec3 specular;\r
+ Quad2DVertices[0].Color = useColor[0];\r
+ Quad2DVertices[1].Color = useColor[3];\r
+ Quad2DVertices[2].Color = useColor[2];\r
+ Quad2DVertices[3].Color = useColor[1];\r
\r
+ Quad2DVertices[0].Pos = core::vector3df((f32)destRect.UpperLeftCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f);\r
+ Quad2DVertices[1].Pos = core::vector3df((f32)destRect.LowerRightCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f);\r
+ Quad2DVertices[2].Pos = core::vector3df((f32)destRect.LowerRightCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f);\r
+ Quad2DVertices[3].Pos = core::vector3df((f32)destRect.UpperLeftCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f);\r
\r
- // the universe started in darkness..\r
- ambient.set ( 0.f, 0.f, 0.f );\r
- diffuse.set ( 0.f, 0.f, 0.f );\r
- specular.set ( 0.f, 0.f, 0.f );\r
+ Quad2DVertices[0].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);\r
+ Quad2DVertices[1].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);\r
+ Quad2DVertices[2].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);\r
+ Quad2DVertices[3].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);\r
\r
\r
- u32 i;\r
- f32 dot;\r
- f32 len;\r
- f32 attenuation;\r
- sVec4 vp; // unit vector vertex to light\r
- sVec4 lightHalf; // blinn-phong reflection\r
+ const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();\r
\r
- for ( i = 0; i!= LightSpace.Light.size (); ++i )\r
+ if (clipRect)\r
{\r
- const SBurningShaderLight &light = LightSpace.Light[i];\r
+ if (!clipRect->isValid())\r
+ return;\r
\r
- if ( !light.LightIsOn )\r
- continue;\r
+ //glEnable(GL_SCISSOR_TEST);\r
+ EyeSpace.TL_Flag |= TL_SCISSOR;\r
+ setScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,\r
+ clipRect->getWidth(), clipRect->getHeight());\r
+ }\r
\r
- // accumulate ambient\r
- ambient.add ( light.AmbientColor );\r
+ video::SColor alphaTest;\r
+ alphaTest.color = useColor[0].color & useColor[0].color & useColor[0].color & useColor[0].color;\r
\r
- switch ( light.Type )\r
- {\r
- case video::ELT_SPOT:\r
- case video::ELT_POINT:\r
- // surface to light\r
- vp.x = light.pos.x - LightSpace.vertex.x;\r
- vp.y = light.pos.y - LightSpace.vertex.y;\r
- vp.z = light.pos.z - LightSpace.vertex.z;\r
- //vp.x = light.pos_objectspace.x - LightSpace.vertex.x;\r
- //vp.y = light.pos_objectspace.y - LightSpace.vertex.x;\r
- //vp.z = light.pos_objectspace.z - LightSpace.vertex.x;\r
-\r
- len = vp.get_length_xyz_square();\r
- if ( light.radius < len )\r
- continue;\r
-\r
- len = core::reciprocal_squareroot ( len );\r
-\r
- // build diffuse reflection\r
-\r
- //angle between normal and light vector\r
- vp.mul ( len );\r
- dot = LightSpace.normal.dot_xyz ( vp );\r
- if ( dot < 0.f )\r
- continue;\r
-\r
- attenuation = light.constantAttenuation + ( 1.f - ( len * light.linearAttenuation ) );\r
-\r
- // diffuse component\r
- diffuse.mulAdd ( light.DiffuseColor, 3.f * dot * attenuation );\r
-\r
- if ( !(LightSpace.Flags & SPECULAR) )\r
- continue;\r
-\r
- // build specular\r
- // surface to view\r
- lightHalf.x = LightSpace.campos.x - LightSpace.vertex.x;\r
- lightHalf.y = LightSpace.campos.y - LightSpace.vertex.y;\r
- lightHalf.z = LightSpace.campos.z - LightSpace.vertex.z;\r
- lightHalf.normalize_xyz();\r
- lightHalf += vp;\r
- lightHalf.normalize_xyz();\r
-\r
- // specular\r
- dot = LightSpace.normal.dot_xyz ( lightHalf );\r
- if ( dot < 0.f )\r
- continue;\r
-\r
- //specular += light.SpecularColor * ( powf ( Material.org.Shininess ,dot ) * attenuation );\r
- specular.mulAdd ( light.SpecularColor, dot * attenuation );\r
- break;\r
-\r
- case video::ELT_DIRECTIONAL:\r
-\r
- //angle between normal and light vector\r
- dot = LightSpace.normal.dot_xyz ( light.pos );\r
- if ( dot < 0.f )\r
- continue;\r
-\r
- // diffuse component\r
- diffuse.mulAdd ( light.DiffuseColor, dot );\r
- break;\r
- default:\r
- break;\r
- }\r
+ //SBlitJob job;\r
+ //transform_for_BlitJob2D(job, Quad2DVertices, renderTargetSize, this);\r
\r
- }\r
+ setRenderStates2DMode(alphaTest, (video::ITexture*) texture, useAlphaChannelOfTexture);\r
\r
- // sum up lights\r
- dColor.mulAdd (ambient, Material.AmbientColor );\r
- dColor.mulAdd (diffuse, Material.DiffuseColor);\r
- dColor.mulAdd (specular, Material.SpecularColor);\r
+ drawVertexPrimitiveList(Quad2DVertices, 4,\r
+ quad_triangle_indexList, 2,\r
+ EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);\r
\r
- dColor.saturate ( dest->Color[0], vertexargb );\r
-}\r
\r
-#endif\r
+ if (clipRect)\r
+ EyeSpace.TL_Flag &= ~TL_SCISSOR;\r
\r
+ setRenderStates3DMode();\r
\r
-//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.\r
-void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,\r
- const core::rect<s32>& sourceRect,\r
- const core::rect<s32>* clipRect, SColor color,\r
- bool useAlphaChannelOfTexture)\r
-{\r
- if (texture)\r
- {\r
- if (texture->getDriverType() != EDT_BURNINGSVIDEO)\r
- {\r
- os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);\r
- return;\r
- }\r
\r
-#if 0\r
- // 2d methods don't use viewPort\r
- core::position2di dest = destPos;\r
- core::recti clip=ViewPort;\r
- if (ViewPort.getSize().Width != ScreenSize.Width)\r
- {\r
- dest.X=ViewPort.UpperLeftCorner.X+core::round32_fast(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width);\r
- dest.Y=ViewPort.UpperLeftCorner.Y+core::round32_fast(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height);\r
- if (clipRect)\r
- {\r
- clip.constrainTo(*clipRect);\r
- }\r
- clipRect = &clip;\r
- }\r
-#endif\r
- if (useAlphaChannelOfTexture)\r
- ((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha(\r
- RenderTargetSurface, destPos, sourceRect, color, clipRect);\r
- else\r
- ((CSoftwareTexture2*)texture)->getImage()->copyTo(\r
- RenderTargetSurface, destPos, sourceRect, clipRect);\r
- }\r
}\r
\r
\r
-//! Draws a part of the texture into the rectangle.\r
-void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,\r
- const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,\r
- const video::SColor* const colors, bool useAlphaChannelOfTexture)\r
+//!Draws an 2d rectangle with a gradient.\r
+void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position,\r
+ SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,\r
+ const core::rect<s32>* clip)\r
{\r
- if (texture)\r
- {\r
- if (texture->getDriverType() != EDT_BURNINGSVIDEO)\r
- {\r
- os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);\r
- return;\r
- }\r
+ core::rect<s32> pos = position;\r
+\r
+ if (clip)\r
+ pos.clipAgainst(*clip);\r
+\r
+ if (!pos.isValid())\r
+ return;\r
+\r
+ Quad2DVertices[0].Color = colorLeftUp;\r
+ Quad2DVertices[1].Color = colorRightUp;\r
+ Quad2DVertices[2].Color = colorRightDown;\r
+ Quad2DVertices[3].Color = colorLeftDown;\r
+\r
+ Quad2DVertices[0].Pos = core::vector3df((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f);\r
+ Quad2DVertices[1].Pos = core::vector3df((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f);\r
+ Quad2DVertices[2].Pos = core::vector3df((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f);\r
+ Quad2DVertices[3].Pos = core::vector3df((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f);\r
+\r
+ Quad2DVertices[0].TCoords.X = 0.f;\r
+ Quad2DVertices[0].TCoords.Y = 0.f;\r
+ Quad2DVertices[1].TCoords.X = 0.f;\r
+ Quad2DVertices[1].TCoords.Y = 0.f;\r
+ Quad2DVertices[2].TCoords.X = 0.f;\r
+ Quad2DVertices[3].TCoords.Y = 0.f;\r
+ Quad2DVertices[3].TCoords.X = 0.f;\r
+ Quad2DVertices[3].TCoords.Y = 0.f;\r
+\r
+\r
+ video::SColor alphaTest;\r
+ alphaTest.color = colorLeftUp.color & colorRightUp.color & colorRightDown.color & colorLeftDown.color;\r
+ setRenderStates2DMode(alphaTest, 0, 0);\r
+\r
+ drawVertexPrimitiveList(Quad2DVertices, 4,\r
+ quad_triangle_indexList, 2,\r
+ EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);\r
+\r
+ setRenderStates3DMode();\r
\r
- if (useAlphaChannelOfTexture)\r
- StretchBlit(BLITTER_TEXTURE_ALPHA_BLEND, RenderTargetSurface, &destRect, &sourceRect,\r
- ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0));\r
- else\r
- StretchBlit(BLITTER_TEXTURE, RenderTargetSurface, &destRect, &sourceRect,\r
- ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0));\r
- }\r
}\r
\r
+\r
+#endif // SOFTWARE_DRIVER_2_2D_AS_3D\r
+\r
+\r
+\r
+\r
+\r
//! Draws a 2d line.\r
void CBurningVideoDriver::draw2DLine(const core::position2d<s32>& start,\r
const core::position2d<s32>& end,\r
SColor color)\r
{\r
- drawLine(BackBuffer, start, end, color );\r
+ drawLine(RenderTargetSurface, start, end, color );\r
}\r
\r
\r
//! Draws a pixel\r
void CBurningVideoDriver::drawPixel(u32 x, u32 y, const SColor & color)\r
{\r
- BackBuffer->setPixel(x, y, color, true);\r
-}\r
-\r
-\r
-//! draw an 2d rectangle\r
-void CBurningVideoDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos,\r
- const core::rect<s32>* clip)\r
-{\r
- if (clip)\r
- {\r
- core::rect<s32> p(pos);\r
-\r
- p.clipAgainst(*clip);\r
-\r
- if(!p.isValid())\r
- return;\r
-\r
- drawRectangle(BackBuffer, p, color);\r
- }\r
- else\r
- {\r
- if(!pos.isValid())\r
- return;\r
-\r
- drawRectangle(BackBuffer, pos, color);\r
- }\r
+ RenderTargetSurface->setPixel(x, y, color, true);\r
}\r
\r
\r
{\r
// make sure width and height are multiples of 2\r
core::dimension2d<u32> realSize(size);\r
-\r
+/*\r
if (realSize.Width % 2)\r
realSize.Width += 1;\r
\r
if (realSize.Height % 2)\r
realSize.Height += 1;\r
-\r
+*/\r
if (ScreenSize != realSize)\r
{\r
if (ViewPort.getWidth() == (s32)ScreenSize.Width &&\r
}\r
\r
\r
-//!Draws an 2d rectangle with a gradient.\r
-void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position,\r
- SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,\r
- const core::rect<s32>* clip)\r
+//! Draws a 3d line.\r
+void CBurningVideoDriver::draw3DLine(const core::vector3df& start,\r
+ const core::vector3df& end, SColor color_start)\r
{\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-\r
- core::rect<s32> pos = position;\r
-\r
- if (clip)\r
- pos.clipAgainst(*clip);\r
-\r
- if (!pos.isValid())\r
- return;\r
-\r
- const core::dimension2d<s32> renderTargetSize ( ViewPort.getSize() );\r
-\r
- const s32 xPlus = -(renderTargetSize.Width>>1);\r
- const f32 xFact = 1.0f / (renderTargetSize.Width>>1);\r
-\r
- const s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1);\r
- const f32 yFact = 1.0f / (renderTargetSize.Height>>1);\r
+ SColor color_end = color_start;\r
\r
- // fill VertexCache direct\r
- s4DVertex *v;\r
+ VertexCache.primitiveHasVertex = 2;\r
+ VertexCache.vType = E4VT_LINE;\r
\r
- VertexCache.vertexCount = 4;\r
+ s4DVertex* v = Clipper.data;\r
\r
- VertexCache.info[0].index = 0;\r
- VertexCache.info[1].index = 1;\r
- VertexCache.info[2].index = 2;\r
- VertexCache.info[3].index = 3;\r
+ transform_calc(ETS_PROJ_MODEL_VIEW);\r
+ const core::matrix4* matrix = Transformation[TransformationStack];\r
+ matrix[ETS_PROJ_MODEL_VIEW].transformVect ( &v[0].Pos.x, start );\r
+ matrix[ETS_PROJ_MODEL_VIEW].transformVect ( &v[2].Pos.x, end );\r
\r
- v = &VertexCache.mem.data [ 0 ];\r
-\r
- v[0].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f );\r
- v[0].Color[0].setA8R8G8B8 ( colorLeftUp.color );\r
-\r
- v[2].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f );\r
- v[2].Color[0].setA8R8G8B8 ( colorRightUp.color );\r
-\r
- v[4].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f ,1.f );\r
- v[4].Color[0].setA8R8G8B8 ( colorRightDown.color );\r
-\r
- v[6].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f, 1.f );\r
- v[6].Color[0].setA8R8G8B8 ( colorLeftDown.color );\r
-\r
- s32 i;\r
- u32 g;\r
-\r
- for ( i = 0; i!= 8; i += 2 )\r
- {\r
- v[i + 0].flag = clipToFrustumTest ( v + i );\r
- v[i + 1].flag = 0;\r
- if ( (v[i].flag & VERTEX4D_INSIDE ) == VERTEX4D_INSIDE )\r
- {\r
- ndc_2_dc_and_project ( v + i + 1, v + i, 2 );\r
- }\r
- }\r
-\r
-\r
- IBurningShader * render;\r
-\r
- render = BurningShader [ ETR_GOURAUD_ALPHA_NOZ ];\r
- render->setRenderTarget(RenderTargetSurface, ViewPort);\r
-\r
- static const s16 indexList[6] = {0,1,2,0,2,3};\r
-\r
- s4DVertex * face[3];\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+ v[0].Color[0].setA8R8G8B8 ( color_start.color );\r
+ v[2].Color[0].setA8R8G8B8 ( color_end.color );\r
+#endif\r
\r
- for ( i = 0; i!= 6; i += 3 )\r
+ u32 i;\r
+ for (i = 0; i < 4; i += sizeof_s4DVertexPairRel)\r
{\r
- face[0] = VertexCache_getVertex ( indexList [ i + 0 ] );\r
- face[1] = VertexCache_getVertex ( indexList [ i + 1 ] );\r
- face[2] = VertexCache_getVertex ( indexList [ i + 2 ] );\r
-\r
- // test clipping\r
- u32 test = face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_INSIDE;\r
-\r
- if ( test == VERTEX4D_INSIDE )\r
- {\r
- render->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 );\r
- continue;\r
- }\r
- // Todo: all vertices are clipped in 2d..\r
- // is this true ?\r
- u32 vOut = 6;\r
- memcpy ( CurrentOut.data + 0, face[0], sizeof ( s4DVertex ) * 2 );\r
- memcpy ( CurrentOut.data + 2, face[1], sizeof ( s4DVertex ) * 2 );\r
- memcpy ( CurrentOut.data + 4, face[2], sizeof ( s4DVertex ) * 2 );\r
-\r
- vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 );\r
- if ( vOut < 3 )\r
- continue;\r
-\r
- vOut <<= 1;\r
- // to DC Space, project homogenous vertex\r
- ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );\r
-\r
- // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )\r
- for ( g = 0; g <= vOut - 6; g += 2 )\r
- {\r
- // rasterize\r
- render->drawTriangle ( CurrentOut.data + 1, &CurrentOut.data[g + 3], &CurrentOut.data[g + 5] );\r
- }\r
-\r
+ v[i + 0].flag = (u32)(VertexCache.vSize[VertexCache.vType].Format);\r
+ v[i + 1].flag = v[i + 0].flag;\r
}\r
-#else\r
- draw2DRectangle ( colorLeftUp, position, clip );\r
-#endif\r
-}\r
\r
\r
-//! Draws a 3d line.\r
-void CBurningVideoDriver::draw3DLine(const core::vector3df& start,\r
- const core::vector3df& end, SColor color)\r
-{\r
- Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[0].Pos.x, start );\r
- Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[2].Pos.x, end );\r
-\r
- u32 g;\r
- u32 vOut;\r
-\r
- // no clipping flags\r
- for ( g = 0; g != CurrentOut.ElementSize; ++g )\r
- {\r
- CurrentOut.data[g].flag = 0;\r
- Temp.data[g].flag = 0;\r
- }\r
+ size_t g;\r
+ size_t vOut;\r
\r
// vertices count per line\r
- vOut = clipToFrustum ( CurrentOut.data, Temp.data, 2 );\r
- if ( vOut < 2 )\r
+ vOut = clipToFrustum (VertexCache.primitiveHasVertex);\r
+ if ( vOut < VertexCache.primitiveHasVertex)\r
return;\r
\r
- vOut <<= 1;\r
-\r
- IBurningShader * line;\r
- line = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ];\r
- line->setRenderTarget(RenderTargetSurface, ViewPort);\r
+ vOut *= sizeof_s4DVertexPairRel;\r
\r
// to DC Space, project homogenous vertex\r
- ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );\r
+ ndc_2_dc_and_project ( v + 1, v, vOut );\r
\r
// unproject vertex color\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if 0\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
for ( g = 0; g != vOut; g+= 2 )\r
{\r
- CurrentOut.data[ g + 1].Color[0].setA8R8G8B8 ( color.color );\r
+ v[ g + 1].Color[0].setA8R8G8B8 ( color.color );\r
}\r
+#endif\r
#endif\r
\r
+ IBurningShader * shader = 0;\r
+ if ( CurrentShader && CurrentShader->canWireFrame() ) shader = CurrentShader;\r
+ else shader = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ];\r
+ shader = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ];\r
+\r
+ shader->pushEdgeTest(1,0,1);\r
+ shader->setRenderTarget(RenderTargetSurface, ViewPort);\r
\r
- for ( g = 0; g <= vOut - 4; g += 2 )\r
+ for ( g = 0; g <= vOut - 4; g += sizeof_s4DVertexPairRel)\r
{\r
- // rasterize\r
- line->drawLine ( CurrentOut.data + 1, CurrentOut.data + g + 3 );\r
+ shader->drawLine ( v + 1 + g, v + 1 + g + sizeof_s4DVertexPairRel);\r
}\r
+\r
+ shader->popEdgeTest();\r
+\r
}\r
\r
\r
const wchar_t* CBurningVideoDriver::getName() const\r
{\r
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
- return L"Burning's Video 0.49 beautiful";\r
+ return L"Burning's Video 0.51 beautiful";\r
#elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST )\r
- return L"Burning's Video 0.49 ultra fast";\r
+ return L"Burning's Video 0.51 ultra fast";\r
#elif defined ( BURNINGVIDEO_RENDERER_FAST )\r
- return L"Burning's Video 0.49 fast";\r
+ return L"Burning's Video 0.51 fast";\r
+#elif defined ( BURNINGVIDEO_RENDERER_CE )\r
+ return L"Burning's Video 0.51 CE";\r
#else\r
- return L"Burning's Video 0.49";\r
+ return L"Burning's Video 0.51";\r
#endif\r
}\r
\r
//! Returns the graphics card vendor name.\r
core::stringc CBurningVideoDriver::getVendorInfo()\r
{\r
- return "Burning's Video: Ing. Thomas Alten (c) 2006-2015";\r
+ return "Burning's Video: Ing. Thomas Alten (c) 2006-2020";\r
}\r
\r
\r
}\r
\r
\r
-//! Returns the transformation set by setTransform\r
-const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const\r
-{\r
- return Transformation[state];\r
-}\r
-\r
-\r
//! Creates a render target texture.\r
ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,\r
const io::path& name, const ECOLOR_FORMAT format)\r
{\r
IImage* img = createImage(BURNINGSHADER_COLOR_FORMAT, size);\r
- ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET );\r
+ ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET,this);\r
img->drop();\r
addTexture(tex);\r
tex->drop();\r
RenderTargetSurface->fill(color);\r
\r
if ((flag & ECBF_DEPTH) && DepthBuffer)\r
- DepthBuffer->clear();\r
+ DepthBuffer->clear(depth);\r
\r
if ((flag & ECBF_STENCIL) && StencilBuffer)\r
- StencilBuffer->clear();\r
+ StencilBuffer->clear(stencil);\r
}\r
\r
+#if 0\r
+void CBurningVideoDriver::saveBuffer()\r
+{\r
+ static int shotCount = 0;\r
+ char buf[256];\r
+ if (BackBuffer)\r
+ {\r
+ sprintf(buf, "shot/%04d_b.png", shotCount);\r
+ writeImageToFile(BackBuffer, buf);\r
+ }\r
+ if (StencilBuffer)\r
+ {\r
+ CImage stencil(ECF_A8R8G8B8, StencilBuffer->getSize(), StencilBuffer->lock(), true, false);\r
+ sprintf(buf, "shot/%04d_s.ppm", shotCount);\r
+ writeImageToFile(&stencil, buf);\r
+ }\r
+ shotCount += 1;\r
+}\r
+#endif\r
\r
//! Returns an image created from the last rendered frame.\r
IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)\r
\r
ITexture* CBurningVideoDriver::createDeviceDependentTexture(const io::path& name, IImage* image)\r
{\r
- CSoftwareTexture2* texture = new CSoftwareTexture2(image, name, (getTextureCreationFlag(ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0) |\r
- (getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2) ? 0 : CSoftwareTexture2::NP2_SIZE));\r
+ u32 flags =\r
+ ((TextureCreationFlags & ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0)\r
+ | ((TextureCreationFlags & ETCF_AUTO_GENERATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP_AUTO : 0)\r
+ | ((TextureCreationFlags & ETCF_ALLOW_NON_POWER_2) ? CSoftwareTexture2::ALLOW_NPOT : 0)\r
+#if defined(IRRLICHT_sRGB)\r
+ | ((TextureCreationFlags & ETCF_IMAGE_IS_LINEAR) ? CSoftwareTexture2::IMAGE_IS_LINEAR : 0)\r
+ | ((TextureCreationFlags & ETCF_TEXTURE_IS_LINEAR) ? CSoftwareTexture2::TEXTURE_IS_LINEAR : 0)\r
+#endif\r
+ ;\r
\r
+ CSoftwareTexture2* texture = new CSoftwareTexture2(image, name, flags, this);\r
return texture;\r
}\r
\r
//! call.\r
u32 CBurningVideoDriver::getMaximalPrimitiveCount() const\r
{\r
- return 0xFFFFFFFF;\r
+ return 0x7FFFFFFF;\r
}\r
\r
\r
void CBurningVideoDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)\r
{\r
const u32 count = triangles.size();\r
- IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ];\r
-\r
- CurrentShader = shader;\r
- shader->setRenderTarget(RenderTargetSurface, ViewPort);\r
+ if (!StencilBuffer || !count)\r
+ return;\r
\r
Material.org.MaterialType = video::EMT_SOLID;\r
Material.org.Lighting = false;\r
Material.org.ZWriteEnable = video::EZW_OFF;\r
- Material.org.ZBuffer = ECFN_LESSEQUAL;\r
- LightSpace.Flags &= ~VERTEXTRANSFORM;\r
+ Material.org.ZBuffer = ECFN_LESS;\r
+\r
+ CurrentShader = BurningShader[ETR_STENCIL_SHADOW];\r
+\r
+ CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);\r
+ CurrentShader->pushEdgeTest(Material.org.Wireframe, 0,0);\r
\r
+ //setMaterial\r
+ EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP);\r
+ CurrentShader->setTLFlag(EyeSpace.TL_Flag);\r
//glStencilMask(~0);\r
//glStencilFunc(GL_ALWAYS, 0, ~0);\r
\r
- if (true)// zpass does not work yet\r
+ //glEnable(GL_DEPTH_CLAMP);\r
+\r
+ if (zfail)\r
{\r
+ Material.org.BackfaceCulling = false;\r
+ Material.org.FrontfaceCulling = true;\r
+ Material.CullFlag = CULL_FRONT | CULL_INVISIBLE;\r
+\r
+ CurrentShader->setStencilOp( StencilOp_KEEP, StencilOp_INCR, StencilOp_KEEP);\r
+ drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);\r
+\r
Material.org.BackfaceCulling = true;\r
Material.org.FrontfaceCulling = false;\r
- shader->setParam ( 0, 0 );\r
- shader->setParam ( 1, 1 );\r
- shader->setParam ( 2, 0 );\r
- drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 );\r
- //glStencilOp(GL_KEEP, incr, GL_KEEP);\r
- //glDrawArrays(GL_TRIANGLES,0,count);\r
+ Material.CullFlag = CULL_BACK | CULL_INVISIBLE;\r
\r
- Material.org.BackfaceCulling = false;\r
- Material.org.FrontfaceCulling = true;\r
- shader->setParam ( 0, 0 );\r
- shader->setParam ( 1, 2 );\r
- shader->setParam ( 2, 0 );\r
- drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 );\r
- //glStencilOp(GL_KEEP, decr, GL_KEEP);\r
- //glDrawArrays(GL_TRIANGLES,0,count);\r
+ CurrentShader->setStencilOp( StencilOp_KEEP, StencilOp_DECR, StencilOp_KEEP);\r
+ drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);\r
}\r
else // zpass\r
{\r
Material.org.BackfaceCulling = true;\r
Material.org.FrontfaceCulling = false;\r
- shader->setParam ( 0, 0 );\r
- shader->setParam ( 1, 0 );\r
- shader->setParam ( 2, 1 );\r
- //glStencilOp(GL_KEEP, GL_KEEP, incr);\r
- //glDrawArrays(GL_TRIANGLES,0,count);\r
+ Material.CullFlag = CULL_BACK | CULL_INVISIBLE;\r
+\r
+ CurrentShader->setStencilOp( StencilOp_KEEP, StencilOp_KEEP, StencilOp_INCR);\r
+ drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);\r
\r
Material.org.BackfaceCulling = false;\r
Material.org.FrontfaceCulling = true;\r
- shader->setParam ( 0, 0 );\r
- shader->setParam ( 1, 0 );\r
- shader->setParam ( 2, 2 );\r
- //glStencilOp(GL_KEEP, GL_KEEP, decr);\r
- //glDrawArrays(GL_TRIANGLES,0,count);\r
+ Material.CullFlag = CULL_FRONT | CULL_INVISIBLE;\r
+\r
+ CurrentShader->setStencilOp(StencilOp_KEEP, StencilOp_KEEP, StencilOp_DECR);\r
+ drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);\r
}\r
+ //glDisable(GL_DEPTH_CLAMP);\r
+\r
}\r
\r
//! Fills the stencil shadow with color. After the shadow volume has been drawn\r
const u32 h = RenderTargetSurface->getDimension().Height;\r
const u32 w = RenderTargetSurface->getDimension().Width;\r
tVideoSample *dst;\r
- u32 *stencil;\r
- u32* const stencilBase=(u32*) StencilBuffer->lock();\r
+ const tStencilSample* stencil;\r
+\r
+#if defined(SOFTWARE_DRIVER_2_32BIT)\r
+ const u32 alpha = extractAlpha(leftUpEdge.color);\r
+ const u32 src = leftUpEdge.color;\r
+#else\r
+ const u16 alpha = extractAlpha( leftUpEdge.color ) >> 3;\r
+ const u32 src = video::A8R8G8B8toA1R5G5B5( leftUpEdge.color );\r
+#endif\r
+\r
\r
for ( u32 y = 0; y < h; ++y )\r
{\r
dst = (tVideoSample*)RenderTargetSurface->getData() + ( y * w );\r
- stencil = stencilBase + ( y * w );\r
+ stencil = (tStencilSample*)StencilBuffer->lock() + (y * w);\r
\r
for ( u32 x = 0; x < w; ++x )\r
{\r
- if ( stencil[x] > 1 )\r
+ if ( stencil[x] )\r
{\r
- dst[x] = PixelBlend32 ( dst[x], leftUpEdge.color );\r
+#if defined(SOFTWARE_DRIVER_2_32BIT)\r
+ dst[x] = PixelBlend32 ( dst[x], src,alpha );\r
+#else\r
+ dst[x] = PixelBlend16( dst[x], src, alpha );\r
+#endif\r
}\r
}\r
}\r
\r
- StencilBuffer->clear();\r
+ if ( clearStencilBuffer )\r
+ StencilBuffer->clear(0);\r
}\r
\r
\r
core::dimension2du CBurningVideoDriver::getMaxTextureSize() const\r
{\r
- return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE);\r
+ return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1 << 20,\r
+ SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1 << 20);\r
}\r
\r
bool CBurningVideoDriver::queryTextureFormat(ECOLOR_FORMAT format) const\r
\r
bool CBurningVideoDriver::needsTransparentRenderPass(const irr::video::SMaterial& material) const\r
{\r
- return CNullDriver::needsTransparentRenderPass(material) || material.isTransparent();\r
+ return CNullDriver::needsTransparentRenderPass(material) || material.isAlphaBlendOperation(); // || material.isTransparent();\r
}\r
\r
+s32 CBurningVideoDriver::addShaderMaterial(const c8* vertexShaderProgram,\r
+ const c8* pixelShaderProgram,\r
+ IShaderConstantSetCallBack* callback,\r
+ E_MATERIAL_TYPE baseMaterial,\r
+ s32 userData)\r
+{\r
+ s32 materialID = -1;\r
\r
-} // end namespace video\r
-} // end namespace irr\r
+ IBurningShader* shader = new IBurningShader(\r
+ this, materialID,\r
+ vertexShaderProgram, 0, video::EVST_VS_1_1,\r
+ pixelShaderProgram, 0, video::EPST_PS_1_1,\r
+ 0, 0, EGST_GS_4_0,\r
+ scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,\r
+ callback, baseMaterial, userData);\r
\r
-#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+ shader->drop();\r
+\r
+ return materialID;\r
+}\r
+\r
+//! Adds a new material renderer to the VideoDriver, based on a high level shading language.\r
+s32 CBurningVideoDriver::addHighLevelShaderMaterial(\r
+ const c8* vertexShaderProgram,\r
+ const c8* vertexShaderEntryPointName,\r
+ E_VERTEX_SHADER_TYPE vsCompileTarget,\r
+ const c8* pixelShaderProgram,\r
+ const c8* pixelShaderEntryPointName,\r
+ E_PIXEL_SHADER_TYPE psCompileTarget,\r
+ const c8* geometryShaderProgram,\r
+ const c8* geometryShaderEntryPointName,\r
+ E_GEOMETRY_SHADER_TYPE gsCompileTarget,\r
+ scene::E_PRIMITIVE_TYPE inType,\r
+ scene::E_PRIMITIVE_TYPE outType,\r
+ u32 verticesOut,\r
+ IShaderConstantSetCallBack* callback,\r
+ E_MATERIAL_TYPE baseMaterial,\r
+ s32 userData\r
+ )\r
+{\r
+ s32 materialID = -1;\r
+\r
+ IBurningShader* shader = new IBurningShader(\r
+ this, materialID,\r
+ vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,\r
+ pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,\r
+ geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,\r
+ inType, outType, verticesOut,\r
+ callback, baseMaterial, userData);\r
+\r
+ shader->drop();\r
+\r
+ return materialID;\r
+}\r
\r
\r
-#if defined(_IRR_WINDOWS_) && defined(_IRR_COMPILE_WITH_BURNINGSVIDEO_)\r
- #include <windows.h>\r
+void CBurningVideoDriver::setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType)\r
+{\r
+ //this should be in material....\r
+ Material.Fallback_MaterialType = fallback_MaterialType;\r
+}\r
\r
-struct dreadglobal\r
+void CBurningVideoDriver::setBasicRenderStates(const SMaterial& material,\r
+ const SMaterial& lastMaterial,\r
+ bool resetAllRenderstates)\r
{\r
- DWORD dreadid;\r
- HANDLE dread;\r
- irr::video::CBurningVideoDriver *driver;\r
- HANDLE sync;\r
\r
- const irr::SIrrlichtCreationParameters* params;\r
- irr::io::IFileSystem* io;\r
- irr::video::IImagePresenter* presenter;\r
-};\r
+}\r
\r
-namespace\r
+//! Return an index constant for the vertex shader based on a name.\r
+s32 CBurningVideoDriver::getVertexShaderConstantID(const c8* name)\r
{\r
- dreadglobal burning_dread;\r
+ return -1;\r
}\r
\r
-DWORD WINAPI dreadFun( void *p)\r
+bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const f32* floats, int count)\r
{\r
- printf("Hi This is burning dread\n");\r
- burning_dread.driver = new irr::video::CBurningVideoDriver(*burning_dread.params, burning_dread.io, burning_dread.presenter);\r
+ return true;\r
+}\r
\r
- SetEvent (burning_dread.sync );\r
- while ( 1 )\r
- {\r
- Sleep ( 1000 );\r
- }\r
- return 0;\r
+bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const s32* ints, int count)\r
+{\r
+ return true;\r
}\r
\r
-#endif\r
+bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const u32* ints, int count)\r
+{\r
+ return true;\r
+}\r
+\r
+void CBurningVideoDriver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
+{\r
+}\r
+\r
+//! Return an index constant for the pixel shader based on a name.\r
+s32 CBurningVideoDriver::getPixelShaderConstantID(const c8* name)\r
+{\r
+ return -1;\r
+}\r
+\r
+bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const f32* floats, int count)\r
+{\r
+ return false;\r
+}\r
+\r
+bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const s32* ints, int count)\r
+{\r
+ return false;\r
+}\r
+\r
+bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const u32* ints, int count)\r
+{\r
+ return false;\r
+}\r
+\r
+void CBurningVideoDriver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1)\r
+{\r
+}\r
+\r
+//! Get pointer to the IVideoDriver interface\r
+/** \return Pointer to the IVideoDriver interface */\r
+IVideoDriver* CBurningVideoDriver::getVideoDriver()\r
+{\r
+ return this;\r
+}\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
\r
namespace irr\r
{\r
IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter)\r
{\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
-\r
- #ifdef _IRR_WINDOWS_\r
- burning_dread.sync = CreateEventA ( 0, 0, 0, "burnevent0" );\r
- burning_dread.params = ¶ms;\r
- burning_dread.io = io;\r
- burning_dread.presenter = presenter;\r
- burning_dread.dread = CreateThread ( 0, 0, dreadFun, 0, 0, &burning_dread.dreadid );\r
- WaitForSingleObject (burning_dread.sync, INFINITE );\r
- return burning_dread.driver;\r
- #else\r
- return new CBurningVideoDriver(params, io, presenter);\r
- #endif\r
-\r
+ return new CBurningVideoDriver(params, io, presenter);\r
#else\r
- return 0;\r
+ return 0;\r
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
}\r
\r
#include "irrString.h"\r
#include "SIrrCreationParameters.h"\r
\r
+\r
namespace irr\r
{\r
namespace video\r
{\r
- class CBurningVideoDriver : public CNullDriver\r
+ class CBurningVideoDriver : public CNullDriver, public IMaterialRendererServices\r
{\r
public:\r
\r
//! sets a material\r
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;\r
\r
- virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),\r
- f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;\r
+ virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor,\r
+ f32 clearDepth, u8 clearStencil) _IRR_OVERRIDE_;\r
\r
//! sets a viewport\r
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;\r
+ virtual void setScissor(int x, int y, int width, int height);\r
\r
- virtual bool beginScene(u16 clearFlag, SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0,\r
- const SExposedVideoData& videoData = SExposedVideoData(), core::rect<s32>* sourceRect = 0) _IRR_OVERRIDE_;\r
+ virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil,\r
+ const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_;\r
\r
virtual bool endScene() _IRR_OVERRIDE_;\r
\r
const void* indexList, u32 primitiveCount,\r
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;\r
\r
+ //! draws a vertex primitive list in 2d\r
+ virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,\r
+ const void* indexList, u32 primitiveCount,\r
+ E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;\r
+\r
+\r
+ //! draws an 2d image\r
+ //virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, bool useAlphaChannelOfTexture) _IRR_OVERRIDE_;\r
+\r
+ /* NullDriver calls\r
+ draw2DImage(texture, destPos,\r
+ core::rect<s32>(core::position2d<s32>(0, 0), core::dimension2di(texture->getOriginalSize())),\r
+ 0,\r
+ SColor(255, 255, 255, 255),\r
+ useAlphaChannelOfTexture\r
+ */\r
+\r
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.\r
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,\r
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,\r
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;\r
\r
- //! Draws a part of the texture into the rectangle.\r
+ //! Draws a part of the texture into the rectangle.\r
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,\r
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,\r
const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;\r
\r
//! Draws a 3d line.\r
virtual void draw3DLine(const core::vector3df& start,\r
- const core::vector3df& end, SColor color = SColor(255,255,255,255)) _IRR_OVERRIDE_;\r
+ const core::vector3df& end, SColor color_start) _IRR_OVERRIDE_;\r
\r
//! draw an 2d rectangle\r
- virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,\r
- const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;\r
+ //virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,\r
+ // const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;\r
+\r
+ /* NullDriver calls\r
+ draw2DRectangle(pos, color, color, color, color, clip);\r
+ */\r
\r
//!Draws an 2d rectangle with a gradient.\r
virtual void draw2DRectangle(const core::rect<s32>& pos,\r
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,\r
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;\r
\r
- virtual void clearBuffers(u16 flag, SColor color = SColor(255,0,0,0), f32 depth = 1.f, u8 stencil = 0) _IRR_OVERRIDE_;\r
+ virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_;\r
\r
//! Returns an image created from the last rendered frame.\r
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) _IRR_OVERRIDE_;\r
video::SColor leftDownEdge = video::SColor(0,0,0,0),\r
video::SColor rightDownEdge = video::SColor(0,0,0,0)) _IRR_OVERRIDE_;\r
\r
+ //! Enable the 2d override material\r
+ virtual void enableMaterial2D(bool enable = true) _IRR_OVERRIDE_;\r
+\r
//! Returns the graphics card vendor name.\r
virtual core::stringc getVendorInfo() _IRR_OVERRIDE_;\r
\r
IDepthBuffer * getDepthBuffer () { return DepthBuffer; }\r
IStencilBuffer * getStencilBuffer () { return StencilBuffer; }\r
\r
+ //#define Tweak_Burning\r
+#if defined(Tweak_Burning)\r
+ virtual void postEventFromUser(const void* sevent) _IRR_OVERRIDE_;\r
+#endif\r
+\r
+ //! Adds a new material renderer to the VideoDriver, using pixel and/or\r
+ //! vertex shaders to render geometry.\r
+ virtual s32 addShaderMaterial(const c8* vertexShaderProgram,\r
+ const c8* pixelShaderProgram,\r
+ IShaderConstantSetCallBack* callback,\r
+ E_MATERIAL_TYPE baseMaterial,\r
+ s32 userData) _IRR_OVERRIDE_;\r
+\r
+ //! Adds a new material renderer to the VideoDriver, based on a high level shading\r
+ //! language. Currently only HLSL in D3D9 is supported.\r
+ virtual s32 addHighLevelShaderMaterial(\r
+ const c8* vertexShaderProgram,\r
+ const c8* vertexShaderEntryPointName = 0,\r
+ E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,\r
+ const c8* pixelShaderProgram = 0,\r
+ const c8* pixelShaderEntryPointName = 0,\r
+ E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,\r
+ const c8* geometryShaderProgram = 0,\r
+ const c8* geometryShaderEntryPointName = "main",\r
+ E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,\r
+ scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,\r
+ scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,\r
+ u32 verticesOut = 0,\r
+ IShaderConstantSetCallBack* callback = 0,\r
+ E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,\r
+ s32 userData = 0) _IRR_OVERRIDE_;\r
+\r
+ //IMaterialRendererService\r
+\r
+ virtual void setBasicRenderStates(const SMaterial& material,\r
+ const SMaterial& lastMaterial,\r
+ bool resetAllRenderstates) _IRR_OVERRIDE_;\r
+\r
+ //pass BaseMaterialID\r
+ void setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType);\r
+\r
+ //! Return an index constant for the vertex shader based on a name.\r
+ virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;\r
+ virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;\r
+ virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;\r
+ virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;\r
+ virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;\r
+\r
+ //! Return an index constant for the pixel shader based on a name.\r
+ virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;\r
+ virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;\r
+ virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;\r
+ virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;\r
+ \r
+ virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;\r
+\r
+ //! Get pointer to the IVideoDriver interface\r
+ /** \return Pointer to the IVideoDriver interface */\r
+ virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;\r
+\r
protected:\r
\r
+ void saveBuffer();\r
+\r
//! sets a render target\r
void setRenderTargetImage(video::CImage* image);\r
\r
video::IImage* RenderTargetSurface;\r
core::dimension2d<u32> RenderTargetSize;\r
\r
- //! selects the right triangle renderer based on the render states.\r
- void setCurrentShader();\r
-\r
IBurningShader* CurrentShader;\r
IBurningShader* BurningShader[ETR2_COUNT];\r
\r
enum E_TRANSFORMATION_STATE_BURNING_VIDEO\r
{\r
ETS_VIEW_PROJECTION = ETS_COUNT,\r
- ETS_CURRENT,\r
- ETS_CLIPSCALE,\r
- ETS_VIEW_INVERSE,\r
- ETS_WORLD_INVERSE,\r
+ ETS_PROJ_MODEL_VIEW,\r
+ ETS_MODEL_VIEW,\r
+ ETS_NORMAL, //3x3 ModelView Tansposed Inverse\r
\r
- ETS_COUNT_BURNING\r
+ ETS_COUNT_BURNING = 16\r
};\r
\r
enum E_TRANSFORMATION_FLAG\r
{\r
- ETF_IDENTITY = 1,\r
- ETF_TEXGEN_CAMERA_NORMAL = 2,\r
- ETF_TEXGEN_CAMERA_REFLECTION = 4,\r
+ ETF_VALID = 1,\r
+ ETF_IDENTITY = 2,\r
+ ETF_TEXGEN_CAMERA_SPHERE = 4,\r
+ ETF_TEXGEN_CAMERA_REFLECTION = 8,\r
+ ETF_TEXGEN_WRAP = 16,\r
+ ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP\r
};\r
- u32 TransformationFlag[ETS_COUNT_BURNING];\r
- core::matrix4 Transformation[ETS_COUNT_BURNING];\r
+ core::matrix4 Transformation[2][ETS_COUNT_BURNING];\r
+ size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG\r
\r
- void getCameraPosWorldSpace ();\r
- void getLightPosObjectSpace ();\r
+ size_t TransformationStack; // 0 .. 3D , 1 .. 2D\r
\r
+ void setRenderStates2DMode(const video::SColor& color,video::ITexture* texture,bool useAlphaChannelOfTexture);\r
+ void setRenderStates3DMode();\r
\r
- // Vertex Cache\r
- static const SVSize vSize[];\r
+ //ETS_CLIPSCALE, // moved outside to stay at 16 matrices\r
+ f32 Transformation_ETS_CLIPSCALE[2][4];\r
+ void transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state);\r
+\r
+ //core::recti ViewPort;\r
+ AbsRectangle Scissor;\r
\r
+ // Vertex Cache\r
SVertexCache VertexCache;\r
\r
- void VertexCache_reset (const void* vertices, u32 vertexCount,\r
+ int VertexCache_reset (const void* vertices, u32 vertexCount,\r
const void* indices, u32 indexCount,\r
E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,\r
E_INDEX_TYPE iType);\r
- void VertexCache_get ( const s4DVertex ** face );\r
- void VertexCache_getbypass ( s4DVertex ** face );\r
+ void VertexCache_get (s4DVertexPair* face[4] );\r
\r
+ void VertexCache_map_source_format();\r
void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex );\r
- s4DVertex * VertexCache_getVertex ( const u32 sourceIndex );\r
+ s4DVertexPair* VertexCache_getVertex ( const u32 sourceIndex ) const;\r
\r
\r
// culling & clipping\r
- u32 clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane );\r
- u32 clipToFrustumTest ( const s4DVertex * v ) const;\r
- u32 clipToFrustum ( s4DVertex *source, s4DVertex * temp, const u32 vIn );\r
+ //size_t inline clipToHyperPlane (s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, const size_t inCount, const sVec4 &plane );\r
+ //size_t inline clipToFrustumTest ( const s4DVertex * v ) const;\r
+ public:\r
+ size_t clipToFrustum( const size_t vIn /*, const size_t clipmask_for_face*/ );\r
+ protected:\r
+\r
+ // holds transformed, clipped vertices for a triangle. triangle expands on clipping\r
+ // Buffer is in in pairs of 4DVertex (0 ... ndc, 1 .. dc and projected)\r
+ SAligned4DVertex Clipper;\r
+ SAligned4DVertex Clipper_temp;\r
\r
\r
#ifdef SOFTWARE_DRIVER_2_LIGHTING\r
+ void lightVertex_eye ( s4DVertex *dest, u32 vertexargb );\r
+#endif\r
\r
- void lightVertex ( s4DVertex *dest, u32 vertexargb );\r
//! Sets the fog mode.\r
virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start,\r
f32 end, f32 density, bool pixelFog, bool rangeFog) _IRR_OVERRIDE_;\r
-#endif\r
\r
\r
- // holds transformed, clipped vertices\r
- SAlignedVertex CurrentOut;\r
- SAlignedVertex Temp;\r
+ void ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair* source, const size_t vIn ) const;\r
\r
- void ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const;\r
- f32 screenarea ( const s4DVertex *v0 ) const;\r
- void select_polygon_mipmap ( s4DVertex *source, u32 vIn, u32 tex, const core::dimension2du& texSize ) const;\r
- f32 texelarea ( const s4DVertex *v0, int tex ) const;\r
+ //const is misleading. **v is const that true, but not *v..\r
+ f32 screenarea_inside (const s4DVertexPair* burning_restrict const face[] ) const;\r
+ s32 lodFactor_inside ( const s4DVertexPair* burning_restrict const face[], const size_t tex, f32 dc_area, f32 lod_bias ) const;\r
+ void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const;\r
\r
+ void getCameraPosWorldSpace();\r
+ SBurningShaderEyeSpace EyeSpace;\r
+ SBurningShaderMaterial Material;\r
\r
- void ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const;\r
- f32 screenarea2 ( const s4DVertex **v ) const;\r
- f32 texelarea2 ( const s4DVertex **v, int tex ) const;\r
- void select_polygon_mipmap2 ( s4DVertex **source, u32 tex, const core::dimension2du& texSize ) const;\r
-\r
+ static const sVec4 NDCPlane[6+2];\r
\r
- SBurningShaderLightSpace LightSpace;\r
- SBurningShaderMaterial Material;\r
+ //! Built-in 2D quad for 2D rendering.\r
+ S3DVertex Quad2DVertices[4];\r
\r
- static const sVec4 NDCPlane[6];\r
};\r
\r
} // end namespace video\r
#include "SoftwareDriver2_helper.h"\r
#include "CSoftwareTexture2.h"\r
#include "CSoftwareDriver2.h"\r
+#include "CBlit.h"\r
#include "os.h"\r
\r
namespace irr\r
namespace video\r
{\r
\r
+//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)\r
+void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, const video::IImage* src, const core::rect<s32>* srcRect, size_t flags);\r
+\r
//! constructor\r
-CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags)\r
- : ITexture(name, ETT_2D), MipMapLOD(0), Flags ( flags ), OriginalFormat(video::ECF_UNKNOWN)\r
+CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver)\r
+ : ITexture(name\r
+#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
+ , ETT_2D\r
+#endif\r
+ )\r
+ ,MipMapLOD(0), Flags(flags), Driver(driver)\r
{\r
#ifdef _DEBUG\r
setDebugName("CSoftwareTexture2");\r
#endif\r
\r
#ifndef SOFTWARE_DRIVER_2_MIPMAPPING\r
- Flags &= ~GEN_MIPMAP;\r
+ Flags &= ~(GEN_MIPMAP| GEN_MIPMAP_AUTO);\r
#endif\r
-\r
+ //set baseclass properties\r
DriverType = EDT_BURNINGSVIDEO;\r
ColorFormat = BURNINGSHADER_COLOR_FORMAT;\r
IsRenderTarget = (Flags & IS_RENDERTARGET) != 0;\r
- \r
- memset32 ( MipMap, 0, sizeof ( MipMap ) );\r
-\r
- if (image)\r
+ HasMipMaps = (Flags & GEN_MIPMAP) != 0;\r
+ MipMap0_Area[0] = 1;\r
+ MipMap0_Area[1] = 1;\r
+ LodBIAS = 0.75f;\r
+ for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) MipMap[i] = 0;\r
+ if (!image) return;\r
+\r
+ OriginalSize = image->getDimension();\r
+ OriginalColorFormat = image->getColorFormat();\r
+\r
+\r
+#if defined(IRRLICHT_sRGB)\r
+ if ( Flags & IMAGE_IS_LINEAR ) image->set_sRGB(0);\r
+#else\r
+ //guessing linear image\r
+ if (name.find("light") >= 0 ||\r
+ name.find("bump") >= 0 ||\r
+ name.find("height") >= 0\r
+ )\r
{\r
- bool IsCompressed = false;\r
-\r
- if (IImage::isCompressedFormat(image->getColorFormat()))\r
- {\r
- os::Printer::log("Texture compression not available.", ELL_ERROR);\r
- IsCompressed = true;\r
- }\r
-\r
- OriginalSize = image->getDimension();\r
- OriginalFormat = image->getColorFormat();\r
-\r
- core::dimension2d<u32> optSize(\r
- OriginalSize.getOptimalSize(0 != (Flags & NP2_SIZE),\r
- false, true,\r
- SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE)\r
- );\r
+ Flags |= TEXTURE_IS_LINEAR | IMAGE_IS_LINEAR;\r
+ }\r
+#endif\r
\r
- if (OriginalSize == optSize)\r
- {\r
- MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());\r
+ bool isCompressed = IImage::isCompressedFormat(OriginalColorFormat);\r
+ if (isCompressed)\r
+ {\r
+ os::Printer::log("Texture compression not available.", ELL_ERROR);\r
+ }\r
\r
- if (!IsCompressed)\r
- image->copyTo(MipMap[0]);\r
- }\r
- else\r
+ //visual studio code warning\r
+ u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE;\r
+ core::dimension2d<u32> optSize( OriginalSize.getOptimalSize(\r
+ (Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo\r
+ false, // requireSquare\r
+ (Flags & ALLOW_NPOT) ? 1 : maxTexSize == 0, // larger\r
+ (Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue\r
+ )\r
+ );\r
+\r
+ if (OriginalSize == optSize)\r
+ {\r
+ MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());\r
+#if defined(IRRLICHT_sRGB)\r
+ MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() );\r
+#endif \r
+ if (!isCompressed)\r
+ image->copyTo(MipMap[0]);\r
+ }\r
+ else\r
+ {\r
+ char buf[256];\r
+ core::stringw showName ( name );\r
+ snprintf_irr ( buf, sizeof(buf), "Burningvideo: Warning Texture %ls reformat %ux%u,%d -> %ux%u,%d",\r
+ showName.c_str(),\r
+ OriginalSize.Width, OriginalSize.Height, OriginalColorFormat,\r
+ optSize.Width, optSize.Height,BURNINGSHADER_COLOR_FORMAT\r
+ );\r
+\r
+ os::Printer::log ( buf, ELL_WARNING );\r
+ MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);\r
+#if defined(IRRLICHT_sRGB)\r
+ MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() );\r
+#endif\r
+ if (!isCompressed)\r
{\r
- char buf[256];\r
- core::stringw showName ( name );\r
- snprintf_irr ( buf, 256, "Burningvideo: Warning Texture %ls reformat %dx%d -> %dx%d,%d",\r
- showName.c_str(),\r
- OriginalSize.Width, OriginalSize.Height, optSize.Width, optSize.Height,\r
- BURNINGSHADER_COLOR_FORMAT\r
- );\r
-\r
- OriginalSize = optSize;\r
- os::Printer::log ( buf, ELL_WARNING );\r
- MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);\r
-\r
- if (!IsCompressed)\r
- image->copyToScalingBoxFilter ( MipMap[0],0, false );\r
+ //image->copyToScalingBoxFilter ( MipMap[0],0, false );\r
+ Resample_subSampling(BLITTER_TEXTURE,MipMap[0],0,image,0, Flags);\r
}\r
-\r
- Size = MipMap[MipMapLOD]->getDimension();\r
- Pitch = MipMap[MipMapLOD]->getPitch();\r
-\r
- OrigImageDataSizeInPixels = (f32) 0.3f * MipMap[0]->getImageDataSizeInPixels();\r
-\r
- HasMipMaps = (Flags & GEN_MIPMAP) != 0;\r
-\r
- regenerateMipMapLevels(image->getMipMapsData());\r
+ // if Original Size is used for calculation ( 2D position, font) it will be wrong\r
+ //OriginalSize = optSize;\r
}\r
+\r
+ //select highest mipmap 0\r
+ regenerateMipMapLevels(image->getMipMapsData());\r
}\r
\r
\r
//! destructor\r
CSoftwareTexture2::~CSoftwareTexture2()\r
{\r
- for ( s32 i = 0; i!= SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )\r
+ for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )\r
{\r
if ( MipMap[i] )\r
+ {\r
MipMap[i]->drop();\r
+ MipMap[i] = 0;\r
+ }\r
}\r
}\r
\r
\r
+\r
//! Regenerates the mip map levels of the texture. Useful after locking and\r
//! modifying the texture\r
+#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)\r
+#else\r
+void CSoftwareTexture2::regenerateMipMapLevels(void* data)\r
+#endif\r
{\r
- if (!hasMipMaps())\r
- return;\r
-\r
- s32 i;\r
+ int i;\r
\r
// release\r
for ( i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )\r
{\r
if ( MipMap[i] )\r
+ {\r
MipMap[i]->drop();\r
+ MipMap[i] = 0;\r
+ }\r
}\r
\r
core::dimension2d<u32> newSize;\r
- core::dimension2d<u32> origSize = Size;\r
\r
- for (i=1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)\r
+ if (HasMipMaps && ( (Flags & GEN_MIPMAP_AUTO) || 0 == data ) )\r
{\r
- newSize = MipMap[i-1]->getDimension();\r
- newSize.Width = core::s32_max ( 1, newSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );\r
- newSize.Height = core::s32_max ( 1, newSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );\r
- origSize.Width = core::s32_max(1, origSize.Width >> 1);\r
- origSize.Height = core::s32_max(1, origSize.Height >> 1);\r
+ //need memory also if autogen mipmap disabled\r
+ for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)\r
+ {\r
+ const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();\r
+ //isotropic\r
+ newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);\r
+ newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);\r
+ if (upperDim == newSize)\r
+ break;\r
\r
- if (data)\r
+ MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);\r
+#if defined(IRRLICHT_sRGB)\r
+ MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB());\r
+#endif\r
+ //MipMap[i]->fill ( 0xFFFF4040 );\r
+ //MipMap[i-1]->copyToScalingBoxFilter( MipMap[i], 0, false );\r
+ Resample_subSampling(BLITTER_TEXTURE, MipMap[i], 0, MipMap[0], 0, Flags);\r
+ }\r
+ }\r
+ else if (HasMipMaps && data)\r
+ {\r
+ //deactivated outside mipdata until TA knows how to handle this.\r
+\r
+ //query mipmap dimension\r
+ u8* mip_current = (u8*)data;\r
+ const u8* mip_end = (u8*)data;\r
+\r
+ core::dimension2d<u32> origSize = OriginalSize;\r
+ i = 1;\r
+ do\r
{\r
- if (OriginalFormat != BURNINGSHADER_COLOR_FORMAT)\r
+ if (origSize.Width > 1) origSize.Width >>= 1;\r
+ if (origSize.Height > 1) origSize.Height >>= 1;\r
+ mip_end += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);\r
+ i += 1;\r
+ } while ((origSize.Width != 1 || origSize.Height != 1) && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX);\r
+\r
+ //TODO: this is not true\r
+ LodBIAS = i*0.75f;\r
+\r
+ origSize = OriginalSize;\r
+ for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX && mip_current < mip_end; ++i)\r
+ {\r
+ const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();\r
+ //isotropic\r
+ newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);\r
+ newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);\r
+ if (upperDim == newSize)\r
+ break;\r
+\r
+ if (origSize.Width > 1) origSize.Width >>= 1;\r
+ if (origSize.Height > 1) origSize.Height >>= 1;\r
+\r
+ if (OriginalColorFormat != BURNINGSHADER_COLOR_FORMAT)\r
{\r
- IImage* tmpImage = new CImage(OriginalFormat, origSize, data, true, false);\r
+ IImage* tmpImage = new CImage(OriginalColorFormat, origSize, mip_current, true, false);\r
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);\r
- if (origSize==newSize)\r
+ if (origSize == newSize)\r
tmpImage->copyTo(MipMap[i]);\r
else\r
tmpImage->copyToScalingBoxFilter(MipMap[i]);\r
}\r
else\r
{\r
- if (origSize==newSize)\r
- MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, data, false);\r
+ if (origSize == newSize)\r
+ MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mip_current, false);\r
else\r
{\r
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);\r
- IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, data, true, false);\r
+ IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mip_current, true, false);\r
tmpImage->copyToScalingBoxFilter(MipMap[i]);\r
tmpImage->drop();\r
}\r
}\r
- data = (u8*)data +origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8;\r
+ mip_current += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);\r
}\r
- else\r
+ }\r
+\r
+\r
+ //visualize mipmap\r
+ for (i=1; i < 0 && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)\r
+ {\r
+/*\r
+ static u32 color[] = { \r
+ 0x30bf7f00,0x3040bf00,0x30bf00bf,0x3000bf00,\r
+ 0x300080bf,0x30bf4000,0x300040bf,0x307f00bf,\r
+ 0x30bf0000,0x3000bfbf,0x304000bf,0x307fbf00,\r
+ 0x8000bf7f,0x80bf0040,0x80bfbf00,0x800000bf\r
+ };\r
+*/\r
+ static u32 color[] = { \r
+ 0xFFFFFFFF,0xFFFF0000,0xFF00FF00,0xFF0000FF,\r
+ 0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,0xFF0000FF,\r
+ 0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFF0000FF,\r
+ 0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFFFF00FF\r
+ };\r
+\r
+ if ( MipMap[i] )\r
{\r
- MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);\r
+ core::rect<s32> p (core::position2di(0,0),MipMap[i]->getDimension());\r
+ SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000);\r
+ Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], 0, 0, MipMap[i], &p, c.color);\r
+ }\r
+ }\r
\r
- //static u32 color[] = { 0, 0xFFFF0000, 0xFF00FF00,0xFF0000FF,0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0xFF0F0F0F };\r
- MipMap[i]->fill ( 0 );\r
- MipMap[0]->copyToScalingBoxFilter( MipMap[i], 0, false );\r
+ //save mipmap chain\r
+ if ( 0 )\r
+ {\r
+ char buf[256];\r
+ const char* name = getName().getPath().c_str();\r
+ int filename = 0;\r
+ //int ext = -1;\r
+ i = 0;\r
+ while (name[i])\r
+ {\r
+ if (name[i] == '/' || name[i] == '\\') filename = i + 1;\r
+ //if (name[i] == '.') ext = i;\r
+ i += 1;\r
+ }\r
+ for (i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)\r
+ {\r
+ if (MipMap[i])\r
+ {\r
+ snprintf_irr(buf, sizeof(buf),"mip/%s_%02d.png", name + filename,i);\r
+ Driver->writeImageToFile(MipMap[i], buf);\r
+ }\r
}\r
}\r
+\r
+ calcDerivative();\r
+}\r
+\r
+void CSoftwareTexture2::calcDerivative()\r
+{\r
+ //reset current MipMap\r
+ MipMapLOD = 0;\r
+ if (MipMap[0])\r
+ {\r
+ const core::dimension2du& dim = MipMap[0]->getDimension();\r
+ MipMap0_Area[0] = dim.Width;\r
+ MipMap0_Area[1] = dim.Height; // screensize of a triangle\r
+\r
+ Size = dim; // MipMap[MipMapLOD]->getDimension();\r
+ Pitch = MipMap[MipMapLOD]->getPitch();\r
+ }\r
+\r
+ //preCalc mipmap texel center boundaries\r
+ for ( s32 i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )\r
+ {\r
+ CSoftwareTexture2_Bound& b = TexBound[i];\r
+ if (MipMap[i])\r
+ {\r
+ const core::dimension2du& dim = MipMap[i]->getDimension();\r
+ //f32 u = 1.f / dim.Width;\r
+ //f32 v = 1.f / dim.Height;\r
+\r
+ b.w = dim.Width - 1.f;\r
+ b.h = dim.Height - 1.f;\r
+ b.cx = 0.f; //u*0.005f;\r
+ b.cy = 0.f; //v*0.005f;\r
+ }\r
+ else\r
+ {\r
+ b.w = 0.f;\r
+ b.h = 0.f;\r
+ b.cx = 0.f;\r
+ b.cy = 0.f;\r
+ }\r
+ }\r
+\r
}\r
\r
\r
/* Software Render Target 2 */\r
\r
CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver)\r
+#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
+, IRenderTarget(0)\r
+#endif\r
{\r
DriverType = EDT_BURNINGSVIDEO;\r
\r
}\r
\r
\r
+\r
+static const float srgb_8bit_to_linear_float[1 << 8] = {\r
+ 0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f,\r
+ 0.001214108f, 0.001517635f, 0.001821162f, 0.0021246888f,\r
+ 0.002428216f, 0.002731743f, 0.00303527f, 0.0033465358f,\r
+ 0.0036765074f, 0.004024717f, 0.004391442f, 0.0047769537f,\r
+ 0.005181517f, 0.005605392f, 0.0060488335f, 0.006512091f,\r
+ 0.0069954107f, 0.007499032f, 0.008023193f, 0.008568126f,\r
+ 0.009134059f, 0.009721218f, 0.010329823f, 0.010960095f,\r
+ 0.011612245f, 0.012286489f, 0.0129830325f, 0.013702083f,\r
+ 0.014443845f, 0.015208516f, 0.015996294f, 0.016807377f,\r
+ 0.017641956f, 0.018500222f, 0.019382363f, 0.020288564f,\r
+ 0.021219011f, 0.022173885f, 0.023153368f, 0.024157634f,\r
+ 0.025186861f, 0.026241222f, 0.027320893f, 0.02842604f,\r
+ 0.029556835f, 0.030713445f, 0.031896032f, 0.033104766f,\r
+ 0.034339808f, 0.035601314f, 0.036889452f, 0.038204372f,\r
+ 0.039546236f, 0.0409152f, 0.04231141f, 0.04373503f,\r
+ 0.045186203f, 0.046665087f, 0.048171826f, 0.049706567f,\r
+ 0.051269464f, 0.05286065f, 0.05448028f, 0.056128494f,\r
+ 0.057805438f, 0.059511244f, 0.06124606f, 0.06301002f,\r
+ 0.06480327f, 0.066625945f, 0.068478175f, 0.0703601f,\r
+ 0.07227185f, 0.07421357f, 0.07618539f, 0.07818743f,\r
+ 0.08021983f, 0.082282715f, 0.084376216f, 0.086500466f,\r
+ 0.08865559f, 0.09084172f, 0.093058966f, 0.09530747f,\r
+ 0.097587354f, 0.09989873f, 0.10224174f, 0.10461649f,\r
+ 0.107023105f, 0.10946172f, 0.111932434f, 0.11443538f,\r
+ 0.11697067f, 0.119538434f, 0.122138776f, 0.12477182f,\r
+ 0.12743768f, 0.13013647f, 0.13286832f, 0.13563333f,\r
+ 0.13843162f, 0.14126329f, 0.14412847f, 0.14702727f,\r
+ 0.14995979f, 0.15292616f, 0.15592647f, 0.15896083f,\r
+ 0.16202939f, 0.1651322f, 0.1682694f, 0.17144111f,\r
+ 0.1746474f, 0.17788842f, 0.18116425f, 0.18447499f,\r
+ 0.18782078f, 0.19120169f, 0.19461784f, 0.19806932f,\r
+ 0.20155625f, 0.20507874f, 0.20863687f, 0.21223076f,\r
+ 0.21586053f, 0.21952623f, 0.22322798f, 0.2269659f,\r
+ 0.23074007f, 0.23455061f, 0.2383976f, 0.24228115f,\r
+ 0.24620135f, 0.2501583f, 0.25415212f, 0.25818288f,\r
+ 0.2622507f, 0.26635563f, 0.27049783f, 0.27467734f,\r
+ 0.2788943f, 0.28314877f, 0.28744087f, 0.29177067f,\r
+ 0.2961383f, 0.3005438f, 0.30498734f, 0.30946895f,\r
+ 0.31398875f, 0.3185468f, 0.32314324f, 0.32777813f,\r
+ 0.33245155f, 0.33716366f, 0.34191445f, 0.3467041f,\r
+ 0.35153264f, 0.35640016f, 0.36130682f, 0.36625263f,\r
+ 0.3712377f, 0.37626216f, 0.38132605f, 0.38642946f,\r
+ 0.3915725f, 0.39675525f, 0.4019778f, 0.40724024f,\r
+ 0.41254264f, 0.4178851f, 0.4232677f, 0.42869052f,\r
+ 0.43415368f, 0.4396572f, 0.44520122f, 0.45078582f,\r
+ 0.45641103f, 0.46207702f, 0.4677838f, 0.4735315f,\r
+ 0.4793202f, 0.48514995f, 0.4910209f, 0.496933f,\r
+ 0.5028865f, 0.50888133f, 0.5149177f, 0.5209956f,\r
+ 0.52711517f, 0.53327644f, 0.5394795f, 0.5457245f,\r
+ 0.55201143f, 0.55834043f, 0.5647115f, 0.57112485f,\r
+ 0.57758045f, 0.58407843f, 0.59061885f, 0.5972018f,\r
+ 0.60382736f, 0.61049557f, 0.6172066f, 0.62396044f,\r
+ 0.63075715f, 0.6375969f, 0.6444797f, 0.65140563f,\r
+ 0.65837485f, 0.66538733f, 0.67244315f, 0.6795425f,\r
+ 0.6866853f, 0.6938718f, 0.7011019f, 0.7083758f,\r
+ 0.71569353f, 0.7230551f, 0.73046076f, 0.73791045f,\r
+ 0.74540424f, 0.7529422f, 0.7605245f, 0.76815116f,\r
+ 0.7758222f, 0.7835378f, 0.791298f, 0.7991027f,\r
+ 0.8069523f, 0.8148466f, 0.82278574f, 0.8307699f,\r
+ 0.838799f, 0.8468732f, 0.8549926f, 0.8631572f,\r
+ 0.8713671f, 0.8796224f, 0.8879231f, 0.8962694f,\r
+ 0.9046612f, 0.91309863f, 0.92158186f, 0.9301109f,\r
+ 0.9386857f, 0.9473065f, 0.9559733f, 0.9646863f,\r
+ 0.9734453f, 0.9822506f, 0.9911021f, 1.0f,\r
+};\r
+/*\r
+int linear_to_srgb_8bit(const float x) {\r
+ if (x <= 0.f) return 0;\r
+ if (x >= 1.f) return 255;\r
+ const float *table = SRGB_8BIT_TO_LINEAR_FLOAT;\r
+ int y = 0;\r
+ for (int i = 128; i != 0; i >>= 1) {\r
+ if (table[y + i] <= x)\r
+ y += i;\r
+ }\r
+ if (x - table[y] <= table[y + 1] - x)\r
+ return y;\r
+ else\r
+ return y + 1;\r
+}\r
+*/\r
+\r
+\r
+u32 linear_to_srgb_8bit(const float v)\r
+{\r
+ ieee754 c;\r
+ c.f = v;\r
+ const register size_t x = c.u;\r
+ const u32 *table = (u32*)srgb_8bit_to_linear_float;\r
+ register u32 y = 0;\r
+ y += table[y + 128] <= x ? 128 : 0;\r
+ y += table[y + 64] <= x ? 64 : 0;\r
+ y += table[y + 32] <= x ? 32 : 0;\r
+ y += table[y + 16] <= x ? 16 : 0;\r
+ y += table[y + 8] <= x ? 8 : 0;\r
+ y += table[y + 4] <= x ? 4 : 0;\r
+ y += table[y + 2] <= x ? 2 : 0;\r
+ y += table[y + 1] <= x ? 1 : 0;\r
+\r
+ return y;\r
+}\r
+\r
+// 2D Region half open [x0;x1[\r
+struct absrect2\r
+{\r
+ s32 x0;\r
+ s32 y0;\r
+ s32 x1;\r
+ s32 y1;\r
+};\r
+\r
+static inline int clipTest(absrect2 &o, const core::rect<s32>* a, const absrect2& b)\r
+{\r
+ if (a == 0)\r
+ {\r
+ o.x0 = b.x0;\r
+ o.y0 = b.y0;\r
+ o.x1 = b.x1;\r
+ o.y1 = b.y1;\r
+ }\r
+ else\r
+ {\r
+ o.x0 = core::s32_max(a->UpperLeftCorner.X, b.x0);\r
+ o.x1 = core::s32_min(a->LowerRightCorner.X, b.x1);\r
+ o.y0 = core::s32_max(a->UpperLeftCorner.Y, b.y0);\r
+ o.y1 = core::s32_min(a->LowerRightCorner.Y, b.y1);\r
+ }\r
+ int clipTest = 0;\r
+ clipTest |= o.x0 >= o.x1 ? 1 : 0;\r
+ clipTest |= o.y0 >= o.y1 ? 2 : 0;\r
+ return clipTest;\r
+}\r
+\r
+//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)\r
+// todo: texture jumps (mip selection problem)\r
+void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect,\r
+ const video::IImage* src, const core::rect<s32>* srcRect,size_t flags)\r
+{\r
+ const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height };\r
+ absrect2 dc;\r
+ if (clipTest(dc, dstRect, dst_clip)) return;\r
+ const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat();\r
+ u8* dstData = (u8*)dst->getData();\r
+\r
+ const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height };\r
+ absrect2 sc;\r
+ if (clipTest(sc, srcRect, src_clip)) return;\r
+ const video::ECOLOR_FORMAT srcFormat = src->getColorFormat();\r
+ const u8* srcData = (u8*)src->getData();\r
+\r
+#if defined(IRRLICHT_sRGB)\r
+ const int dst_sRGB = dst->get_sRGB();\r
+ const int src_sRGB = src->get_sRGB();\r
+#else\r
+ const int dst_sRGB = (flags & CSoftwareTexture2::TEXTURE_IS_LINEAR) ? 0 : 1;\r
+ const int src_sRGB = (flags & CSoftwareTexture2::IMAGE_IS_LINEAR) ? 0 : 1;\r
+#endif\r
+\r
+\r
+\r
+ float scale[2];\r
+ scale[0] = (float)(sc.x1 - sc.x0) / (float)(dc.x1 - dc.x0);\r
+ scale[1] = (float)(sc.y1 - sc.y0) / (float)(dc.y1 - dc.y0);\r
+ const float rs = 1.f / (scale[0] * scale[1]);\r
+\r
+ float sum[4];\r
+ u32 sbgra = 0;\r
+\r
+ float f[4];\r
+ int fi[4];\r
+ f[3] = (float)sc.y0;\r
+ for (int dy = dc.y0; dy < dc.y1; ++dy)\r
+ {\r
+ f[1] = f[3];\r
+ f[3] = sc.y0 + (dy + 1 - dc.y0)*scale[1];\r
+ if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough\r
+\r
+ f[2] = (float)sc.x0;\r
+ for (int dx = dc.x0; dx < dc.x1; ++dx)\r
+ {\r
+ f[0] = f[2];\r
+ f[2] = sc.x0 + (dx + 1 - dc.x0)*scale[0];\r
+ if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f;\r
+\r
+ //accumulate linear color\r
+ sum[0] = 0.f;\r
+ sum[1] = 0.f;\r
+ sum[2] = 0.f;\r
+ sum[3] = 0.f;\r
+\r
+ //sample border\r
+ fi[0] = (int)(f[0]);\r
+ fi[1] = (int)(f[1]);\r
+ fi[2] = (int)(f[2]);\r
+ fi[3] = (int)(f[3]);\r
+\r
+ float w[2];\r
+ for (int fy = fi[1]; fy <= fi[3]; ++fy)\r
+ {\r
+ w[1] = 1.f;\r
+ if (fy == fi[1]) w[1] -= f[1] - fy;\r
+ if (fy == fi[3]) w[1] -= fy + 1 - f[3];\r
+\r
+ for (int fx = fi[0]; fx <= fi[2]; ++fx)\r
+ {\r
+ w[0] = 1.f;\r
+ if (fx == fi[0]) w[0] -= f[0] - fx;\r
+ if (fx == fi[2]) w[0] -= fx + 1 - f[2];\r
+\r
+ const float ws = w[1] * w[0] * rs;\r
+\r
+ switch (srcFormat)\r
+ {\r
+ case video::ECF_A1R5G5B5: sbgra = video::A1R5G5B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break;\r
+ case video::ECF_R5G6B5: sbgra = video::R5G6B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break;\r
+ case video::ECF_A8R8G8B8: sbgra = *(u32*)(srcData + (fy*src_clip.x1) * 4 + (fx * 4)); break;\r
+ case video::ECF_R8G8B8:\r
+ {\r
+ const u8* p = srcData + (fy*src_clip.x1) * 3 + (fx * 3);\r
+ sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2];\r
+ } break;\r
+ default: break;\r
+ }\r
+ if (src_sRGB)\r
+ {\r
+ sum[0] += srgb_8bit_to_linear_float[(sbgra) & 0xFF] * ws;\r
+ sum[1] += srgb_8bit_to_linear_float[(sbgra >> 8) & 0xFF] * ws;\r
+ sum[2] += srgb_8bit_to_linear_float[(sbgra >> 16) & 0xFF] * ws;\r
+ sum[3] += ((sbgra >> 24) & 0xFF) * ws;\r
+ }\r
+ else\r
+ {\r
+ sum[0] += ((sbgra) & 0xFF) * ws;\r
+ sum[1] += ((sbgra >> 8) & 0xFF) * ws;\r
+ sum[2] += ((sbgra >> 16) & 0xFF) * ws;\r
+ sum[3] += ((sbgra >> 24) & 0xFF) * ws;\r
+ }\r
+\r
+ }\r
+ }\r
+ switch (op)\r
+ {\r
+ case BLITTER_TEXTURE_ALPHA_BLEND:\r
+ case BLITTER_TEXTURE_ALPHA_COLOR_BLEND:\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ if (dst_sRGB)\r
+ {\r
+ sbgra = linear_to_srgb_8bit(sum[0]) |\r
+ linear_to_srgb_8bit(sum[1]) << 8 |\r
+ linear_to_srgb_8bit(sum[2]) << 16 |\r
+ (u32)(sum[3]) << 24;\r
+ }\r
+ else\r
+ {\r
+ sbgra = (u32)(sum[0]) |\r
+ (u32)(sum[1]) << 8 |\r
+ (u32)(sum[2]) << 16 |\r
+ (u32)(sum[3]) << 24;\r
+ }\r
+ switch (dstFormat)\r
+ {\r
+ case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy*dst_clip.x1) * 4 + (dx * 4)) = sbgra; break;\r
+ case video::ECF_R8G8B8:\r
+ {\r
+ u8* p = dstData + (dy*dst_clip.x1) * 3 + (dx * 3);\r
+ p[2] = (sbgra) & 0xFF;\r
+ p[1] = (sbgra >> 8) & 0xFF;\r
+ p[0] = (sbgra >> 16) & 0xFF;\r
+ } break;\r
+ case video::ECF_A1R5G5B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toA1R5G5B5(sbgra); break;\r
+ case video::ECF_R5G6B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toR5G6B5(sbgra); break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+}\r
+\r
} // end namespace video\r
} // end namespace irr\r
\r
/*!\r
interface for a Video Driver dependent Texture.\r
*/\r
+struct CSoftwareTexture2_Bound\r
+{\r
+ f32 w; // width - 0.5f;\r
+ f32 h; // height- 0.5f;\r
+ f32 cx; // texelcenter x 1.f/width*0.5f\r
+ f32 cy; // texelcenter y 1.f/height*0.5f\r
+};\r
+\r
class CSoftwareTexture2 : public ITexture\r
{\r
public:\r
//! constructor\r
enum eTex2Flags\r
{\r
- GEN_MIPMAP = 1,\r
- IS_RENDERTARGET = 2,\r
- NP2_SIZE = 4,\r
+ GEN_MIPMAP = 1, // has mipmaps\r
+ GEN_MIPMAP_AUTO = 2, // automatic mipmap generation\r
+ IS_RENDERTARGET = 4,\r
+ ALLOW_NPOT = 8, //allow non power of two\r
+ IMAGE_IS_LINEAR = 16,\r
+ TEXTURE_IS_LINEAR = 32,\r
};\r
- CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags);\r
+ CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags /*eTex2Flags*/, CBurningVideoDriver* driver);\r
\r
//! destructor\r
virtual ~CSoftwareTexture2();\r
\r
+ u32 getMipmapLevel(s32 newLevel) const\r
+ {\r
+ if ( newLevel < 0 ) newLevel = 0;\r
+ else if ( newLevel >= SOFTWARE_DRIVER_2_MIPMAPPING_MAX ) newLevel = SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1;\r
+\r
+ while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1;\r
+ return newLevel;\r
+ }\r
+\r
//! lock function\r
virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_\r
{\r
if (Flags & GEN_MIPMAP)\r
{\r
- MipMapLOD = mipmapLevel;\r
+ //called from outside. must test\r
+ MipMapLOD = getMipmapLevel(mipmapLevel);\r
Size = MipMap[MipMapLOD]->getDimension();\r
Pitch = MipMap[MipMapLOD]->getPitch();\r
}\r
{\r
}\r
\r
- //! Returns the size of the largest mipmap.\r
+ //! compare the area drawn with the area of the texture\r
f32 getLODFactor( const f32 texArea ) const\r
{\r
- return OrigImageDataSizeInPixels * texArea;\r
+ return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea;\r
//return MipMap[0]->getImageDataSizeInPixels () * texArea;\r
}\r
\r
- //! returns unoptimized surface\r
+ const u32* getMipMap0_Area() const\r
+ {\r
+ return MipMap0_Area;\r
+ }\r
+\r
+ //! returns unoptimized surface (misleading name. burning can scale down originalimage)\r
virtual CImage* getImage() const\r
{\r
return MipMap[0];\r
return MipMap[MipMapLOD];\r
}\r
\r
+ //precalculated dimx-1/dimx*0.5f\r
+ const CSoftwareTexture2_Bound& getTexBound() const\r
+ {\r
+ return TexBound[MipMapLOD];\r
+ }\r
+\r
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;\r
\r
+ f32 get_lod_bias() const { return LodBIAS; }\r
private:\r
- f32 OrigImageDataSizeInPixels;\r
+ void calcDerivative();\r
\r
- CImage * MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];\r
+ //! controls MipmapSelection. relation between drawn area and image size\r
+ u32 MipMapLOD; // 0 .. original Texture pot -SOFTWARE_DRIVER_2_MIPMAPPING_MAX\r
+ u32 Flags; //eTex2Flags\r
+ CBurningVideoDriver* Driver;\r
\r
- u32 MipMapLOD;\r
- u32 Flags;\r
- ECOLOR_FORMAT OriginalFormat;\r
+ CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];\r
+ CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];\r
+ u32 MipMap0_Area[2];\r
+ f32 LodBIAS;\r
};\r
\r
/*!\r
CBurningVideoDriver* Driver;\r
};\r
\r
-\r
} // end namespace video\r
} // end namespace irr\r
\r
-#endif\r
+#endif // __C_SOFTWARE_2_TEXTURE_H_INCLUDED__\r
+\r
\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRGouraud2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle (const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ //virtual bool canWireFrame () { return true; }\r
\r
-\r
-private:\r
- void scanline_bilinear ();\r
- sScanConvertData scan;\r
- sScanLineData line;\r
+protected:\r
+ virtual void scanline_bilinear ();\r
\r
};\r
\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
#ifdef IPOL_C0\r
tFixPoint r0, g0, b0;\r
\r
-#ifdef INVERSE_W\r
- f32 inversew;\r
-#endif\r
+ f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;\r
\r
#endif\r
\r
for ( s32 i = 0; i <= dx; ++i )\r
{\r
+ //if test active only first pixel\r
+ if ( (0 == EdgeTestPass) & i ) break;\r
#ifdef CMP_Z\r
if ( line.z[0] < z[i] )\r
#endif\r
#ifdef CMP_W\r
- if ( line.w[0] >= z[i] )\r
+ if (line.w[0] >= z[i] )\r
#endif\r
\r
{\r
#ifdef IPOL_C0\r
-#ifdef INVERSE_W\r
- inversew = core::reciprocal ( line.w[0] );\r
\r
- getSample_color ( r0, g0, b0, line.c[0][0] * inversew );\r
-#else\r
- getSample_color ( r0, g0, b0, line.c[0][0] );\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32_color(line.w[0]);\r
#endif\r
-\r
- dst[i] = fix_to_color ( r0, g0, b0 );\r
+ vec4_to_fix( r0, g0, b0, line.c[0][0],inversew );\r
+ dst[i] = fix_to_sample( r0, g0, b0 );\r
#else\r
- dst[i] = COLOR_BRIGHT_WHITE;\r
+ dst[i] = PrimitiveColor;\r
#endif\r
\r
#ifdef WRITE_Z\r
\r
}\r
\r
-void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
\r
+ scan.invDeltaY[0] = reciprocal_edge( ca );\r
+ scan.invDeltaY[1] = reciprocal_edge( ba );\r
+ scan.invDeltaY[2] = reciprocal_edge( cb );\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
\r
// render a scanline\r
scanline_bilinear ();\r
+ if ( EdgeTestPass & edge_test_first_line ) break;\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
}\r
\r
// rasterize lower sub-triangle\r
- if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+ if ( (f32) 0.0 != scan.invDeltaY[2] )\r
{\r
// advance to middle point\r
if( (f32) 0.0 != scan.invDeltaY[1] )\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
\r
// render a scanline\r
scanline_bilinear ();\r
+ if ( EdgeTestPass & edge_test_first_line ) break;\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
//! creates a flat triangle renderer\r
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver)\r
{\r
+ // ETR_GOURAUD . no texture\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRGouraud2(driver);\r
#else\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRGouraudAlpha2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c ) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear ();\r
\r
- sScanConvertData scan;\r
- sScanLineData line;\r
-\r
};\r
\r
//! constructor\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
#ifdef IPOL_C0\r
\r
-#ifdef INVERSE_W\r
- f32 inversew;\r
-#endif\r
+ f32 inversew = FIX_POINT_F32_MUL;\r
\r
tFixPoint a0;\r
tFixPoint r0, g0, b0;\r
{\r
#ifdef IPOL_C0\r
#ifdef INVERSE_W\r
- inversew = core::reciprocal ( line.w[0] );\r
-\r
- getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );\r
-#else\r
- getSample_color ( a0, r0, g0, b0, line.c[0][0] );\r
+ inversew = reciprocal_zero_no ( line.w[0] );\r
#endif\r
+ vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
+ fix_color_norm(a0);\r
r2 = r1 + imulFix ( a0, r0 - r1 );\r
g2 = g1 + imulFix ( a0, g0 - g1 );\r
b2 = b1 + imulFix ( a0, b0 - b1 );\r
\r
- dst[i] = fix_to_color ( r2, g2, b2 );\r
+ dst[i] = fix4_to_sample( a0,r2, g2, b2 );\r
#else\r
- dst[i] = COLOR_BRIGHT_WHITE;\r
+ dst[i] = PrimitiveColor;\r
#endif\r
#ifdef WRITE_Z\r
z[i] = line.z[0];\r
\r
}\r
\r
-void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver)\r
{\r
+ // ETR_GOURAUD_ALPHA unused\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRGouraudAlpha2(driver);\r
#else\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle (const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear ();\r
- sScanConvertData scan;\r
- sScanLineData line;\r
-\r
};\r
\r
//! constructor\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
\r
\r
+ f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;\r
+\r
#ifdef IPOL_C0\r
\r
-#ifdef INVERSE_W\r
- f32 inversew;\r
-#endif\r
\r
tFixPoint a0;\r
tFixPoint r0, g0, b0;\r
\r
#ifdef IPOL_C0\r
#ifdef IPOL_W\r
- inversew = core::reciprocal ( line.w[0] );\r
-\r
- getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );\r
-#else\r
- getSample_color ( a0, r0, g0, b0, line.c[0][0] );\r
+ inversew = fix_inverse32_color(line.w[0]);\r
#endif\r
\r
+ vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );\r
+\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
+ fix_color_norm(a0);\r
r2 = r1 + imulFix ( a0, r0 - r1 );\r
g2 = g1 + imulFix ( a0, g0 - g1 );\r
b2 = b1 + imulFix ( a0, b0 - b1 );\r
\r
- dst[i] = fix_to_color ( r2, g2, b2 );\r
+ dst[i] = fix_to_sample( r2, g2, b2 );\r
#else\r
- dst[i] = COLOR_BRIGHT_WHITE;\r
+ dst[i] = PrimitiveColor;\r
#endif\r
\r
\r
\r
}\r
\r
-void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)\r
{\r
+ //ETR_GOURAUD_ALPHA_NOZ - draw2DRectangle Gradient\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRGouraudAlphaNoZ2(driver);\r
#else\r
--- /dev/null
+// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten\r
+// This file is part of the "Irrlicht Engine".\r
+// For conditions of distribution and use, see copyright notice in irrlicht.h\r
+\r
+#include "IrrCompileConfig.h"\r
+#include "IBurningShader.h"\r
+\r
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+// compile flag for this file\r
+#undef USE_ZBUFFER\r
+#undef IPOL_Z\r
+#undef CMP_Z\r
+#undef WRITE_Z\r
+\r
+#undef IPOL_W\r
+#undef CMP_W\r
+#undef WRITE_W\r
+\r
+#undef SUBTEXEL\r
+#undef INVERSE_W\r
+\r
+#undef IPOL_C0\r
+#undef IPOL_T0\r
+#undef IPOL_T1\r
+\r
+// define render case\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+\r
+#define USE_ZBUFFER\r
+#define IPOL_W\r
+//#define CMP_W\r
+//#define WRITE_W\r
+\r
+#define IPOL_C0\r
+//#define IPOL_T0\r
+//#define IPOL_T1\r
+\r
+// apply global override\r
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+ #undef INVERSE_W\r
+#endif\r
+\r
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL\r
+ #undef SUBTEXEL\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+ #undef IPOL_C0\r
+#endif\r
+\r
+#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
+ #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+ #undef IPOL_W\r
+ #endif\r
+ #define IPOL_Z\r
+\r
+ #ifdef CMP_W\r
+ #undef CMP_W\r
+ #define CMP_Z\r
+ #endif\r
+\r
+ #ifdef WRITE_W\r
+ #undef WRITE_W\r
+ #define WRITE_Z\r
+ #endif\r
+\r
+#endif\r
+\r
+\r
+namespace irr\r
+{\r
+\r
+namespace video\r
+{\r
+\r
+class CTRGouraudNoZ2 : public IBurningShader\r
+{\r
+public:\r
+\r
+ //! constructor\r
+ CTRGouraudNoZ2(CBurningVideoDriver* driver);\r
+\r
+ //! draws an indexed triangle list\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual bool canWireFrame () { return true; }\r
+\r
+protected:\r
+ virtual void scanline_bilinear ();\r
+};\r
+\r
+//! constructor\r
+CTRGouraudNoZ2::CTRGouraudNoZ2(CBurningVideoDriver* driver)\r
+: IBurningShader(driver)\r
+{\r
+ #ifdef _DEBUG\r
+ setDebugName("CTRGouraudNoZ2");\r
+ #endif\r
+}\r
+\r
+\r
+\r
+/*!\r
+*/\r
+void CTRGouraudNoZ2::scanline_bilinear ()\r
+{\r
+ tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+ //fp24 *z;\r
+#endif\r
+\r
+ s32 xStart;\r
+ s32 xEnd;\r
+ s32 dx;\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+ f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ sVec4 slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+ // apply top-left fill-convention, left\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
+\r
+ dx = xEnd - xStart;\r
+\r
+ if ( dx < 0 )\r
+ return;\r
+\r
+ // slopes\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
+\r
+#ifdef IPOL_Z\r
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+ slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ( (f32) xStart ) - line.x[0];\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+ dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+ //z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+#endif\r
+\r
+\r
+\r
+#ifdef IPOL_C0\r
+ tFixPoint r0, g0, b0;\r
+\r
+ f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;\r
+\r
+#endif\r
+\r
+ for ( s32 i = 0; i <= dx; ++i )\r
+ {\r
+ if ( (0 == EdgeTestPass) & i ) break;\r
+\r
+#ifdef CMP_Z\r
+ if ( line.z[0] < z[i] )\r
+#endif\r
+#ifdef CMP_W\r
+ if (line.w[0] >= z[i] )\r
+#endif\r
+\r
+ {\r
+#ifdef IPOL_C0\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32_color(line.w[0]);\r
+#endif\r
+ vec4_to_fix(r0, g0, b0, line.c[0][0], inversew);\r
+ dst[i] = fix_to_sample(r0, g0, b0);\r
+#else\r
+ dst[i] = PrimitiveColor;\r
+#endif\r
+\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+#endif\r
+\r
+ }\r
+\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1];\r
+#endif\r
+ }\r
+\r
+}\r
+\r
+void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
+{\r
+ // sort on height, y\r
+ if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);\r
+ if ( a->Pos.y > c->Pos.y ) swapVertexPointer(&a, &c);\r
+ if ( b->Pos.y > c->Pos.y ) swapVertexPointer(&b, &c);\r
+\r
+ const f32 ca = c->Pos.y - a->Pos.y;\r
+ const f32 ba = b->Pos.y - a->Pos.y;\r
+ const f32 cb = c->Pos.y - b->Pos.y;\r
+\r
+ // calculate delta y of the edges\r
+ scan.invDeltaY[0] = reciprocal_edge( ca );\r
+ scan.invDeltaY[1] = reciprocal_edge( ba );\r
+ scan.invDeltaY[2] = reciprocal_edge( cb );\r
+\r
+ if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
+ return;\r
+\r
+ // find if the major edge is left or right aligned\r
+ f32 temp[4];\r
+\r
+ temp[0] = a->Pos.x - c->Pos.x;\r
+ temp[1] = -ca;\r
+ temp[2] = b->Pos.x - a->Pos.x;\r
+ temp[3] = ba;\r
+\r
+ scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;\r
+ scan.right = 1 - scan.left;\r
+\r
+ // calculate slopes for the major edge\r
+ scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];\r
+ scan.x[0] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];\r
+ scan.z[0] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];\r
+ scan.w[0] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
+ scan.c[0][0] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
+ scan.t[0][0] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];\r
+ scan.t[1][0] = a->Tex[1];\r
+#endif\r
+\r
+ // top left fill convention y run\r
+ s32 yStart;\r
+ s32 yEnd;\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+\r
+ // rasterize upper sub-triangle\r
+ if ( (f32) 0.0 != scan.invDeltaY[1] )\r
+ {\r
+ // calculate slopes for top edge\r
+ scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
+ scan.x[1] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];\r
+ scan.z[1] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];\r
+ scan.w[1] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
+ scan.c[0][1] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
+ scan.t[0][1] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];\r
+ scan.t[1][1] = a->Tex[1];\r
+#endif\r
+\r
+ // apply top-left fill convention, top part\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ( (f32) yStart ) - a->Pos.y;\r
+\r
+ // correct to pixel center\r
+ scan.x[0] += scan.slopeX[0] * subPixel;\r
+ scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0] * subPixel;\r
+ scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0] * subPixel;\r
+ scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+ // rasterize the edge scanlines\r
+ for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+ {\r
+ line.x[scan.left] = scan.x[0];\r
+ line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+ line.z[scan.left] = scan.z[0];\r
+ line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ line.w[scan.left] = scan.w[0];\r
+ line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ line.c[0][scan.left] = scan.c[0][0];\r
+ line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ line.t[0][scan.left] = scan.t[0][0];\r
+ line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ line.t[1][scan.left] = scan.t[1][0];\r
+ line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+ // render a scanline\r
+ scanline_bilinear ();\r
+ if ( EdgeTestPass & edge_test_first_line ) break;\r
+\r
+ scan.x[0] += scan.slopeX[0];\r
+ scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0];\r
+ scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0];\r
+ scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0];\r
+ scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0];\r
+ scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0];\r
+ scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+ }\r
+ }\r
+\r
+ // rasterize lower sub-triangle\r
+ if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+ {\r
+ // advance to middle point\r
+ if( (f32) 0.0 != scan.invDeltaY[1] )\r
+ {\r
+ temp[0] = b->Pos.y - a->Pos.y; // dy\r
+\r
+ scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];\r
+#ifdef IPOL_Z\r
+ scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_W\r
+ scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];\r
+#endif\r
+\r
+ }\r
+\r
+ // calculate slopes for bottom edge\r
+ scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];\r
+ scan.x[1] = b->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];\r
+ scan.z[1] = b->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];\r
+ scan.w[1] = b->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
+ scan.c[0][1] = b->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
+ scan.t[0][1] = b->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];\r
+ scan.t[1][1] = b->Tex[1];\r
+#endif\r
+\r
+ // apply top-left fill convention, top part\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
+\r
+#ifdef SUBTEXEL\r
+\r
+ subPixel = ( (f32) yStart ) - b->Pos.y;\r
+\r
+ // correct to pixel center\r
+ scan.x[0] += scan.slopeX[0] * subPixel;\r
+ scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0] * subPixel;\r
+ scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0] * subPixel;\r
+ scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+ // rasterize the edge scanlines\r
+ for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+ {\r
+ line.x[scan.left] = scan.x[0];\r
+ line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+ line.z[scan.left] = scan.z[0];\r
+ line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ line.w[scan.left] = scan.w[0];\r
+ line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ line.c[0][scan.left] = scan.c[0][0];\r
+ line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ line.t[0][scan.left] = scan.t[0][0];\r
+ line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ line.t[1][scan.left] = scan.t[1][0];\r
+ line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+ // render a scanline\r
+ scanline_bilinear ();\r
+ if ( EdgeTestPass & edge_test_first_line ) break;\r
+\r
+ scan.x[0] += scan.slopeX[0];\r
+ scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0];\r
+ scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0];\r
+ scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0];\r
+ scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0];\r
+ scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0];\r
+ scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+\r
+ }\r
+ }\r
+\r
+}\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+namespace irr\r
+{\r
+namespace video\r
+{\r
+\r
+//! creates a flat triangle renderer\r
+IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver)\r
+{\r
+ //ETR_GOURAUD_NOZ - no texture no depth test no depth write\r
+ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+ return new CTRGouraudNoZ2(driver);\r
+ #else\r
+ return 0;\r
+ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+}\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+\r
+\r
#undef INVERSE_W\r
\r
#undef IPOL_C0\r
+#undef IPOL_C1\r
#undef IPOL_T0\r
#undef IPOL_T1\r
#undef IPOL_T2\r
#define WRITE_W\r
\r
#define IPOL_C0\r
+#define IPOL_C1\r
#define IPOL_T0\r
#define IPOL_T1\r
#define IPOL_L0\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
+#if BURNING_MATERIAL_MAX_COLORS < 2\r
+ #undef IPOL_C1\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1\r
+ #undef IPOL_L0\r
+#endif\r
+\r
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
#undef IPOL_W\r
CTRNormalMap(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
-\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
\r
private:\r
- void scanline_bilinear ();\r
-\r
- sScanConvertData scan;\r
- sScanLineData line;\r
+ void fragmentShader();\r
\r
};\r
\r
}\r
\r
\r
+void CTRNormalMap::OnSetMaterial(const SBurningShaderMaterial& material)\r
+{\r
+}\r
\r
/*!\r
*/\r
-void CTRNormalMap::scanline_bilinear ()\r
+void CTRNormalMap::fragmentShader()\r
{\r
tVideoSample *dst;\r
\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
#ifdef IPOL_L0\r
- sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];\r
+ sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#ifdef IPOL_C0\r
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
#endif\r
+#ifdef IPOL_C1\r
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
#ifdef IPOL_T0\r
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
#endif\r
#ifdef IPOL_C0\r
line.c[0][0] += slopeC[0] * subPixel;\r
#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0] * subPixel;\r
#endif\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
#endif\r
\r
\r
- f32 inversew;\r
+ f32 inversew = FIX_POINT_F32_MUL;\r
\r
- tFixPoint tx0, tx1;\r
- tFixPoint ty0, ty1;\r
+ tFixPoint tx0, ty0;\r
+\r
+#ifdef IPOL_T1\r
+ tFixPoint tx1, ty1;\r
+#endif\r
\r
tFixPoint r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
tFixPoint r2, g2, b2;\r
\r
+#ifdef IPOL_L0\r
tFixPoint lx, ly, lz;\r
- tFixPoint ndotl;\r
-\r
- sVec3 light;\r
+#endif\r
+ tFixPoint ndotl = FIX_POINT_ONE;\r
\r
\r
#ifdef IPOL_C0\r
- tFixPoint r3, g3, b3;\r
+ tFixPoint a3,r3, g3, b3;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+ tFixPoint aFog = FIX_POINT_ONE;\r
#endif\r
\r
+\r
for ( s32 i = 0; i <= dx; i++ )\r
{\r
#ifdef CMP_Z\r
{\r
#ifdef INVERSE_W\r
inversew = fix_inverse32 ( line.w[0] );\r
-\r
- tx0 = tofix ( line.t[0][0].x,inversew);\r
- ty0 = tofix ( line.t[0][0].y,inversew);\r
- tx1 = tofix ( line.t[1][0].x,inversew);\r
- ty1 = tofix ( line.t[1][0].y,inversew);\r
-\r
-\r
-#ifdef IPOL_C0\r
- r3 = tofix ( line.c[0][0].y ,inversew );\r
- g3 = tofix ( line.c[0][0].z ,inversew );\r
- b3 = tofix ( line.c[0][0].w ,inversew );\r
#endif\r
\r
-#else\r
- inversew = FIX_POINT_F32_MUL;\r
- tx0 = tofix(line.t[0][0].x, inversew);\r
- ty0 = tofix(line.t[0][0].y, inversew);\r
- tx1 = tofix(line.t[1][0].x, inversew);\r
- ty1 = tofix(line.t[1][0].y, inversew);\r
-\r
#ifdef IPOL_C0\r
- r3 = tofix ( line.c[0][0].y );\r
- g3 = tofix ( line.c[0][0].z );\r
- b3 = tofix ( line.c[0][0].w );\r
+ //vertex alpha blend ( and omit depthwrite ,hacky..)\r
+ a3 = tofix(line.c[0][0].x, inversew);\r
+ if (a3 + 2 >= FIX_POINT_ONE)\r
+ {\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+#endif\r
+ }\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ //complete inside fog\r
+ if (TL_Flag & TL_FOG)\r
+ {\r
+ aFog = tofix(line.c[1][0].a, inversew);\r
+ if (aFog <= 0)\r
+ {\r
+ dst[i] = fog_color_sample;\r
+ continue;\r
+ }\r
+ }\r
#endif\r
+\r
+ tx0 = tofix ( line.t[0][0].x,inversew);\r
+ ty0 = tofix ( line.t[0][0].y,inversew);\r
+ tx1 = tofix ( line.t[1][0].x,inversew);\r
+ ty1 = tofix ( line.t[1][0].y,inversew);\r
+\r
+ // diffuse map\r
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );\r
\r
- // normal map\r
+ // normal map ( same texcoord0 but different mipmapping)\r
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );\r
\r
r1 = ( r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);\r
g1 = ( g1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);\r
b1 = ( b1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);\r
\r
-/*\r
- sVec3 l = line.l[0][0] * inversew;\r
- l.setLength( 2.f );\r
-\r
- lx = tofix ( l.x - 0.5f );\r
- ly = tofix ( l.y - 0.5f );\r
- lz = tofix ( l.z - 0.5f );\r
-*/\r
-\r
+#ifdef IPOL_L0\r
lx = tofix ( line.l[0][0].x, inversew );\r
ly = tofix ( line.l[0][0].y, inversew );\r
lz = tofix ( line.l[0][0].z, inversew );\r
\r
// DOT 3 Normal Map light in tangent space\r
- ndotl = saturateFix ( FIX_POINT_HALF_COLOR + (( imulFix ( r1, lx ) + imulFix ( g1, ly ) + imulFix ( b1, lz ) ) << (COLOR_MAX_LOG2-1)) );\r
+ //max(dot(LightVector, Normal), 0.0);\r
+ ndotl = clampfix_mincolor( (imulFix_simple(r1,lx) + imulFix_simple(g1,ly) + imulFix_simple(b1,lz) ) );\r
+#endif\r
\r
#ifdef IPOL_C0\r
\r
- // N . L\r
- r2 = imulFix ( imulFix_tex1 ( r0, ndotl ), r3 );\r
- g2 = imulFix ( imulFix_tex1 ( g0, ndotl ), g3 );\r
- b2 = imulFix ( imulFix_tex1 ( b0, ndotl ), b3 );\r
-\r
-/*\r
- // heightmap: (1 - neu ) + alt - 0.5, on_minus_srcalpha + add signed\r
- // emboss bump map\r
- a4 -= a1;\r
- r2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( r0 + a4, r3 ) ) );\r
- g2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( g0 + a4, g3 ) ) );\r
- b2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( b0 + a4, b3 ) ) );\r
-*/\r
+ //LightColor[0]\r
+ r3 = tofix(line.c[0][0].y, inversew);\r
+ g3 = tofix(line.c[0][0].z, inversew);\r
+ b3 = tofix(line.c[0][0].w, inversew);\r
+\r
+ // Lambert * LightColor[0] * Diffuse Texture;\r
+ r2 = imulFix (imulFix_simple( r3, ndotl ), r0 );\r
+ g2 = imulFix (imulFix_simple( g3, ndotl ), g0 );\r
+ b2 = imulFix (imulFix_simple( b3, ndotl ), b0 );\r
+\r
+ //vertex alpha blend ( and omit depthwrite ,hacky..)\r
+ if (a3 + 2 < FIX_POINT_ONE)\r
+ {\r
+ color_to_fix(r1, g1, b1, dst[i]);\r
+ r2 = r1 + imulFix(a3, r2 - r1);\r
+ g2 = g1 + imulFix(a3, g2 - g1);\r
+ b2 = b1 + imulFix(a3, b2 - b1);\r
+ }\r
+\r
+#ifdef IPOL_C1\r
+ //mix with distance\r
+ if (aFog < FIX_POINT_ONE)\r
+ {\r
+ r2 = fog_color[1] + imulFix(aFog, r2 - fog_color[1]);\r
+ g2 = fog_color[2] + imulFix(aFog, g2 - fog_color[2]);\r
+ b2 = fog_color[3] + imulFix(aFog, b2 - fog_color[3]);\r
+ }\r
+#endif\r
+ dst[i] = fix_to_sample(r2, g2, b2);\r
+\r
\r
-/*\r
- r2 = clampfix_maxcolor ( imulFix_tex1 ( r2, r1 ) );\r
- g2 = clampfix_maxcolor ( imulFix_tex1 ( g2, g1 ) );\r
- b2 = clampfix_maxcolor ( imulFix_tex1 ( b2, b1 ) );\r
-*/\r
#else\r
- r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );\r
- g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );\r
- b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );\r
+ r2 = imulFix_tex4 ( r0, r1 );\r
+ g2 = imulFix_tex4 ( g0, g1 );\r
+ b2 = imulFix_tex4 ( b0, b1 );\r
+ dst[i] = fix_to_sample(r2, g2, b2);\r
#endif\r
\r
-\r
- dst[i] = fix_to_color ( r2, g2, b2 );\r
-\r
-#ifdef WRITE_Z\r
- z[i] = line.z[0];\r
-#endif\r
-#ifdef WRITE_W\r
- z[i] = line.w[0];\r
-#endif\r
}\r
\r
#ifdef IPOL_Z\r
#ifdef IPOL_C0\r
line.c[0][0] += slopeC[0];\r
#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1];\r
+#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0];\r
#endif\r
\r
}\r
\r
-void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
scan.c[0][0] = a->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];\r
+ scan.c[1][0] = a->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
scan.t[0][0] = a->Tex[0];\r
\r
\r
// rasterize upper sub-triangle\r
- //if ( (f32) 0.0 != scan.invDeltaY[1] )\r
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )\r
{\r
// calculate slopes for top edge\r
scan.c[0][1] = a->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];\r
+ scan.c[1][1] = a->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
scan.t[0][1] = a->Tex[0];\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ line.c[1][scan.left] = scan.c[1][0];\r
+ line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][scan.left] = scan.t[0][0];\r
line.t[0][scan.right] = scan.t[0][1];\r
#endif\r
\r
// render a scanline\r
- scanline_bilinear ();\r
+ fragmentShader ();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0];\r
+ scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0];\r
scan.t[0][1] += scan.slopeT[0][1];\r
}\r
\r
// rasterize lower sub-triangle\r
- //if ( (f32) 0.0 != scan.invDeltaY[2] )\r
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )\r
{\r
// advance to middle point\r
- //if( (f32) 0.0 != scan.invDeltaY[1] )\r
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )\r
{\r
temp[0] = b->Pos.y - a->Pos.y; // dy\r
#ifdef IPOL_C0\r
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
#endif\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];\r
+#endif\r
#ifdef IPOL_T0\r
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
#endif\r
scan.t[2][0] = a->Tex[2] + scan.slopeT[2][0] * temp[0];\r
#endif\r
#ifdef IPOL_L0\r
- scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0];\r
+ scan.l[0][0] = sVec3Pack_unpack(a->LightTangent[0]) + scan.slopeL[0][0] * temp[0];\r
#endif\r
\r
}\r
scan.c[0][1] = b->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];\r
+ scan.c[1][1] = b->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
scan.t[0][1] = b->Tex[0];\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ line.c[1][scan.left] = scan.c[1][0];\r
+ line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][scan.left] = scan.t[0][0];\r
line.t[0][scan.right] = scan.t[0][1];\r
#endif\r
\r
// render a scanline\r
- scanline_bilinear ();\r
+ fragmentShader();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0];\r
+ scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0];\r
scan.t[0][1] += scan.slopeT[0][1];\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRStencilShadow(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
- virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
private:\r
- // fragment shader\r
- typedef void (CTRStencilShadow::*tFragmentShader) ();\r
- void fragment_zfail_decr ();\r
- void fragment_zfail_incr ();\r
-\r
- tFragmentShader fragmentShader;\r
-\r
- sScanConvertData scan;\r
- sScanLineData line;\r
+ void fragmentShader();\r
\r
};\r
\r
\r
/*!\r
*/\r
-void CTRStencilShadow::setParam ( u32 index, f32 value)\r
-{\r
- u32 val = (u32) value;\r
-\r
- // glStencilOp (fail,zfail,zpass\r
- if ( index == 1 && val == 1 )\r
- {\r
- fragmentShader = &CTRStencilShadow::fragment_zfail_incr;\r
- }\r
- else\r
- if ( index == 1 && val == 2 )\r
- {\r
- fragmentShader = &CTRStencilShadow::fragment_zfail_decr;\r
- }\r
-}\r
-\r
-/*!\r
-*/\r
-void CTRStencilShadow::fragment_zfail_decr ()\r
+void CTRStencilShadow::fragmentShader()\r
{\r
- if (!Stencil)\r
- return;\r
- //tVideoSample *dst;\r
-\r
#ifdef USE_ZBUFFER\r
fp24 *z;\r
#endif\r
\r
#ifdef USE_SBUFFER\r
- u32 *stencil;\r
+ tStencilSample *stencil;\r
#endif\r
\r
s32 xStart;\r
#ifdef IPOL_W\r
fp24 slopeW;\r
#endif\r
-#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
-#endif\r
-#ifdef IPOL_T0\r
- sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
-#endif\r
-#ifdef IPOL_L0\r
- sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];\r
-#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
-\r
if ( dx < 0 )\r
return;\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#ifdef IPOL_W\r
slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
#endif\r
-#ifdef IPOL_C0\r
- slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T0\r
- slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T1\r
- slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T2\r
- slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_L0\r
- slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;\r
-#endif\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) xStart ) - line.x[0];\r
#ifdef IPOL_W\r
line.w[0] += slopeW * subPixel;\r
#endif\r
-#ifdef IPOL_C0\r
- line.c[0][0] += slopeC[0] * subPixel;\r
-#endif\r
-#ifdef IPOL_T0\r
- line.t[0][0] += slopeT[0] * subPixel;\r
-#endif\r
-#ifdef IPOL_T1\r
- line.t[1][0] += slopeT[1] * subPixel;\r
#endif\r
-#ifdef IPOL_T2\r
- line.t[2][0] += slopeT[2] * subPixel;\r
-#endif\r
-#ifdef IPOL_L0\r
- line.l[0][0] += slopeL[0] * subPixel;\r
-#endif\r
-#endif\r
-\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
//dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
#endif\r
\r
#ifdef USE_SBUFFER\r
- stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+ stencil = (tStencilSample*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
#endif\r
\r
\r
#ifdef INVERSE_W\r
- f32 inversew;\r
-#endif\r
-\r
-\r
-#ifdef IPOL_C0\r
- tFixPoint r3, g3, b3;\r
+ f32 inversew = FIX_POINT_F32_MUL;\r
#endif\r
\r
- for ( s32 i = 0; i <= dx; i++ )\r
+ s32 i;\r
+ for (i = 0; i <= dx; i++)\r
{\r
#ifdef CMP_Z\r
- if ( line.z[0] < z[i] )\r
+ if (line.z[0] < z[i])\r
#endif\r
#ifdef CMP_W\r
- if ( line.w[0] < z[i] )\r
+ if (line.w[0] > z[i])\r
#endif\r
{\r
- // zfail\r
- stencil[i] -= 1;\r
+ // zpass\r
+ switch (stencilOp[2])\r
+ {\r
+ case StencilOp_INCR: stencil[i] += 1; break;\r
+ case StencilOp_DECR: stencil[i] -= 1; break;// core::s32_max(0, stencil[i] - 1); break;\r
+ default:\r
+ case StencilOp_KEEP: break;\r
+ }\r
}\r
-\r
-#ifdef IPOL_Z\r
- line.z[0] += slopeZ;\r
-#endif\r
-#ifdef IPOL_W\r
- line.w[0] += slopeW;\r
-#endif\r
-#ifdef IPOL_C0\r
- line.c[0][0] += slopeC[0];\r
-#endif\r
-#ifdef IPOL_T0\r
- line.t[0][0] += slopeT[0];\r
-#endif\r
-#ifdef IPOL_T1\r
- line.t[1][0] += slopeT[1];\r
-#endif\r
-#ifdef IPOL_T2\r
- line.t[2][0] += slopeT[2];\r
-#endif\r
-#ifdef IPOL_L0\r
- line.l[0][0] += slopeL[0];\r
-#endif\r
- }\r
-}\r
-\r
-/*!\r
-*/\r
-void CTRStencilShadow::fragment_zfail_incr()\r
-{\r
- if (!Stencil)\r
- return;\r
- //tVideoSample *dst;\r
-\r
-#ifdef USE_ZBUFFER\r
- fp24 *z;\r
-#endif\r
-\r
-#ifdef USE_SBUFFER\r
- u32 *stencil;\r
-#endif\r
-\r
- s32 xStart;\r
- s32 xEnd;\r
- s32 dx;\r
-\r
-\r
-#ifdef SUBTEXEL\r
- f32 subPixel;\r
-#endif\r
-\r
-#ifdef IPOL_Z\r
- f32 slopeZ;\r
-#endif\r
-#ifdef IPOL_W\r
- fp24 slopeW;\r
-#endif\r
-#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
-#endif\r
-#ifdef IPOL_T0\r
- sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
-#endif\r
-#ifdef IPOL_L0\r
- sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];\r
-#endif\r
-\r
- // apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
-\r
- dx = xEnd - xStart;\r
-\r
- if ( dx < 0 )\r
- return;\r
-\r
- // slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
-\r
-#ifdef IPOL_Z\r
- slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_W\r
- slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_C0\r
- slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T0\r
- slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T1\r
- slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T2\r
- slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_L0\r
- slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;\r
-#endif\r
-\r
-#ifdef SUBTEXEL\r
- subPixel = ( (f32) xStart ) - line.x[0];\r
-#ifdef IPOL_Z\r
- line.z[0] += slopeZ * subPixel;\r
-#endif\r
-#ifdef IPOL_W\r
- line.w[0] += slopeW * subPixel;\r
-#endif\r
-#ifdef IPOL_C0\r
- line.c[0][0] += slopeC[0] * subPixel;\r
-#endif\r
-#ifdef IPOL_T0\r
- line.t[0][0] += slopeT[0] * subPixel;\r
-#endif\r
-#ifdef IPOL_T1\r
- line.t[1][0] += slopeT[1] * subPixel;\r
-#endif\r
-#ifdef IPOL_T2\r
- line.t[2][0] += slopeT[2] * subPixel;\r
-#endif\r
-#ifdef IPOL_L0\r
- line.l[0][0] += slopeL[0] * subPixel;\r
-#endif\r
-#endif\r
-\r
- //dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
-\r
-#ifdef USE_ZBUFFER\r
- z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
-#endif\r
-\r
-#ifdef USE_SBUFFER\r
- stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
-#endif\r
-\r
-#ifdef INVERSE_W\r
- f32 inversew;\r
-#endif\r
-\r
-#ifdef IPOL_C0\r
- tFixPoint r3, g3, b3;\r
-#endif\r
-\r
- for ( s32 i = 0; i <= dx; i++ )\r
- {\r
-#ifdef CMP_Z\r
- if ( line.z[0] < z[i] )\r
-#endif\r
-#ifdef CMP_W\r
- if ( line.w[0] < z[i] )\r
-#endif\r
+ else\r
{\r
// zfail\r
- stencil[i] += 1;\r
+ switch (stencilOp[1])\r
+ {\r
+ case StencilOp_INCR: stencil[i] += 1; break;\r
+ case StencilOp_DECR: stencil[i] -= 1; break;// core::s32_max(0, stencil[i] - 1); break;\r
+ default:\r
+ case StencilOp_KEEP: break;\r
+ }\r
}\r
\r
#ifdef IPOL_Z\r
#endif\r
#ifdef IPOL_W\r
line.w[0] += slopeW;\r
-#endif\r
-#ifdef IPOL_C0\r
- line.c[0][0] += slopeC[0];\r
-#endif\r
-#ifdef IPOL_T0\r
- line.t[0][0] += slopeT[0];\r
-#endif\r
-#ifdef IPOL_T1\r
- line.t[1][0] += slopeT[1];\r
-#endif\r
-#ifdef IPOL_T2\r
- line.t[2][0] += slopeT[2];\r
-#endif\r
-#ifdef IPOL_L0\r
- line.l[0][0] += slopeL[0];\r
#endif\r
}\r
+\r
}\r
\r
-void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+\r
+void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// rasterize upper sub-triangle\r
- //if ( (f32) 0.0 != scan.invDeltaY[1] )\r
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )\r
{\r
// calculate slopes for top edge\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// render a scanline\r
- (this->*fragmentShader) ();\r
+ fragmentShader ();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
#endif\r
\r
// render a scanline\r
- (this->*fragmentShader) ();\r
+ fragmentShader ();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
//! creates a triangle renderer\r
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver)\r
{\r
+ //ETR_STENCIL_SHADOW\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRStencilShadow(driver);\r
#else\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
namespace video\r
{\r
\r
-class CTRTextureBlend : public IBurningShader\r
-{\r
-public:\r
+ class CTRTextureBlend : public IBurningShader\r
+ {\r
+ public:\r
\r
- //! constructor\r
- CTRTextureBlend(CBurningVideoDriver* driver);\r
+ //! constructor\r
+ CTRTextureBlend(CBurningVideoDriver* driver);\r
\r
- //! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ //! draws an indexed triangle list\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
\r
- virtual void setZCompareFunc ( u32 func) _IRR_OVERRIDE_;\r
- virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;\r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
\r
+ virtual void setZCompareFunc(u32 func)\r
+ {\r
+ depth_func = (E_COMPARISON_FUNC)func;\r
+ }\r
+ virtual void setParam(u32 index, f32 value)\r
+ {\r
+ SBurningShaderMaterial material;\r
+ material.org.ZBuffer = depth_func;\r
+ material.org.MaterialTypeParam = value;\r
+ OnSetMaterial(material);\r
+ }\r
+\r
+#endif\r
\r
private:\r
// fragment shader\r
void fragment_one_one_minus_src_alpha ();\r
void fragment_one_minus_dst_alpha_one();\r
void fragment_src_alpha_one();\r
+ void fragment_src_alpha_one_minus_src_alpha();\r
\r
tFragmentShader fragmentShader;\r
- sScanConvertData scan;\r
- sScanLineData line;\r
\r
- u32 ZCompare;\r
+ E_COMPARISON_FUNC depth_func;\r
};\r
\r
//! constructor\r
setDebugName("CTRTextureBlend");\r
#endif\r
\r
- ZCompare = 1;\r
+ depth_func = ECFN_LESSEQUAL;\r
+ fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;\r
}\r
\r
/*!\r
*/\r
-void CTRTextureBlend::setZCompareFunc ( u32 func)\r
+void CTRTextureBlend::OnSetMaterial(const SBurningShaderMaterial& material)\r
{\r
- ZCompare = func;\r
-}\r
+ int showname = 0;\r
\r
-/*!\r
-*/\r
-void CTRTextureBlend::setParam ( u32 index, f32 value)\r
-{\r
- u8 showname = 0;\r
+ depth_func = (E_COMPARISON_FUNC)material.org.ZBuffer;\r
+ AlphaRef = 0; // tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);\r
\r
E_BLEND_FACTOR srcFact,dstFact;\r
E_MODULATE_FUNC modulate;\r
u32 alphaSrc;\r
- unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSrc, value );\r
+ unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSrc, material.org.MaterialTypeParam);\r
\r
fragmentShader = 0;\r
\r
{\r
fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;\r
}\r
- else\r
- if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE )\r
+ else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE )\r
{\r
fragmentShader = &CTRTextureBlend::fragment_dst_color_one;\r
}\r
- else\r
- if ( srcFact == EBF_DST_COLOR && dstFact == EBF_SRC_ALPHA)\r
+ else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_SRC_ALPHA)\r
{\r
fragmentShader = &CTRTextureBlend::fragment_dst_color_src_alpha;\r
}\r
- else\r
- if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE_MINUS_DST_ALPHA)\r
+ else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE_MINUS_DST_ALPHA)\r
{\r
fragmentShader = &CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha;\r
}\r
- else\r
- if ( srcFact == EBF_ZERO && dstFact == EBF_ONE_MINUS_SRC_COLOR )\r
+ else if ( srcFact == EBF_ZERO && dstFact == EBF_ONE_MINUS_SRC_COLOR )\r
{\r
fragmentShader = &CTRTextureBlend::fragment_zero_one_minus_scr_color;\r
}\r
- else\r
- if ( srcFact == EBF_ONE && dstFact == EBF_ONE_MINUS_SRC_ALPHA)\r
+ else if ( srcFact == EBF_ONE && dstFact == EBF_ONE_MINUS_SRC_ALPHA)\r
{\r
fragmentShader = &CTRTextureBlend::fragment_one_one_minus_src_alpha;\r
}\r
- else\r
- if ( srcFact == EBF_ONE_MINUS_DST_ALPHA && dstFact == EBF_ONE )\r
+ else if ( srcFact == EBF_ONE_MINUS_DST_ALPHA && dstFact == EBF_ONE )\r
{\r
fragmentShader = &CTRTextureBlend::fragment_one_minus_dst_alpha_one;\r
}\r
- else\r
- if ( srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE )\r
+ else if ( srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE )\r
{\r
fragmentShader = &CTRTextureBlend::fragment_src_alpha_one;\r
}\r
- else\r
- if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA )\r
+ else if (srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE_MINUS_SRC_ALPHA)\r
+ {\r
+ fragmentShader = &CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha;\r
+ }\r
+ else if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA )\r
{\r
fragmentShader = &CTRTextureBlend::fragment_src_color_src_alpha;\r
}\r
{\r
char buf[128];\r
snprintf_irr ( buf, 128, "missing shader: %s %s",n[srcFact], n[dstFact] );\r
- os::Printer::log( buf, ELL_INFORMATION );\r
+ os::Printer::log( buf, ELL_WARNING);\r
\r
lsrcFact = srcFact;\r
ldstFact = dstFact;\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
);\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
);\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
-\r
if ( dx < 0 )\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
tFixPoint a0, r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
\r
+#ifdef IPOL_C0\r
+ tFixPoint a2,r2, g2, b2;\r
+#endif\r
+\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
#endif\r
\r
{\r
-\r
+ //solves example 08. todo: depth_write. \r
#ifdef WRITE_W\r
- z[i] = line.w[0];\r
+ //z[i] = line.w[0];\r
#endif\r
\r
#ifdef INVERSE_W\r
#endif\r
\r
getSample_texture ( a0, r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,iw), tofix ( line.t[0][0].y,iw) );\r
- color_to_fix ( r1, g1, b1, dst[i] );\r
\r
-// u32 check = imulFix_tex1( r0, r1 );\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1( r0, r1 ) + imulFix_tex1( r1, a0 ) ),\r
- clampfix_maxcolor ( imulFix_tex1( g0, g1 ) + imulFix_tex1( g1, a0 ) ),\r
- clampfix_maxcolor ( imulFix_tex1( b0, b1 ) + imulFix_tex1( b1, a0 ) )\r
+#ifdef IPOL_C0\r
+ vec4_to_fix(a2,r2, g2, b2, line.c[0][0], iw);\r
+ //a0 = imulFix(a0, a2); why is vertex color enabled and not vertex_alpha?\r
+ r0 = imulFix_simple(r0, r2);\r
+ g0 = imulFix_simple(g0, g2);\r
+ b0 = imulFix_simple(b0, b2);\r
+#endif\r
+\r
+ color_to_fix ( r1, g1, b1, dst[i] );\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1( r0, r0 ) + imulFix_tex1( r1, a0 ) ),\r
+ clampfix_maxcolor ( imulFix_tex1( g0, g0 ) + imulFix_tex1( g1, a0 ) ),\r
+ clampfix_maxcolor ( imulFix_tex1( b0, b0 ) + imulFix_tex1( b1, a0 ) )\r
);\r
+\r
}\r
\r
#ifdef IPOL_W\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
);\r
line.c[0][0] += slopeC[0];\r
#endif\r
}break;\r
+ \r
} // zcompare\r
\r
}\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2 ( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
tFixPoint a0,r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
tFixPoint r2, g2, b2;\r
-\r
+#endif\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
\r
color_to_fix1 ( r1, g1, b1, dst[i] );\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix_to_color ( imulFix ( r0 + imulFix ( r1, a0 ), r2 ),\r
- imulFix ( g0 + imulFix ( g1, a0 ), g2 ),\r
- imulFix ( b0 + imulFix ( b1, a0 ), b2 )\r
+ dst[i] = fix_to_sample( imulFix ( r0 + imulFix_simple( r1, a0 ), r2 ),\r
+ imulFix ( g0 + imulFix_simple( g1, a0 ), g2 ),\r
+ imulFix ( b0 + imulFix_simple( b1, a0 ), b2 )\r
);\r
#else\r
- dst[i] = fix_to_color ( r0 + imulFix ( r1, a0 ),\r
- g0 + imulFix ( g1, a0 ),\r
- b0 + imulFix ( b1, a0 )\r
+ dst[i] = fix_to_sample( r0 + imulFix_simple( r1, a0 ),\r
+ g0 + imulFix_simple( g1, a0 ),\r
+ b0 + imulFix_simple( b1, a0 )\r
);\r
\r
#endif\r
\r
color_to_fix1 ( r1, g1, b1, dst[i] );\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix_to_color ( imulFix ( r0 + imulFix ( r1, a0 ), r2 ),\r
- imulFix ( g0 + imulFix ( g1, a0 ), g2 ),\r
- imulFix ( b0 + imulFix ( b1, a0 ), b2 )\r
+ dst[i] = fix_to_sample( imulFix ( r0 + imulFix_simple( r1, a0 ), r2 ),\r
+ imulFix ( g0 + imulFix_simple( g1, a0 ), g2 ),\r
+ imulFix ( b0 + imulFix_simple( b1, a0 ), b2 )\r
);\r
#else\r
- dst[i] = fix_to_color ( r0 + imulFix ( r1, a0 ),\r
- g0 + imulFix ( g1, a0 ),\r
- b0 + imulFix ( b1, a0 )\r
+ dst[i] = fix_to_sample( r0 + imulFix_simple( r1, a0 ),\r
+ g0 + imulFix_simple( g1, a0 ),\r
+ b0 + imulFix_simple( b1, a0 )\r
);\r
\r
#endif\r
line.c[0][0] += slopeC[0];\r
#endif\r
}break;\r
+\r
} // zcompare\r
\r
}\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
tFixPoint r0, g0, b0;\r
tFixPoint a1, r1, g1, b1;\r
+#ifdef IPOL_C0\r
tFixPoint r2, g2, b2;\r
-\r
+#endif\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
color_to_fix1 ( a1, r1, g1, b1, dst[i] );\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
a1 = FIX_POINT_ONE - a1;\r
- dst[i] = fix_to_color ( imulFix ( imulFix ( r0, a1 ) + r1, r2 ),\r
- imulFix ( imulFix ( g0, a1 ) + g1, g2 ),\r
- imulFix ( imulFix ( b0, a1 ) + b1, b2 )\r
+ dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, a1 ) + r1, r2 ),\r
+ imulFix (imulFix_simple( g0, a1 ) + g1, g2 ),\r
+ imulFix (imulFix_simple( b0, a1 ) + b1, b2 )\r
);\r
#else\r
- dst[i] = fix_to_color ( imulFix ( r0, a1) + r0,\r
- imulFix ( g0, a1) + g0,\r
- imulFix ( b0, a1) + b0\r
+ dst[i] = fix_to_sample(imulFix_simple( r0, a1) + r0,\r
+ imulFix_simple( g0, a1) + g0,\r
+ imulFix_simple( b0, a1) + b0\r
);\r
\r
#endif\r
color_to_fix1 ( a1, r1, g1, b1, dst[i] );\r
\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
a1 = FIX_POINT_ONE - a1;\r
- dst[i] = fix_to_color ( imulFix ( imulFix ( r0, a1 ) + r1, r2 ),\r
- imulFix ( imulFix ( g0, a1 ) + g1, g2 ),\r
- imulFix ( imulFix ( b0, a1 ) + b1, b2 )\r
+ dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, a1 ) + r1, r2 ),\r
+ imulFix (imulFix_simple( g0, a1 ) + g1, g2 ),\r
+ imulFix (imulFix_simple( b0, a1 ) + b1, b2 )\r
);\r
#else\r
- dst[i] = fix_to_color ( imulFix ( r0, a1) + r0,\r
- imulFix ( g0, a1) + g0,\r
- imulFix ( b0, a1) + b0\r
+ dst[i] = fix_to_sample(imulFix_simple( r0, a1) + r0,\r
+ imulFix_simple( g0, a1) + g0,\r
+ imulFix_simple( b0, a1) + b0\r
);\r
\r
#endif\r
line.c[0][0] += slopeC[0];\r
#endif\r
}break;\r
+\r
} // zcompare\r
\r
}\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
tFixPoint a0, r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
tFixPoint r2, g2, b2;\r
-\r
+#endif\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
if ( a0 > 0 )\r
{\r
- a0 >>= 8;\r
+ fix_color_norm(a0);\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix4_to_color ( a0,\r
- clampfix_maxcolor ( imulFix (r0,a0 ) + r1),\r
- clampfix_maxcolor ( imulFix (g0,a0 ) + g1),\r
- clampfix_maxcolor ( imulFix (b0,a0 ) + b1)\r
+ dst[i] = fix4_to_sample( a0,\r
+ clampfix_maxcolor (imulFix_simple(r0,a0) + r1),\r
+ clampfix_maxcolor (imulFix_simple(g0,a0) + g1),\r
+ clampfix_maxcolor (imulFix_simple(b0,a0) + b1)\r
);\r
\r
/*\r
- a0 >>= 8;\r
- dst[i] = fix4_to_color ( a0,\r
- imulFix ( imulFix ( r0, a0 ) + r1, r2 ),\r
- imulFix ( imulFix ( g0, a0 ) + g1, g2 ),\r
- imulFix ( imulFix ( b0, a0 ) + b1, b2 )\r
+ fix_color_norm(a0);\r
+ dst[i] = fix4_to_sample ( a0,\r
+ imulFix ( imulFix_simple ( r0, a0 ) + r1, r2 ),\r
+ imulFix ( imulFix_simple ( g0, a0 ) + g1, g2 ),\r
+ imulFix ( imulFix_simple ( b0, a0 ) + b1, b2 )\r
);\r
*/\r
#else\r
- dst[i] = fix4_to_color ( a0,\r
- clampfix_maxcolor ( imulFix (r0,a0 ) + r1 ),\r
- clampfix_maxcolor ( imulFix (g0,a0 ) + g1 ),\r
- clampfix_maxcolor ( imulFix (b0,a0 ) + b1 )\r
+ dst[i] = fix4_to_sample( a0,\r
+ clampfix_maxcolor (imulFix_simple(r0,a0 ) + r1 ),\r
+ clampfix_maxcolor (imulFix_simple(g0,a0 ) + g1 ),\r
+ clampfix_maxcolor (imulFix_simple(b0,a0 ) + b1 )\r
);\r
\r
#endif\r
getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
if ( a0 > 0 )\r
{\r
- a0 >>= 8;\r
+ fix_color_norm(a0);\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix4_to_color ( a0,\r
- clampfix_maxcolor ( imulFix ( imulFix (r0,a0 ) + r1, r2 ) ),\r
- clampfix_maxcolor ( imulFix ( imulFix (g0,a0 ) + g1, g2 ) ),\r
- clampfix_maxcolor ( imulFix ( imulFix (b0,a0 ) + b1, b2 ) )\r
+ dst[i] = fix4_to_sample( a0,\r
+ clampfix_maxcolor ( imulFix (imulFix_simple(r0,a0 ) + r1, r2 ) ),\r
+ clampfix_maxcolor ( imulFix (imulFix_simple(g0,a0 ) + g1, g2 ) ),\r
+ clampfix_maxcolor ( imulFix (imulFix_simple(b0,a0 ) + b1, b2 ) )\r
);\r
\r
/*\r
- a0 >>= 8;\r
- dst[i] = fix4_to_color ( a0,\r
- imulFix ( imulFix ( r0, a0 ) + r1, r2 ),\r
- imulFix ( imulFix ( g0, a0 ) + g1, g2 ),\r
- imulFix ( imulFix ( b0, a0 ) + b1, b2 )\r
+ fix_color_norm(a0);\r
+ dst[i] = fix4_to_sample ( a0,\r
+ imulFix ( imulFix_simple ( r0, a0 ) + r1, r2 ),\r
+ imulFix ( imulFix_simple ( g0, a0 ) + g1, g2 ),\r
+ imulFix ( imulFix_simple ( b0, a0 ) + b1, b2 )\r
);\r
*/\r
#else\r
- dst[i] = fix4_to_color ( a0,\r
- clampfix_maxcolor ( imulFix (r0,a0 ) + r1 ),\r
- clampfix_maxcolor ( imulFix (g0,a0 ) + g1 ),\r
- clampfix_maxcolor ( imulFix (b0,a0 ) + b1 )\r
+ dst[i] = fix4_to_sample( a0,\r
+ clampfix_maxcolor (imulFix_simple(r0,a0 ) + r1 ),\r
+ clampfix_maxcolor (imulFix_simple(g0,a0 ) + g1 ),\r
+ clampfix_maxcolor (imulFix_simple(b0,a0 ) + b1 )\r
);\r
\r
#endif\r
line.c[0][0] += slopeC[0];\r
#endif\r
}break;\r
+\r
+ } // zcompare\r
+\r
+}\r
+\r
+\r
+/*!\r
+*/\r
+void CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha()\r
+{\r
+ tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+ fp24 *z;\r
+#endif\r
+\r
+ s32 xStart;\r
+ s32 xEnd;\r
+ s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+ f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
+#endif\r
+#ifdef IPOL_T0\r
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+ // apply top-left fill-convention, left\r
+ xStart = fill_convention_left(line.x[0]);\r
+ xEnd = fill_convention_right(line.x[1]);\r
+\r
+ dx = xEnd - xStart;\r
+ if (dx < 0)\r
+ return;\r
+\r
+ // slopes\r
+ const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+ z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+ f32 iw = FIX_POINT_F32_MUL;\r
+\r
+ tFixPoint a0, r0, g0, b0;\r
+ tFixPoint r1, g1, b1;\r
+ tFixPoint a2, r2, g2, b2;\r
+\r
+ s32 i;\r
+\r
+ switch (depth_func)\r
+ {\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
+ for (i = 0; i <= dx; ++i)\r
+ {\r
+#ifdef CMP_W\r
+ if (line.w[0] >= z[i])\r
+#endif\r
+\r
+ {\r
+#ifdef WRITE_W\r
+ //z[i] = line.w[0];\r
+#endif\r
+\r
+#ifdef INVERSE_W\r
+ iw = fix_inverse32(line.w[0]);\r
+#endif\r
+\r
+ getSample_texture(a0, r0, g0, b0, &IT[0], tofix(line.t[0][0].x, iw), tofix(line.t[0][0].y, iw));\r
+ if (a0 > AlphaRef)\r
+ {\r
+#ifdef IPOL_C0\r
+ vec4_to_fix(a2, r2, g2, b2, line.c[0][0], iw);\r
+ //a0 = imulFix(a0, a2); why is vertex color enabled and not vertex_alpha?\r
+ r0 = imulFix_simple(r0, r2);\r
+ g0 = imulFix_simple(g0, g2);\r
+ b0 = imulFix_simple(b0, b2);\r
+#endif\r
+\r
+ color_to_fix(r1, g1, b1, dst[i]);\r
+\r
+ fix_color_norm(a0);\r
+\r
+ r2 = r1 + imulFix(a0, r0 - r1);\r
+ g2 = g1 + imulFix(a0, g0 - g1);\r
+ b2 = b1 + imulFix(a0, b0 - b1);\r
+ dst[i] = fix4_to_sample(a0, r2, g2, b2);\r
+ }\r
+\r
+ }\r
+\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC[0];\r
+#endif\r
+ }\r
+ break;\r
+\r
} // zcompare\r
\r
}\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
tFixPoint r0, g0, b0;\r
tFixPoint a1, r1, g1, b1;\r
+#ifdef IPOL_C0\r
tFixPoint r2, g2, b2;\r
-\r
+#endif\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
color_to_fix1 ( a1, r1, g1, b1, dst[i] );\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
a1 = FIX_POINT_ONE - a1;\r
- dst[i] = fix_to_color ( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),\r
+ dst[i] = fix_to_sample( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),\r
imulFix ( imulFix ( g1, g0 + a1 ), g2 ),\r
imulFix ( imulFix ( b1, b0 + a1 ), b2 )\r
);\r
#else\r
- dst[i] = fix_to_color ( imulFix ( r1, r0 + a1 ),\r
+ dst[i] = fix_to_sample( imulFix ( r1, r0 + a1 ),\r
imulFix ( g1, g0 + a1 ),\r
imulFix ( b1, b0 + a1 )\r
);\r
color_to_fix1 ( a1, r1, g1, b1, dst[i] );\r
\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
a1 = FIX_POINT_ONE - a1;\r
- dst[i] = fix_to_color ( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),\r
+ dst[i] = fix_to_sample( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),\r
imulFix ( imulFix ( g1, g0 + a1 ), g2 ),\r
imulFix ( imulFix ( b1, b0 + a1 ), b2 )\r
);\r
#else\r
- dst[i] = fix_to_color ( imulFix ( r1, r0 + a1 ),\r
+ dst[i] = fix_to_sample( imulFix ( r1, r0 + a1 ),\r
imulFix ( g1, g0 + a1 ),\r
imulFix ( b1, b0 + a1 )\r
);\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
tFixPoint r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
tFixPoint r2, g2, b2;\r
-\r
+#endif\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
color_to_fix1 ( r1, g1, b1, dst[i] );\r
\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix_to_color ( imulFix ( imulFix ( r0, r1 ), r2 ),\r
- imulFix ( imulFix ( g0, g1 ), g2 ),\r
- imulFix ( imulFix ( b0, b1 ), b2 ) );\r
+ dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, r1 ), r2 ),\r
+ imulFix (imulFix_simple( g0, g1 ), g2 ),\r
+ imulFix (imulFix_simple( b0, b1 ), b2 ) );\r
#else\r
- dst[i] = fix_to_color ( imulFix ( r0, r1 ),\r
- imulFix ( g0, g1 ),\r
- imulFix ( b0, b1 )\r
+ dst[i] = fix_to_sample(imulFix_simple( r0, r1 ),\r
+ imulFix_simple( g0, g1 ),\r
+ imulFix_simple( b0, b1 )\r
);\r
\r
#endif\r
color_to_fix1 ( r1, g1, b1, dst[i] );\r
\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix_to_color ( imulFix ( imulFix ( r0, r1 ), r2 ),\r
- imulFix ( imulFix ( g0, g1 ), g2 ),\r
- imulFix ( imulFix ( b0, b1 ), b2 )\r
+ dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, r1 ), r2 ),\r
+ imulFix (imulFix_simple( g0, g1 ), g2 ),\r
+ imulFix (imulFix_simple( b0, b1 ), b2 )\r
);\r
#else\r
- dst[i] = fix_to_color ( imulFix ( r0, r1 ),\r
- imulFix ( g0, g1 ),\r
- imulFix ( b0, b1 )\r
+ dst[i] = fix_to_sample(imulFix_simple( r0, r1 ),\r
+ imulFix_simple( g0, g1 ),\r
+ imulFix_simple( b0, b1 )\r
);\r
\r
#endif\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
tFixPoint r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
tFixPoint r2, g2, b2;\r
-\r
+#endif\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
color_to_fix ( r1, g1, b1, dst[i] );\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),\r
clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )\r
);\r
\r
#else\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),\r
clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )\r
);\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),\r
clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )\r
);\r
\r
#else\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),\r
clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )\r
);\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
tFixPoint r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
tFixPoint r2, g2, b2;\r
-\r
+#endif\r
s32 i;\r
\r
- switch ( ZCompare )\r
+ switch (depth_func)\r
{\r
- case 1:\r
+ default:\r
+ case ECFN_LESSEQUAL:\r
for ( i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_W\r
getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
color_to_fix1 ( r1, g1, b1, dst[i] );\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),\r
- imulFix ( FIX_POINT_ONE - g0, g1 ),\r
- imulFix ( FIX_POINT_ONE - b0, b1 )\r
+ dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),\r
+ imulFix( FIX_POINT_ONE - g0, g1 ),\r
+ imulFix( FIX_POINT_ONE - b0, b1 )\r
);\r
\r
#else\r
- dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),\r
- imulFix ( FIX_POINT_ONE - g0, g1 ),\r
- imulFix ( FIX_POINT_ONE - b0, b1 )\r
+ dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),\r
+ imulFix( FIX_POINT_ONE - g0, g1 ),\r
+ imulFix( FIX_POINT_ONE - b0, b1 )\r
);\r
\r
#endif\r
getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
color_to_fix1 ( r1, g1, b1, dst[i] );\r
#ifdef IPOL_C0\r
- getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
\r
- dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),\r
- imulFix ( FIX_POINT_ONE - g0, g1 ),\r
- imulFix ( FIX_POINT_ONE - b0, b1 )\r
+ dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),\r
+ imulFix( FIX_POINT_ONE - g0, g1 ),\r
+ imulFix( FIX_POINT_ONE - b0, b1 )\r
);\r
\r
#else\r
- dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),\r
- imulFix ( FIX_POINT_ONE - g0, g1 ),\r
- imulFix ( FIX_POINT_ONE - b0, b1 )\r
+ dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),\r
+ imulFix( FIX_POINT_ONE - g0, g1 ),\r
+ imulFix( FIX_POINT_ONE - b0, b1 )\r
);\r
\r
#endif\r
\r
\r
\r
-void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
if ( 0 == fragmentShader )\r
return;\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver)\r
{\r
+ // EMT_ONETEXTURE_BLEND\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureBlend(driver);\r
#else\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRTextureDetailMap2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual bool canWireFrame () { return true; }\r
\r
-\r
-private:\r
- void scanline_bilinear ();\r
- sScanConvertData scan;\r
- sScanLineData line;\r
+protected:\r
+ virtual void scanline_bilinear ();\r
\r
};\r
\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
for ( s32 i = 0; i <= dx; ++i )\r
{\r
+ if ( (0 == EdgeTestPass) & i ) break;\r
+\r
#ifdef CMP_Z\r
if ( line.z[0] < z[i] )\r
#endif\r
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
getSample_texture ( r1, g1, b1, &IT[1], tx1,ty1 );\r
\r
- // bias half color\r
- r1 += -FIX_POINT_HALF_COLOR;\r
- g1 += -FIX_POINT_HALF_COLOR;\r
- b1 += -FIX_POINT_HALF_COLOR;\r
+ // add signed\r
\r
- r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 ) );\r
- g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 ) );\r
- b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 ) );\r
+ r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 - FIX_POINT_HALF_COLOR ) );\r
+ g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 - FIX_POINT_HALF_COLOR ) );\r
+ b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 - FIX_POINT_HALF_COLOR ) );\r
\r
- dst[i] = fix_to_color ( r2, g2, b2 );\r
+ dst[i] = fix_to_sample( r2, g2, b2 );\r
\r
#ifdef WRITE_Z\r
z[i] = line.z[0];\r
\r
}\r
\r
-void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_edge( ca );\r
+ scan.invDeltaY[1] = reciprocal_edge( ba );\r
+ scan.invDeltaY[2] = reciprocal_edge( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
#undef INVERSE_W\r
\r
#undef IPOL_C0\r
+#undef IPOL_C1\r
+#undef IPOL_C2\r
#undef IPOL_T0\r
#undef IPOL_T1\r
+#undef IPOL_L0\r
\r
// define render case\r
#define SUBTEXEL\r
#define WRITE_W\r
\r
#define IPOL_C0\r
+#define IPOL_C1\r
+//#define IPOL_C2\r
#define IPOL_T0\r
//#define IPOL_T1\r
+//#define IPOL_L0\r
\r
// apply global override\r
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
+#if BURNING_MATERIAL_MAX_COLORS < 2\r
+ #undef IPOL_C1\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 3\r
+#undef IPOL_C2\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1\r
+ #undef IPOL_L0\r
+#endif\r
+\r
+\r
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
#undef IPOL_W\r
CTRTextureGouraud2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual bool canWireFrame () { return true; }\r
\r
\r
private:\r
- void scanline_bilinear ();\r
- sScanConvertData scan;\r
- sScanLineData line;\r
-\r
+ void fragmentShader ();\r
};\r
\r
//! constructor\r
\r
/*!\r
*/\r
-void CTRTextureGouraud2::scanline_bilinear ()\r
+void CTRTextureGouraud2::fragmentShader ()\r
{\r
tVideoSample *dst;\r
\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC;\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT];\r
+#endif\r
+\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
#endif\r
#ifdef IPOL_C0\r
- slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C1\r
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C2\r
+ slopeC[2] = (line.c[2][1] - line.c[2][0]) * invDeltaX;\r
#endif\r
#ifdef IPOL_T0\r
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
#ifdef IPOL_T1\r
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
#endif\r
+#ifdef IPOL_L0\r
+ slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;\r
+#endif\r
+\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) xStart ) - line.x[0];\r
line.w[0] += slopeW * subPixel;\r
#endif\r
#ifdef IPOL_C0\r
- line.c[0][0] += slopeC * subPixel;\r
+ line.c[0][0] += slopeC[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
+#ifdef IPOL_C2\r
+ line.c[2][0] += slopeC[2] * subPixel;\r
#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0] * subPixel;\r
#ifdef IPOL_T1\r
line.t[1][0] += slopeT[1] * subPixel;\r
#endif\r
+#ifdef IPOL_L0\r
+ line.l[0][0] += slopeL[0] * subPixel;\r
+#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
tFixPoint tx0;\r
tFixPoint ty0;\r
\r
- tFixPoint r0, g0, b0;\r
-\r
#ifdef IPOL_C0\r
+ tFixPoint r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
#endif\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#ifdef IPOL_C1\r
+ tFixPoint aFog = FIX_POINT_ONE;\r
+#endif\r
+\r
+\r
+#ifdef IPOL_C2\r
+ tFixPoint r3, g3, b3;\r
+#endif\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
u32 dIndex = ( line.y & 3 ) << 2;\r
#endif\r
\r
for ( s32 i = 0; i <= dx; ++i )\r
{\r
+ //if test active only first pixel\r
+ if ( (0 == EdgeTestPass) & i ) break;\r
+\r
#ifdef CMP_Z\r
if ( line.z[0] < z[i] )\r
#endif\r
z[i] = line.w[0];\r
#endif\r
\r
-\r
#ifdef INVERSE_W\r
inversew = fix_inverse32 ( line.w[0] );\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+ //complete inside fog\r
+ if (TL_Flag & TL_FOG)\r
+ {\r
+ aFog = tofix(line.c[1][0].a, inversew);\r
+ if (aFog <= 0)\r
+ {\r
+ dst[i] = fog_color_sample;\r
+ continue;\r
+ }\r
+ }\r
+#endif\r
tx0 = tofix ( line.t[0][0].x, inversew);\r
ty0 = tofix ( line.t[0][0].y, inversew);\r
\r
+\r
#ifdef IPOL_C0\r
- r1 = tofix ( line.c[0][0].y ,inversew );\r
- g1 = tofix ( line.c[0][0].z ,inversew );\r
- b1 = tofix ( line.c[0][0].w ,inversew );\r
-#endif\r
+\r
+ getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);\r
+ vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);\r
+\r
+ r0 = imulFix_simple(r0, r1);\r
+ g0 = imulFix_simple(g0, g1);\r
+ b0 = imulFix_simple(b0, b1);\r
+\r
+#ifdef IPOL_C1\r
+\r
+ //specular highlight\r
+ if (TL_Flag & TL_SPECULAR)\r
+ {\r
+ vec4_to_fix(r1, g1, b1, line.c[1][0], inversew*COLOR_MAX);\r
+ r0 = clampfix_maxcolor(r1 + r0);\r
+ g0 = clampfix_maxcolor(g1 + g0);\r
+ b0 = clampfix_maxcolor(b1 + b0);\r
+ }\r
+ //mix with distance\r
+ if (aFog < FIX_POINT_ONE)\r
+ {\r
+ r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);\r
+ g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);\r
+ b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);\r
+ }\r
+ dst[i] = fix_to_sample(r0, g0, b0);\r
\r
#else\r
- tx0 = tofix(line.t[0][0].x, inversew);\r
- ty0 = tofix(line.t[0][0].y, inversew);\r
-#ifdef IPOL_C0\r
- getTexel_plain2 ( r1, g1, b1, line.c[0][0] );\r
-#endif\r
+ dst[i] = fix_to_sample(\r
+ imulFix_simple(r0, r1),\r
+ imulFix_simple(g0, g1),\r
+ imulFix_simple(b0, b1)\r
+ );\r
#endif\r
\r
-#ifdef IPOL_C0\r
- getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
-\r
- dst[i] = fix_to_color ( imulFix ( r0, r1 ),\r
- imulFix ( g0, g1 ),\r
- imulFix ( b0, b1 )\r
- );\r
#else\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
dst[i] = getTexel_plain ( &IT[0], d + tx0, d + ty0 );\r
#else\r
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
- dst[i] = fix_to_color ( r0, g0, b0 );\r
+ dst[i] = fix_to_sample( r0, g0, b0 );\r
#endif\r
\r
#endif\r
line.w[0] += slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- line.c[0][0] += slopeC;\r
+ line.c[0][0] += slopeC[0];\r
+#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1];\r
+#endif\r
+#ifdef IPOL_C2\r
+ line.c[2][0] += slopeC[2];\r
#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0];\r
#endif\r
#ifdef IPOL_T1\r
line.t[1][0] += slopeT[1];\r
+#endif\r
+#ifdef IPOL_L0\r
+ line.l[0][0] += slopeL[0];\r
#endif\r
}\r
\r
}\r
\r
-void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
scan.c[0][0] = a->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];\r
+ scan.c[1][0] = a->Color[1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+ scan.slopeC[2][0] = (c->Color[2] - a->Color[2]) * scan.invDeltaY[0];\r
+ scan.c[2][0] = a->Color[2];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
scan.t[0][0] = a->Tex[0];\r
scan.t[1][0] = a->Tex[1];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0];\r
+ scan.l[0][0] = a->LightTangent[0];\r
+#endif\r
+\r
// top left fill convention y run\r
s32 yStart;\r
s32 yEnd;\r
#endif\r
\r
// rasterize upper sub-triangle\r
- if ( (f32) 0.0 != scan.invDeltaY[1] )\r
+ if ( F32_GREATER_0(scan.invDeltaY[1]) )\r
{\r
// calculate slopes for top edge\r
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
scan.c[0][1] = a->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];\r
+ scan.c[1][1] = a->Color[1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+ scan.slopeC[2][1] = (b->Color[2] - a->Color[2]) * scan.invDeltaY[1];\r
+ scan.c[2][1] = a->Color[2];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
scan.t[0][1] = a->Tex[0];\r
scan.t[1][1] = a->Tex[1];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1];\r
+ scan.l[0][1] = a->LightTangent[0];\r
+#endif\r
+\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+ scan.c[2][0] += scan.slopeC[2][0] * subPixel;\r
+ scan.c[2][1] += scan.slopeC[2][1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ scan.l[0][0] += scan.slopeL[0][0] * subPixel;\r
+ scan.l[0][1] += scan.slopeL[0][1] * subPixel;\r
+#endif\r
+\r
#endif\r
\r
// rasterize the edge scanlines\r
line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ line.c[1][scan.left] = scan.c[1][0];\r
+ line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+ line.c[2][scan.left] = scan.c[2][0];\r
+ line.c[2][scan.right] = scan.c[2][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][scan.left] = scan.t[0][0];\r
line.t[0][scan.right] = scan.t[0][1];\r
line.t[1][scan.right] = scan.t[1][1];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ line.l[0][scan.left] = scan.l[0][0];\r
+ line.l[0][scan.right] = scan.l[0][1];\r
+#endif\r
+\r
// render a scanline\r
- scanline_bilinear ();\r
+ fragmentShader ();\r
+ if ( EdgeTestPass & edge_test_first_line ) break;\r
+\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0];\r
+ scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+ scan.c[2][0] += scan.slopeC[2][0];\r
+ scan.c[2][1] += scan.slopeC[2][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0];\r
scan.t[0][1] += scan.slopeT[0][1];\r
scan.t[1][1] += scan.slopeT[1][1];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ scan.l[0][0] += scan.slopeL[0][0];\r
+ scan.l[0][1] += scan.slopeL[0][1];\r
+#endif\r
+\r
}\r
}\r
\r
// rasterize lower sub-triangle\r
- if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+ if (F32_GREATER_0(scan.invDeltaY[2]) )\r
{\r
// advance to middle point\r
- if( (f32) 0.0 != scan.invDeltaY[1] )\r
+ if(F32_GREATER_0(scan.invDeltaY[1]) )\r
{\r
temp[0] = b->Pos.y - a->Pos.y; // dy\r
\r
#ifdef IPOL_C0\r
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
#endif\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_C2\r
+ scan.c[2][0] = a->Color[2] + scan.slopeC[2][0] * temp[0];\r
+#endif\r
#ifdef IPOL_T0\r
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
#endif\r
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ scan.l[0][0] = sVec3Pack_unpack(a->LightTangent[0]) + scan.slopeL[0][0] * temp[0];\r
+#endif\r
}\r
\r
// calculate slopes for bottom edge\r
scan.c[0][1] = b->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];\r
+ scan.c[1][1] = b->Color[1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+ scan.slopeC[2][1] = (c->Color[2] - b->Color[2]) * scan.invDeltaY[2];\r
+ scan.c[2][1] = b->Color[2];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
scan.t[0][1] = b->Tex[0];\r
scan.t[1][1] = b->Tex[1];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2];\r
+ scan.l[0][1] = b->LightTangent[0];\r
+#endif\r
+\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+ scan.c[2][0] += scan.slopeC[2][0] * subPixel;\r
+ scan.c[2][1] += scan.slopeC[2][1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ scan.l[0][0] += scan.slopeL[0][0] * subPixel;\r
+ scan.l[0][1] += scan.slopeL[0][1] * subPixel;\r
+#endif\r
+\r
#endif\r
\r
// rasterize the edge scanlines\r
line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ line.c[1][scan.left] = scan.c[1][0];\r
+ line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+ line.c[2][scan.left] = scan.c[2][0];\r
+ line.c[2][scan.right] = scan.c[2][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][scan.left] = scan.t[0][0];\r
line.t[0][scan.right] = scan.t[0][1];\r
line.t[1][scan.right] = scan.t[1][1];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ line.l[0][scan.left] = scan.l[0][0];\r
+ line.l[0][scan.right] = scan.l[0][1];\r
+#endif\r
+\r
// render a scanline\r
- scanline_bilinear ( );\r
+ fragmentShader ();\r
+ if ( EdgeTestPass & edge_test_first_line ) break;\r
+\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0];\r
+ scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+ scan.c[2][0] += scan.slopeC[2][0];\r
+ scan.c[2][1] += scan.slopeC[2][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0];\r
scan.t[0][1] += scan.slopeT[0][1];\r
scan.t[1][1] += scan.slopeT[1][1];\r
#endif\r
\r
+#ifdef IPOL_L0\r
+ scan.l[0][0] += scan.slopeL[0][0];\r
+ scan.l[0][1] += scan.slopeL[0][1];\r
+#endif\r
+\r
}\r
}\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver)\r
{\r
+ // ETR_TEXTURE_GOURAUD\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureGouraud2(driver);\r
#else\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRTextureGouraudAdd2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear ();\r
- sScanLineData line;\r
-\r
};\r
\r
//! constructor\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
f32 inversew = FIX_POINT_F32_MUL;\r
\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
u32 dIndex = ( line.y & 3 ) << 2;\r
-\r
#else\r
tFixPoint tx0;\r
tFixPoint ty0;\r
\r
{\r
\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32(line.w[0]);\r
+#endif\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
\r
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
\r
-\r
-#ifdef INVERSE_W\r
- inversew = fix_inverse32 ( line.w[0] );\r
-#endif\r
- dst[i] = PixelAdd32 (\r
- dst[i],\r
- getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),\r
- d + tofix ( line.t[0][0].y,inversew) )\r
- );\r
+ dst[i] = PixelAdd32 (\r
+ dst[i],\r
+ getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),\r
+ d + tofix ( line.t[0][0].y,inversew) )\r
+ );\r
#else\r
\r
-#ifdef INVERSE_W\r
- inversew = fix_inverse32 ( line.w[0] );\r
-#endif\r
tx0 = tofix ( line.t[0][0].x,inversew);\r
ty0 = tofix ( line.t[0][0].y,inversew);\r
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + r0 ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( r1 + r0 ),\r
clampfix_maxcolor ( g1 + g0 ),\r
clampfix_maxcolor ( b1 + b0 )\r
);\r
\r
}\r
\r
-void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
- sScanConvertData scan;\r
-\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
// find if the major edge is left or right aligned\r
f32 temp[4];\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver)\r
{\r
+ //ETR_TEXTURE_GOURAUD_ADD\r
+\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureGouraudAdd2(driver);\r
#else\r
#define CMP_W\r
//#define WRITE_W\r
\r
-//#define IPOL_C0\r
+#define IPOL_C0\r
#define IPOL_T0\r
//#define IPOL_T1\r
\r
// apply global override\r
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
- #undef INVERSE_W\r
- #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
- #undef IPOL_W\r
- #endif\r
+#undef INVERSE_W\r
#endif\r
\r
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL\r
- #undef SUBTEXEL\r
+#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
- #undef IPOL_C0\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+#undef IPOL_C0\r
#endif\r
\r
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
- #define IPOL_Z\r
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+#undef IPOL_W\r
+#endif\r
+#define IPOL_Z\r
\r
- #ifdef CMP_W\r
- #undef CMP_W\r
- #define CMP_Z\r
- #endif\r
+#ifdef CMP_W\r
+#undef CMP_W\r
+#define CMP_Z\r
+#endif\r
\r
- #ifdef WRITE_W\r
- #undef WRITE_W\r
- #define WRITE_Z\r
- #endif\r
+#ifdef WRITE_W\r
+#undef WRITE_W\r
+#define WRITE_Z\r
+#endif\r
\r
#endif\r
\r
CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
- void scanline_bilinear ();\r
- sScanConvertData scan;\r
- sScanLineData line;\r
+ void fragmentShader();\r
\r
};\r
\r
\r
/*!\r
*/\r
-void CTRTextureGouraudAddNoZ2::scanline_bilinear ()\r
+void CTRTextureGouraudAddNoZ2::fragmentShader()\r
{\r
tVideoSample *dst;\r
\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
-\r
if ( dx < 0 )\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
#endif\r
#ifdef IPOL_C0\r
- slopeC = (line.c[1] - line.c[0]) * invDeltaX;\r
+ slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
#endif\r
#ifdef IPOL_T0\r
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
line.w[0] += slopeW * subPixel;\r
#endif\r
#ifdef IPOL_C0\r
- line.c[0] += slopeC * subPixel;\r
+ line.c[0][0] += slopeC * subPixel;\r
#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0] * subPixel;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
tFixPoint r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
\r
+#ifdef IPOL_C0\r
+ tFixPoint r2, g2, b2;\r
+#endif\r
+\r
for ( s32 i = 0; i <= dx; ++i )\r
{\r
#ifdef CMP_Z\r
if ( line.w[0] >= z[i] )\r
#endif\r
{\r
-#ifdef IPOL_W\r
+#ifdef INVERSE_W\r
inversew = fix_inverse32 ( line.w[0] );\r
#endif\r
tx0 = tofix ( line.t[0][0].x,inversew);\r
ty0 = tofix ( line.t[0][0].y,inversew);\r
\r
- getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
-\r
- color_to_fix ( r1, g1, b1, dst[i] );\r
+ getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + (r0 >> 1 ) ),\r
- clampfix_maxcolor ( g1 + (g0 >> 1 ) ),\r
- clampfix_maxcolor ( b1 + (b0 >> 1) )\r
- );\r
+#ifdef IPOL_C0\r
+ vec4_to_fix(r2, g2, b2, line.c[0][0], inversew);\r
+ r0 = imulFix(r2, r0);\r
+ g0 = imulFix(g2, g0);\r
+ b0 = imulFix(b2, b0);\r
+#endif\r
+ \r
+ //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);\r
+ if (r0 | g0 | b0)\r
+ {\r
+ color_to_fix(r1, g1, b1, dst[i]);\r
+ r1 = imulFix_tex1(r1, FIXPOINT_COLOR_MAX - r0);\r
+ g1 = imulFix_tex1(g1, FIXPOINT_COLOR_MAX - g0);\r
+ b1 = imulFix_tex1(b1, FIXPOINT_COLOR_MAX - b0);\r
+ dst[i] = fix_to_sample(r0+r1, g0+g1, b0+b1);\r
+ }\r
\r
#ifdef WRITE_Z\r
z[i] = line.z[0];\r
line.w[0] += slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- line.c[0] += slopeC;\r
+ line.c[0][0] += slopeC;\r
#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0];\r
\r
}\r
\r
-void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
+ //billboard discard\r
+ //if (a->Color[0].r <= 0.f) return;\r
+\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
#ifdef IPOL_C0\r
- scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
- scan.c[0] = a->Color[0];\r
+ scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
+ scan.c[0][0] = a->Color[0];\r
#endif\r
\r
#ifdef IPOL_T0\r
#endif\r
\r
// rasterize upper sub-triangle\r
- if ( (f32) 0.0 != scan.invDeltaY[1] )\r
+ if (F32_GREATER_0(scan.invDeltaY[1]) )\r
{\r
// calculate slopes for top edge\r
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
#endif\r
\r
#ifdef IPOL_C0\r
- scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
- scan.c[1] = a->Color[0];\r
+ scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
+ scan.c[0][1] = a->Color[0];\r
#endif\r
\r
#ifdef IPOL_T0\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
#ifdef IPOL_C0\r
- scan.c[0] += scan.slopeC[0] * subPixel;\r
- scan.c[1] += scan.slopeC[1] * subPixel;\r
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
#ifdef IPOL_T0\r
#endif\r
\r
#ifdef IPOL_C0\r
- line.c[scan.left] = scan.c[0];\r
- line.c[scan.right] = scan.c[1];\r
+ line.c[0][scan.left] = scan.c[0][0];\r
+ line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
#ifdef IPOL_T0\r
#endif\r
\r
// render a scanline\r
- scanline_bilinear ();\r
+ fragmentShader();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
#endif\r
\r
#ifdef IPOL_C0\r
- scan.c[0] += scan.slopeC[0];\r
- scan.c[1] += scan.slopeC[1];\r
+ scan.c[0][0] += scan.slopeC[0][0];\r
+ scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
#ifdef IPOL_T0\r
}\r
\r
// rasterize lower sub-triangle\r
- if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+ if (F32_GREATER_0(scan.invDeltaY[2]) )\r
{\r
// advance to middle point\r
- if( (f32) 0.0 != scan.invDeltaY[1] )\r
+ if(F32_GREATER_0(scan.invDeltaY[1]) )\r
{\r
temp[0] = b->Pos.y - a->Pos.y; // dy\r
\r
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
#endif\r
#ifdef IPOL_C0\r
- scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];\r
+ scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
#endif\r
#ifdef IPOL_T0\r
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
#endif\r
\r
#ifdef IPOL_C0\r
- scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
- scan.c[1] = b->Color[0];\r
+ scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
+ scan.c[0][1] = b->Color[0];\r
#endif\r
\r
#ifdef IPOL_T0\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
#endif\r
\r
#ifdef IPOL_C0\r
- scan.c[0] += scan.slopeC[0] * subPixel;\r
- scan.c[1] += scan.slopeC[1] * subPixel;\r
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
#ifdef IPOL_T0\r
#endif\r
\r
#ifdef IPOL_C0\r
- line.c[scan.left] = scan.c[0];\r
- line.c[scan.right] = scan.c[1];\r
+ line.c[0][scan.left] = scan.c[0][0];\r
+ line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
#ifdef IPOL_T0\r
#endif\r
\r
// render a scanline\r
- scanline_bilinear ( );\r
+ fragmentShader( );\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
#endif\r
\r
#ifdef IPOL_C0\r
- scan.c[0] += scan.slopeC[0];\r
- scan.c[1] += scan.slopeC[1];\r
+ scan.c[0][0] += scan.slopeC[0][0];\r
+ scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
#ifdef IPOL_T0\r
//! creates a flat triangle renderer\r
IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)\r
{\r
+ /*\r
+ ETR_TEXTURE_GOURAUD_ADD_NO_Z\r
+ \r
+ Irrlicht:\r
+ Material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;\r
+ Material.ZBuffer = ECFN_DISABLED;\r
+ -> need Material.ZWriteEnable off\r
+\r
+ OpenGL\r
+ glDisable(GL_DEPTH_TEST);\r
+ glDepthMask(GL_FALSE);\r
+ glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);\r
+ */\r
+\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureGouraudAddNoZ2(driver);\r
#else\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRTextureGouraudAlpha2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
-\r
- virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;\r
-\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
\r
private:\r
void scanline_bilinear ();\r
\r
- sScanConvertData scan;\r
- sScanLineData line;\r
-\r
- u32 AlphaRef;\r
};\r
\r
//! constructor\r
#ifdef _DEBUG\r
setDebugName("CTRTextureGouraudAlpha2");\r
#endif\r
-\r
- AlphaRef = 0;\r
}\r
\r
\r
/*!\r
*/\r
-void CTRTextureGouraudAlpha2::setParam ( u32 index, f32 value)\r
+void CTRTextureGouraudAlpha2::OnSetMaterial(const SBurningShaderMaterial& material)\r
{\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
- AlphaRef = core::floor32_fast( value * 256.f );\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+ AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);\r
#else\r
- AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) );\r
+ AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);\r
#endif\r
}\r
\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
f32 inversew = FIX_POINT_F32_MUL;\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
- u32 dIndex = ( line.y & 3 ) << 2;\r
-\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+ u32 dIndex = (line.y & 3) << 2;\r
#else\r
- tFixPoint a0;\r
- tFixPoint r0, g0, b0;\r
-#endif\r
+ tFixPoint a0, r0, g0, b0;\r
\r
#ifdef IPOL_C0\r
tFixPoint r1, g1, b1;\r
tFixPoint r2, g2, b2;\r
+#endif\r
#endif\r
\r
for ( s32 i = 0; i <= dx; ++i )\r
\r
{\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
\r
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
\r
d + tofix ( line.t[0][0].y,inversew)\r
);\r
\r
- const u32 alpha = ( argb >> 24 );\r
+ const tFixPoint alpha = ( argb >> 24 );\r
if ( alpha > AlphaRef )\r
{\r
#ifdef WRITE_Z\r
\r
#ifdef INVERSE_W\r
inversew = fix_inverse32 ( line.w[0] );\r
+#endif\r
getSample_texture ( a0,r0,g0,b0,\r
&IT[0],\r
tofix ( line.t[0][0].x,inversew),\r
tofix ( line.t[0][0].y,inversew)\r
);\r
-#else\r
- getSample_texture ( a0,r0,g0,b0,\r
- &IT[0],\r
- tofix ( line.t[0][0].x),\r
- tofix ( line.t[0][0].y)\r
- );\r
-#endif\r
- if ( (tFixPointu) a0 > AlphaRef )\r
+\r
+ if ( a0 > AlphaRef )\r
{\r
#ifdef WRITE_Z\r
z[i] = line.z[0];\r
z[i] = line.w[0];\r
#endif\r
\r
-#ifdef INVERSE_W\r
- getSample_color ( r2, g2, b2, line.c[0][0], inversew );\r
-#else\r
- getSample_color ( r2, g2, b2, line.c[0][0] );\r
-#endif\r
- r0 = imulFix ( r0, r2 );\r
- g0 = imulFix ( g0, g2 );\r
- b0 = imulFix ( b0, b2 );\r
+#ifdef IPOL_C0\r
+\r
+ vec4_to_fix( r2, g2, b2, line.c[0][0], inversew );\r
+\r
+ r0 = imulFix_simple( r0, r2 );\r
+ g0 = imulFix_simple( g0, g2 );\r
+ b0 = imulFix_simple( b0, b2 );\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
- a0 >>= 8;\r
+ fix_color_norm(a0);\r
\r
r2 = r1 + imulFix ( a0, r0 - r1 );\r
g2 = g1 + imulFix ( a0, g0 - g1 );\r
b2 = b1 + imulFix ( a0, b0 - b1 );\r
- dst[i] = fix4_to_color ( a0, r2, g2, b2 );\r
+ dst[i] = fix4_to_sample( a0, r2, g2, b2 );\r
\r
-/*\r
- dst[i] = PixelBlend32 ( dst[i],\r
- fix_to_color ( r0,g0, b0 ),\r
- fixPointu_to_u32 ( a0 )\r
- );\r
-*/\r
/*\r
getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );\r
color_to_fix ( r1, g1, b1, dst[i] );\r
r2 = r0 + imulFix ( a0, r1 - r0 );\r
g2 = g0 + imulFix ( a0, g1 - g0 );\r
b2 = b0 + imulFix ( a0, b1 - b0 );\r
- dst[i] = fix_to_color ( r2, g2, b2 );\r
+ dst[i] = fix_to_sample ( r2, g2, b2 );\r
*/\r
-\r
+#else\r
+ dst[i] = PixelBlend32 ( dst[i],\r
+ fix_to_sample( r0,g0, b0 ),\r
+ fixPointu_to_u32 ( a0 )\r
+ );\r
+#endif\r
}\r
#endif\r
\r
\r
}\r
\r
-void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver)\r
{\r
+ //ETR_TEXTURE_GOURAUD_ALPHA\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureGouraudAlpha2(driver);\r
#else\r
#undef INVERSE_W\r
\r
#undef IPOL_C0\r
+#undef IPOL_C1\r
#undef IPOL_T0\r
#undef IPOL_T1\r
\r
//#define WRITE_W\r
\r
#define IPOL_C0\r
+//#define IPOL_C1\r
#define IPOL_T0\r
//#define IPOL_T1\r
\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
+#if BURNING_MATERIAL_MAX_COLORS < 2\r
+ #undef IPOL_C1\r
+#endif\r
+\r
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
#undef IPOL_W\r
CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
+\r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
+ SBurningShaderMaterial Material;\r
\r
- virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;\r
+ virtual void setMaterial(const SBurningShaderMaterial &material)\r
+ {\r
+ Material = material;\r
+ }\r
\r
+ virtual void setParam(u32 index, f32 value)\r
+ {\r
+ OnSetMaterial(Material);\r
+}\r
+#endif\r
\r
private:\r
- void scanline_bilinear ();\r
\r
- sScanConvertData scan;\r
- sScanLineData line;\r
+ // fragment shader\r
+ typedef void (CTRTextureGouraudAlphaNoZ::*tFragmentShader) ();\r
+ void fragment_linear();\r
+ void fragment_linear_test();\r
+ void fragment_point_noz();\r
+\r
+ tFragmentShader fragmentShader;\r
+\r
\r
- u32 AlphaRef;\r
};\r
\r
//! constructor\r
setDebugName("CTRTextureGouraudAlphaNoZ");\r
#endif\r
\r
- AlphaRef = 0;\r
+ fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;\r
}\r
\r
\r
/*!\r
*/\r
-void CTRTextureGouraudAlphaNoZ::setParam ( u32 index, f32 value)\r
+void CTRTextureGouraudAlphaNoZ::OnSetMaterial(const SBurningShaderMaterial& material)\r
{\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
- AlphaRef = core::floor32_fast( value * 256.f );\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+ AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);\r
#else\r
- AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) );\r
+ AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);\r
#endif\r
+\r
+ //check triangle on w = 1.f instead..\r
+#ifdef SOFTWARE_DRIVER_2_BILINEAR\r
+ if (material.Fallback_MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)\r
+ fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear_test;\r
+ else\r
+ if ( material.org.TextureLayer[0].BilinearFilter )\r
+ fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;\r
+ else\r
+\r
+#endif\r
+ fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_point_noz;\r
+\r
}\r
\r
/*!\r
*/\r
-void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()\r
+void CTRTextureGouraudAlphaNoZ::fragment_linear()\r
{\r
tVideoSample *dst;\r
\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#ifdef IPOL_C0\r
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
#endif\r
+#ifdef IPOL_C1\r
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
#ifdef IPOL_T0\r
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
#endif\r
#ifdef IPOL_C0\r
line.c[0][0] += slopeC[0] * subPixel;\r
#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0] * subPixel;\r
#endif\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
f32 inversew = FIX_POINT_F32_MUL;\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
u32 dIndex = ( line.y & 3 ) << 2;\r
\r
#else\r
\r
#ifdef IPOL_C0\r
tFixPoint r1, g1, b1;\r
- tFixPoint r2, g2, b2;\r
+ tFixPoint a2,r2, g2, b2;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+ tFixPoint a3,r3, g3, b3;\r
#endif\r
\r
for ( s32 i = 0; i <= dx; ++i )\r
\r
{\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
\r
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
\r
d + tofix ( line.t[0][0].y,inversew)\r
);\r
\r
- const u32 alpha = ( argb >> 24 );\r
+ const tFixPoint alpha = ( argb >> 24 );\r
if ( alpha > AlphaRef )\r
{\r
#ifdef WRITE_Z\r
\r
#ifdef INVERSE_W\r
inversew = fix_inverse32 ( line.w[0] );\r
+#endif\r
getSample_texture ( a0, r0, g0, b0,\r
&IT[0],\r
tofix ( line.t[0][0].x,inversew),\r
tofix ( line.t[0][0].y,inversew)\r
);\r
-#else\r
- getSample_texture ( a0, r0, g0,b0,\r
- &IT[0],\r
- tofix ( line.t[0][0].x),\r
- tofix ( line.t[0][0].y)\r
- );\r
-#endif\r
- if ( (tFixPointu) a0 > AlphaRef )\r
+\r
+ if ( a0 > AlphaRef )\r
{\r
#ifdef WRITE_Z\r
z[i] = line.z[0];\r
z[i] = line.w[0];\r
#endif\r
\r
-#ifdef INVERSE_W\r
- getSample_color ( r2, g2, b2, line.c[0][0], inversew );\r
-#else\r
- getSample_color ( r2, g2, b2, line.c[0][0] );\r
-#endif\r
- r0 = imulFix ( r0, r2 );\r
- g0 = imulFix ( g0, g2 );\r
- b0 = imulFix ( b0, b2 );\r
+#ifdef IPOL_C0\r
+\r
+ vec4_to_fix( a2,r2, g2, b2, line.c[0][0], inversew );\r
+\r
+ //a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha\r
+ r0 = imulFix_simple( r0, r2 );\r
+ g0 = imulFix_simple( g0, g2 );\r
+ b0 = imulFix_simple( b0, b2 );\r
\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
- a0 >>= 8;\r
+ fix_color_norm(a0);\r
\r
r2 = r1 + imulFix ( a0, r0 - r1 );\r
g2 = g1 + imulFix ( a0, g0 - g1 );\r
b2 = b1 + imulFix ( a0, b0 - b1 );\r
- dst[i] = fix4_to_color ( a0, r2, g2, b2 );\r
+ dst[i] = fix4_to_sample( a0, r2, g2, b2 );\r
\r
-/*\r
+#else\r
dst[i] = PixelBlend32 ( dst[i],\r
- fix_to_color ( r0,g0, b0 ),\r
+ fix_to_sample( r0,g0, b0 ),\r
fixPointu_to_u32 ( a0 )\r
);\r
-*/\r
-/*\r
- getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );\r
- color_to_fix ( r1, g1, b1, dst[i] );\r
-\r
- r2 = r0 + imulFix ( a0, r1 - r0 );\r
- g2 = g0 + imulFix ( a0, g1 - g0 );\r
- b2 = b0 + imulFix ( a0, b1 - b0 );\r
- dst[i] = fix_to_color ( r2, g2, b2 );\r
-*/\r
+#endif\r
\r
}\r
#endif\r
#ifdef IPOL_C0\r
line.c[0][0] += slopeC[0];\r
#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1];\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1];\r
+#endif\r
+ }\r
+\r
+}\r
+\r
+/*!\r
+*/\r
+void CTRTextureGouraudAlphaNoZ::fragment_linear_test()\r
+{\r
+ tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+ fp24 *z;\r
+#endif\r
+\r
+ s32 xStart;\r
+ s32 xEnd;\r
+ s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+ f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
+#endif\r
+#ifdef IPOL_T0\r
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+ // apply top-left fill-convention, left\r
+ xStart = fill_convention_left(line.x[0]);\r
+ xEnd = fill_convention_right(line.x[1]);\r
+\r
+ dx = xEnd - xStart;\r
+\r
+ if (dx < 0)\r
+ return;\r
+\r
+ // slopes\r
+ const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C1\r
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+ z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+ f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+ u32 dIndex = (line.y & 3) << 2;\r
+\r
+#else\r
+ tFixPoint a0;\r
+ tFixPoint r0, g0, b0;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ tFixPoint r1, g1, b1;\r
+ tFixPoint a2, r2, g2, b2;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+ tFixPoint a3, r3, g3, b3;\r
+#endif\r
+\r
+ for (s32 i = 0; i <= dx; ++i)\r
+ {\r
+#ifdef CMP_Z\r
+ if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+ if (line.w[0] >= z[i])\r
+#endif\r
+\r
+ {\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+\r
+ const tFixPointu d = dithermask[dIndex | (i) & 3];\r
+\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+ u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),\r
+ d + tofix(line.t[0][0].y, inversew)\r
+ );\r
+\r
+ const tFixPoint alpha = (argb >> 24);\r
+ if (alpha > AlphaRef)\r
+ {\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+#endif\r
+\r
+ dst[i] = PixelBlend32(dst[i], argb, alpha);\r
+ }\r
+\r
+\r
+#else\r
+\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+ getSample_texture(a0, r0, g0, b0,\r
+ &IT[0],\r
+ tofix(line.t[0][0].x, inversew),\r
+ tofix(line.t[0][0].y, inversew)\r
+ );\r
+\r
+ if (a0 > AlphaRef)\r
+ {\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+\r
+ vec4_to_fix(a2, r2, g2, b2, line.c[0][0], inversew);\r
+\r
+ a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha\r
+ r0 = imulFix(r0, r2);\r
+ g0 = imulFix(g0, g2);\r
+ b0 = imulFix(b0, b2);\r
+\r
+ color_to_fix(r1, g1, b1, dst[i]);\r
+\r
+ fix_color_norm(a0);\r
+\r
+ r2 = r1 + imulFix(a0, r0 - r1);\r
+ g2 = g1 + imulFix(a0, g0 - g1);\r
+ b2 = b1 + imulFix(a0, b0 - b1);\r
+ dst[i] = fix4_to_sample(a0, r2, g2, b2);\r
+\r
+#else\r
+ dst[i] = PixelBlend32(dst[i],\r
+ fix_to_sample(r0, g0, b0),\r
+ fixPointu_to_u32(a0)\r
+ );\r
+#endif\r
+\r
+ }\r
+#endif\r
+\r
+ }\r
+\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC[0];\r
+#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1];\r
+#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0];\r
#endif\r
\r
}\r
\r
-void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+\r
+/*!\r
+*/\r
+void CTRTextureGouraudAlphaNoZ::fragment_point_noz()\r
+{\r
+ tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+ //fp24 *z;\r
+#endif\r
+\r
+ s32 xStart;\r
+ s32 xEnd;\r
+ s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+ f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
+#endif\r
+#ifdef IPOL_T0\r
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+ // apply top-left fill-convention, left\r
+ xStart = fill_convention_left(line.x[0]);\r
+ xEnd = fill_convention_right(line.x[1]);\r
+\r
+ dx = xEnd - xStart;\r
+\r
+ if (dx < 0)\r
+ return;\r
+\r
+ // slopes\r
+ const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C1\r
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+ //z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+ f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+ u32 dIndex = (line.y & 3) << 2;\r
+\r
+#else\r
+ tFixPoint a0;\r
+ tFixPoint r0, g0, b0;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ tFixPoint r1, g1, b1;\r
+ tFixPoint a2,r2, g2, b2;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+ tFixPoint a3, r3, g3, b3;\r
+#endif\r
+ for (s32 i = 0; i <= dx; ++i)\r
+ {\r
+#ifdef CMP_Z\r
+ if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+// if (line.w[0] >= z[i])\r
+#endif\r
+\r
+ {\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+\r
+ const tFixPointu d = dithermask[dIndex | (i) & 3];\r
+\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+ u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),\r
+ d + tofix(line.t[0][0].y, inversew)\r
+ );\r
+\r
+ const tFixPoint alpha = (argb >> 24);\r
+ if (alpha > AlphaRef)\r
+ {\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+#endif\r
+\r
+ dst[i] = PixelBlend32(dst[i], argb, alpha);\r
+ }\r
+\r
+\r
+#else\r
+\r
+#ifdef INVERSE_W\r
+ //inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+ getTexel_fix(a0, r0, g0, b0,\r
+ &IT[0],\r
+ tofix(line.t[0][0].x, inversew),\r
+ tofix(line.t[0][0].y, inversew)\r
+ );\r
+\r
+ if (a0 > AlphaRef)\r
+ {\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ //z[i] = line.w[0];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+\r
+ vec4_to_fix(a2,r2, g2, b2, line.c[0][0], inversew);\r
+\r
+ a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha\r
+ r0 = imulFix(r0, r2);\r
+ g0 = imulFix(g0, g2);\r
+ b0 = imulFix(b0, b2);\r
+\r
+ color_to_fix(r1, g1, b1, dst[i]);\r
+\r
+ fix_color_norm(a0);\r
+\r
+ r2 = r1 + imulFix(a0, r0 - r1);\r
+ g2 = g1 + imulFix(a0, g0 - g1);\r
+ b2 = b1 + imulFix(a0, b0 - b1);\r
+ dst[i] = fix4_to_sample(a0, r2, g2, b2);\r
+\r
+#else\r
+ dst[i] = PixelBlend32(dst[i],\r
+ fix_to_sample(r0, g0, b0),\r
+ fixPointu_to_u32(a0)\r
+ );\r
+#endif\r
+\r
+ }\r
+#endif\r
+\r
+ }\r
+\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ //line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC[0];\r
+#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1];\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1];\r
+#endif\r
+ }\r
+\r
+}\r
+\r
+void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
scan.c[0][0] = a->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];\r
+ scan.c[1][0] = a->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
scan.t[0][0] = a->Tex[0];\r
scan.c[0][1] = a->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];\r
+ scan.c[1][1] = a->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
scan.t[0][1] = a->Tex[0];\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ line.c[1][scan.left] = scan.c[1][0];\r
+ line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][scan.left] = scan.t[0][0];\r
line.t[0][scan.right] = scan.t[0][1];\r
#endif\r
\r
// render a scanline\r
- scanline_bilinear ( );\r
+ (this->*fragmentShader) ();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0];\r
+ scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0];\r
scan.t[0][1] += scan.slopeT[0][1];\r
#ifdef IPOL_C0\r
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
#endif\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
#endif\r
scan.c[0][1] = b->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];\r
+ scan.c[1][1] = b->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
scan.t[0][1] = b->Tex[0];\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ line.c[1][scan.left] = scan.c[1][0];\r
+ line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][scan.left] = scan.t[0][0];\r
line.t[0][scan.right] = scan.t[0][1];\r
#endif\r
\r
// render a scanline\r
- scanline_bilinear ( );\r
+ (this->*fragmentShader) ();\r
\r
scan.x[0] += scan.slopeX[0];\r
scan.x[1] += scan.slopeX[1];\r
scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0];\r
+ scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0];\r
scan.t[0][1] += scan.slopeT[0][1];\r
//! creates a flat triangle renderer\r
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)\r
{\r
+ // ETR_TEXTURE_GOURAUD_ALPHA_NOZ\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureGouraudAlphaNoZ(driver);\r
#else\r
}\r
\r
\r
+\r
} // end namespace video\r
} // end namespace irr\r
\r
#define IPOL_T0\r
//#define IPOL_T1\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRTextureGouraudNoZ2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear ();\r
- sScanConvertData scan;\r
- sScanLineData line;\r
\r
};\r
\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
tFixPoint tx0;\r
tFixPoint ty0;\r
-\r
+ tFixPoint r0, g0, b0;\r
\r
for ( s32 i = 0; i <= dx; ++i )\r
{\r
#endif\r
tx0 = tofix ( line.t[0][0].x,inversew);\r
ty0 = tofix ( line.t[0][0].y,inversew);\r
- dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );\r
+ //skybox\r
+ //dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );\r
+\r
+ getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 );\r
+ dst[i] = fix_to_sample( r0, g0, b0 );\r
\r
-/*\r
- getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );\r
- dst[i] = fix_to_color ( r0, g0, b0 );\r
-*/\r
#ifdef WRITE_Z\r
z[i] = line.z[0];\r
#endif\r
\r
}\r
\r
-void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver)\r
{\r
+ // ETR_TEXTURE_GOURAUD_NOZ\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureGouraudNoZ2( driver );\r
#else\r
#undef INVERSE_W\r
\r
#undef IPOL_C0\r
+#undef IPOL_C1\r
#undef IPOL_T0\r
#undef IPOL_T1\r
\r
//#define WRITE_W\r
\r
#define IPOL_C0\r
+#define IPOL_C1\r
#define IPOL_T0\r
//#define IPOL_T1\r
\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
+#if BURNING_MATERIAL_MAX_COLORS < 2\r
+ #undef IPOL_C1\r
+#endif\r
+\r
+\r
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
#undef IPOL_W\r
CTRTextureVertexAlpha2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear ();\r
- sScanConvertData scan;\r
- sScanLineData line;\r
\r
};\r
\r
fp24 slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- sVec4 slopeC;\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
#endif\r
#ifdef IPOL_T0\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
#endif\r
#ifdef IPOL_C0\r
- slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+ slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C1\r
+ slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
#endif\r
#ifdef IPOL_T0\r
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
line.w[0] += slopeW * subPixel;\r
#endif\r
#ifdef IPOL_C0\r
- line.c[0][0] += slopeC * subPixel;\r
+ line.c[0][0] += slopeC[0] * subPixel;\r
#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0] * subPixel;\r
#endif\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
\r
f32 inversew = FIX_POINT_F32_MUL;\r
\r
-//#define __TEST_THIS\r
-\r
-#ifdef __TEST_THIS\r
-\r
-#else\r
tFixPoint tx0;\r
tFixPoint ty0;\r
\r
tFixPoint r0, g0, b0;\r
tFixPoint r1, g1, b1;\r
- tFixPoint r2, g2, b2;\r
-#endif\r
-\r
\r
#ifdef IPOL_C0\r
- tFixPoint a3;\r
+ tFixPoint a2,r2, g2, b2;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+ tFixPoint aFog = FIX_POINT_ONE;\r
#endif\r
\r
\r
#endif\r
\r
{\r
-#ifdef __TEST_THIS\r
-\r
- inversew = fix_inverse32 ( line.w[0] );\r
-\r
- dst[i] = PixelAdd32 (\r
- dst[i],\r
- getTexel_plain ( &IT[0], tofix ( line.t[0][0].x,inversew),\r
- tofix ( line.t[0][0].y,inversew) )\r
- );\r
-\r
-#else\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+#endif\r
\r
#ifdef INVERSE_W\r
inversew = fix_inverse32 ( line.w[0] );\r
+#endif\r
+#ifdef IPOL_C1\r
+ //complete inside fog\r
+ if (TL_Flag & TL_FOG)\r
+ {\r
+ aFog = tofix(line.c[1][0].a, inversew);\r
+ if (aFog <= 0)\r
+ {\r
+ dst[i] = fog_color_sample;\r
+ continue;\r
+ }\r
+ }\r
#endif\r
tx0 = tofix ( line.t[0][0].x,inversew);\r
ty0 = tofix ( line.t[0][0].y,inversew);\r
\r
-#ifdef IPOL_C0\r
- a3 = tofix ( line.c[0][0].y,inversew );\r
-#endif\r
-\r
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );\r
color_to_fix ( r1, g1, b1, dst[i] );\r
\r
#ifdef IPOL_C0\r
- r2 = clampfix_maxcolor ( r1 + imulFix ( r0, a3 ) );\r
- g2 = clampfix_maxcolor ( g1 + imulFix ( g0, a3 ) );\r
- b2 = clampfix_maxcolor ( b1 + imulFix ( b0, a3 ) );\r
+ vec4_to_fix(a2,r2, g2, b2, line.c[0][0], inversew);\r
+\r
+ r0 = imulFix_simple(r0, r2);\r
+ g0 = imulFix_simple(g0, g2);\r
+ b0 = imulFix_simple(b0, b2);\r
+\r
+#ifdef IPOL_C1\r
+ //specular highlight\r
+ if (TL_Flag & TL_SPECULAR)\r
+ {\r
+ vec4_to_fix(r2, g2, b2, line.c[1][0], inversew*COLOR_MAX);\r
+ r0 = clampfix_maxcolor(r2 + r0);\r
+ g0 = clampfix_maxcolor(g2 + g0);\r
+ b0 = clampfix_maxcolor(b2 + b0);\r
+ }\r
+#endif\r
+ //blend background\r
+ r0 = r1 + imulFix(a2, r0 - r1);\r
+ g0 = g1 + imulFix(a2, g0 - g1);\r
+ b0 = b1 + imulFix(a2, b0 - b1);\r
+\r
+#ifdef IPOL_C1\r
+ //mix with distance\r
+ if (aFog < FIX_POINT_ONE) //TL_Flag & TL_FOG)\r
+ {\r
+ r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);\r
+ g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);\r
+ b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);\r
+ }\r
+#endif\r
+\r
#else\r
- r2 = clampfix_maxcolor ( r1 + r0 );\r
- g2 = clampfix_maxcolor ( g1 + g0 );\r
- b2 = clampfix_maxcolor ( b1 + b0 );\r
+ r0 = clampfix_maxcolor ( r1 + r0 );\r
+ g0 = clampfix_maxcolor ( g1 + g0 );\r
+ b0 = clampfix_maxcolor ( b1 + b0 );\r
#endif\r
\r
- dst[i] = fix_to_color ( r2, g2, b2 );\r
+ dst[i] = fix_to_sample( r0, g0, b0 );\r
\r
-#ifdef WRITE_Z\r
- z[i] = line.z[0];\r
-#endif\r
-#ifdef WRITE_W\r
- z[i] = line.w[0];\r
-#endif\r
-#endif\r
}\r
\r
#ifdef IPOL_Z\r
line.w[0] += slopeW;\r
#endif\r
#ifdef IPOL_C0\r
- line.c[0][0] += slopeC;\r
+ line.c[0][0] += slopeC[0];\r
+#endif\r
+#ifdef IPOL_C1\r
+ line.c[1][0] += slopeC[1];\r
#endif\r
#ifdef IPOL_T0\r
line.t[0][0] += slopeT[0];\r
\r
}\r
\r
-void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
scan.c[0][0] = a->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];\r
+ scan.c[1][0] = a->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
scan.t[0][0] = a->Tex[0];\r
scan.c[0][1] = a->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];\r
+ scan.c[1][1] = a->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
scan.t[0][1] = a->Tex[0];\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ line.c[1][scan.left] = scan.c[1][0];\r
+ line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][scan.left] = scan.t[0][0];\r
line.t[0][scan.right] = scan.t[0][1];\r
scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0];\r
+ scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0];\r
scan.t[0][1] += scan.slopeT[0][1];\r
#ifdef IPOL_C0\r
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
#endif\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];\r
+#endif\r
#ifdef IPOL_T0\r
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
#endif\r
scan.c[0][1] = b->Color[0];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];\r
+ scan.c[1][1] = b->Color[1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
scan.t[0][1] = b->Tex[0];\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+ scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
line.c[0][scan.right] = scan.c[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ line.c[1][scan.left] = scan.c[1][0];\r
+ line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
line.t[0][scan.left] = scan.t[0][0];\r
line.t[0][scan.right] = scan.t[0][1];\r
scan.c[0][1] += scan.slopeC[0][1];\r
#endif\r
\r
+#ifdef IPOL_C1\r
+ scan.c[1][0] += scan.slopeC[1][0];\r
+ scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
#ifdef IPOL_T0\r
scan.t[0][0] += scan.slopeT[0][0];\r
scan.t[0][1] += scan.slopeT[0][1];\r
//! creates a flat triangle renderer\r
IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver)\r
{\r
+ /* ETR_TEXTURE_GOURAUD_VERTEX_ALPHA */\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureVertexAlpha2(driver);\r
#else\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRTextureLightMap2_Add(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear ();\r
\r
- sScanConvertData scan;\r
- sScanLineData line;\r
-\r
};\r
\r
//! constructor\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
#endif\r
\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
f32 inversew = FIX_POINT_F32_MUL;\r
- u32 dIndex = ( line.y & 3 ) << 2;\r
-\r
\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+ u32 dIndex = ( line.y & 3 ) << 2;\r
#else\r
//\r
tFixPoint r0, g0, b0;\r
z[i] = line.w[0];\r
#endif\r
\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
-\r
#ifdef INVERSE_W\r
- inversew = fix_inverse32 ( line.w[0] );\r
+ inversew = fix_inverse32(line.w[0]);\r
#endif\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+\r
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
\r
dst[i] = PixelAdd32 (\r
);\r
\r
#else\r
- const f32 inversew = fix_inverse32 ( line.w[0] );\r
\r
getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );\r
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[0][1].x,inversew), tofix ( line.t[0][1].y,inversew) );\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( r0 + r1 ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( r0 + r1 ),\r
clampfix_maxcolor ( g0 + g1 ),\r
clampfix_maxcolor ( b0 + b1 )\r
);\r
\r
}\r
\r
-void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRTextureLightMap2_M1(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear2 ();\r
\r
- sScanLineData line;\r
-\r
};\r
\r
//! constructor\r
\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
if ( dx < 0 )\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
// search z-buffer for first not occulled pixel\r
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
line.z[0] = a;\r
line.z[1] = b;\r
#endif\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
a = (f32) i + subPixel;\r
\r
#endif\r
\r
- dst[i] = fix_to_color ( imulFix_tex1 ( r0, r1 ),\r
+ dst[i] = fix_to_sample( imulFix_tex1 ( r0, r1 ),\r
imulFix_tex1 ( g0, g1 ),\r
imulFix_tex1 ( b0, b1 )\r
);\r
}\r
\r
\r
-void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
- sScanConvertData scan;\r
\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver)\r
{\r
+ //ETR_TEXTURE_GOURAUD_LIGHTMAP_M1\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureLightMap2_M1(driver);\r
#else\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRTextureLightMap2_M2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear2 ();\r
\r
- sScanLineData line;\r
-\r
};\r
\r
//! constructor\r
\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
if ( dx < 0 )\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
// search z-buffer for first not occulled pixel\r
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
line.z[0] = a;\r
line.z[1] = b;\r
#endif\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
a = (f32) i + subPixel;\r
\r
#endif\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+ dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
);\r
}\r
\r
\r
-void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
- sScanConvertData scan;\r
-\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRTextureLightMap2_M4(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
\r
- void drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );\r
- void drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );\r
-\r
- void scanline_bilinear ();\r
+#if defined(SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)\r
+ void drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );\r
+ void drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );\r
void scanline_bilinear2_mag ();\r
void scanline_bilinear2_min ();\r
+#else\r
+ #define scanline_bilinear2_mag scanline_bilinear\r
+#endif\r
\r
- sScanLineData line;\r
+ void scanline_bilinear ();\r
\r
};\r
\r
\r
/*!\r
*/\r
-REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()\r
+void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()\r
{\r
tVideoSample *dst;\r
fp24 *z;\r
\r
// apply top-left fill-convention, left\r
- const s32 xStart = irr::core::ceil32_fast( line.x[0] );\r
- const s32 xEnd = irr::core::ceil32_fast( line.x[1] ) - 1;\r
+ const s32 xStart = fill_convention_left(line.x[0]);\r
+ const s32 xEnd = fill_convention_right(line.x[1]);\r
s32 dx;\r
s32 i;\r
\r
if ( dx < 0 )\r
return;\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
// search z-buffer for first not occulled pixel\r
i = ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );\r
\r
#endif\r
-\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),\r
- clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),\r
- clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )\r
- );\r
+ dst[i] = fix_to_sample(imulFix_tex4(r0, r1), imulFix_tex4(g0, g1), imulFix_tex4(b0, b1));\r
}\r
\r
#ifdef IPOL_W\r
}\r
\r
\r
-REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()\r
+#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)\r
+void CTRTextureLightMap2_M4::scanline_bilinear2_min ()\r
{\r
tVideoSample *dst;\r
fp24 *z;\r
\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left(line.x[0]);\r
+ xEnd = fill_convention_right(line.x[1]);\r
\r
dx = xEnd - xStart;\r
if ( dx < 0 )\r
return;\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
// search z-buffer for first not occulled pixel\r
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
line.z[0] = a;\r
line.z[1] = b;\r
#endif\r
+\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
a = (f32) i + subPixel;\r
getTexel_fix ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );\r
getTexel_fix ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );\r
\r
- dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),\r
- clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),\r
- clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )\r
- );\r
+ dst[i] = fix_to_sample(imulFix_tex4(r0, r1), imulFix_tex4(g0, g1), imulFix_tex4(b0, b1));\r
}\r
\r
#ifdef IPOL_W\r
\r
}\r
\r
-//#ifdef BURNINGVIDEO_RENDERER_FAST\r
-#if 1\r
-\r
-void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
- if ( IT[0].lodLevel <= 2 )\r
- drawTriangle_Mag ( a, b, c );\r
+ if (IT[0].lodFactor < 4)\r
+ {\r
+ drawTriangle_Mag(a, b, c);\r
+ }\r
else\r
- drawTriangle_Min ( a, b, c );\r
+ {\r
+ drawTriangle_Min(a, b, c);\r
+ }\r
}\r
\r
-void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )\r
{\r
- sScanConvertData scan;\r
-\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
\r
}\r
\r
-void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )\r
\r
-#else\r
+#else //#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)\r
\r
-void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
\r
#endif\r
\r
{\r
- sScanConvertData scan;\r
\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ca = c->Pos.y - a->Pos.y;\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
- // calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
\r
- if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
+ if ( F32_LOWER_EQUAL_0 ( ca ) )\r
return;\r
\r
+ // calculate delta y of the edges\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
+\r
+ //if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
+ // return;\r
+\r
// find if the major edge is left or right aligned\r
f32 temp[4];\r
\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
\r
}\r
\r
+#undef scanline_bilinear2_mag\r
+\r
} // end namespace video\r
} // end namespace irr\r
\r
#undef SUBTEXEL\r
#endif\r
\r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
#undef IPOL_C0\r
#endif\r
\r
CTRGTextureLightMap2_M4(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
\r
\r
private:\r
void scanline_bilinear ();\r
\r
- sScanConvertData scan;\r
- sScanLineData line;\r
-\r
};\r
\r
//! constructor\r
#endif\r
\r
// apply top-left fill-convention, left\r
- xStart = core::ceil32_fast( line.x[0] );\r
- xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
\r
dx = xEnd - xStart;\r
\r
return;\r
\r
// slopes\r
- const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
\r
#ifdef IPOL_Z\r
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
#endif\r
#endif\r
\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
\r
#ifdef USE_ZBUFFER\r
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );\r
\r
#ifdef IPOL_C0\r
- r2 = imulFix ( r0, r3 );\r
- g2 = imulFix ( g0, g3 );\r
- b2 = imulFix ( b0, b3 );\r
-\r
- r2 = clampfix_maxcolor ( imulFix_tex4 ( r2, r1 ) );\r
- g2 = clampfix_maxcolor ( imulFix_tex4 ( g2, g1 ) );\r
- b2 = clampfix_maxcolor ( imulFix_tex4 ( b2, b1 ) );\r
-/*\r
- r2 = r3 << 8;\r
- g2 = g3 << 8;\r
- b2 = b3 << 8;\r
-*/\r
+ r2 = imulFix_simple( r0, r3 );\r
+ g2 = imulFix_simple( g0, g3 );\r
+ b2 = imulFix_simple( b0, b3 );\r
+\r
+ r2 = imulFix_tex4 ( r2, r1 );\r
+ g2 = imulFix_tex4 ( g2, g1 );\r
+ b2 = imulFix_tex4 ( b2, b1 );\r
+\r
#else\r
- r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );\r
- g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );\r
- b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );\r
+ r2 = imulFix_tex4 ( r0, r1 );\r
+ g2 = imulFix_tex4 ( g0, g1 );\r
+ b2 = imulFix_tex4 ( b0, b1 );\r
#endif\r
\r
\r
- dst[i] = fix_to_color ( r2, g2, b2 );\r
+ dst[i] = fix_to_sample( r2, g2, b2 );\r
\r
#ifdef WRITE_Z\r
z[i] = line.z[0];\r
\r
}\r
\r
-void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
const f32 ba = b->Pos.y - a->Pos.y;\r
const f32 cb = c->Pos.y - b->Pos.y;\r
// calculate delta y of the edges\r
- scan.invDeltaY[0] = core::reciprocal( ca );\r
- scan.invDeltaY[1] = core::reciprocal( ba );\r
- scan.invDeltaY[2] = core::reciprocal( cb );\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
\r
if ( F32_LOWER_0 ( scan.invDeltaY[0] ) )\r
return;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( a->Pos.y );\r
- yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
\r
#ifdef SUBTEXEL\r
subPixel = ( (f32) yStart ) - a->Pos.y;\r
#endif\r
\r
// apply top-left fill convention, top part\r
- yStart = core::ceil32_fast( b->Pos.y );\r
- yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
\r
#ifdef SUBTEXEL\r
\r
#define SUBTEXEL\r
#define INVERSE_W\r
\r
-#define USE_ZBUFFER\r
+//#define USE_ZBUFFER\r
#define IPOL_W\r
-#define CMP_W\r
-#define WRITE_W\r
+//#define CMP_W\r
+//#define WRITE_W\r
\r
\r
-//#define IPOL_C0\r
-#define IPOL_T0\r
+#define IPOL_C0\r
+//#define IPOL_T0\r
//#define IPOL_T1\r
\r
// apply global override\r
#undef SUBTEXEL\r
#endif\r
\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+ #undef IPOL_C0\r
+#endif\r
+\r
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
#undef IPOL_W\r
CTRTextureWire2(CBurningVideoDriver* driver);\r
\r
//! draws an indexed triangle list\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) _IRR_OVERRIDE_;\r
+ virtual void drawPoint( const s4DVertex *a) _IRR_OVERRIDE_;\r
+ virtual bool canWireFrame () _IRR_OVERRIDE_ { return true; }\r
+ virtual bool canPointCloud() _IRR_OVERRIDE_ { return true; }\r
\r
+protected:\r
+ virtual void scanline_bilinear ();\r
\r
-\r
-private:\r
void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const;\r
- void renderLine ( const s4DVertex *a,const s4DVertex *b ) const;\r
+ void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const;\r
\r
};\r
\r
}\r
\r
\r
-// swap integer with xor\r
-static inline void swap_xor ( s32 &a, s32 &b )\r
-{\r
- a ^= b;\r
- b ^= a;\r
- a ^= b;\r
-}\r
-\r
\r
/*!\r
+ 2d line\r
*/\r
-void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const\r
+void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const\r
{\r
int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY;\r
+#ifdef USE_ZBUFFER\r
int pitch1 = RenderTarget->getDimension().Width << 2;\r
+#endif\r
\r
- int aposx = (int) a->Pos.x;\r
- int aposy = (int) a->Pos.y;\r
- int bposx = (int) b->Pos.x;\r
- int bposy = (int) b->Pos.y;\r
+ //todo:!\r
+ int aposx = fill_convention_none(a->Pos.x);\r
+ int aposy = fill_convention_none(a->Pos.y);\r
+ int bposx = fill_convention_none(b->Pos.x);\r
+ int bposy = fill_convention_none(b->Pos.y);\r
\r
int dx = bposx - aposx;\r
int dy = bposy - aposy;\r
int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY;\r
int yInc0 = pitch0;\r
\r
+#ifdef USE_ZBUFFER\r
int xInc1 = 4;\r
int yInc1 = pitch1;\r
-\r
- tVideoSample color;\r
-\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
- tFixPoint r0, g0, b0;\r
- getSample_color ( r0, g0, b0, a->Color[0] );\r
- color = fix_to_color ( r0, g0, b0 );\r
-#else\r
- color = (tVideoSample) 0xFFFFFFFF;\r
#endif\r
\r
if ( dx < 0 )\r
{\r
xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY);\r
+#ifdef USE_ZBUFFER\r
xInc1 = -4;\r
+#endif\r
dx = -dx;\r
}\r
\r
if ( dy > dx )\r
{\r
- swap_xor ( dx, dy );\r
- swap_xor ( xInc0, yInc0 );\r
- swap_xor ( xInc1, yInc1 );\r
+ //swap\r
+ register s32 t;\r
+ t = dx;dx=dy;dy=t;\r
+ t = xInc0;xInc0=yInc0;yInc0=t;\r
+#ifdef USE_ZBUFFER\r
+ t = xInc1;xInc1=yInc1;yInc1=t;\r
+#endif\r
}\r
\r
- if ( 0 == dx )\r
- return;\r
+ if (0 == dx)\r
+ {\r
+ if (!renderZero) return;\r
+ dx = 1;\r
+ }\r
\r
- dst = (tVideoSample*) ( (u8*) (tVideoSample*)RenderTarget->getData() + ( aposy * pitch0 ) + (aposx << VIDEO_SAMPLE_GRANULARITY ) );\r
+ SOFTWARE_DRIVER_2_CLIPCHECK_WIRE;\r
+ dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( aposy * pitch0 ) + (aposx* (1<< VIDEO_SAMPLE_GRANULARITY) ) );\r
#ifdef USE_ZBUFFER\r
z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) );\r
#endif\r
c = dx << 1;\r
m = dy << 1;\r
\r
+ // slopes\r
+ const f32 invDeltaX = reciprocal_zero2( (f32)dx );\r
+\r
#ifdef IPOL_Z\r
- f32 slopeZ = (b->Pos.z - a->Pos.z) / f32(dx);\r
+ f32 slopeZ = (b->Pos.z - a->Pos.z) * invDeltaX;\r
f32 dataZ = a->Pos.z;\r
#endif\r
\r
#ifdef IPOL_W\r
- fp24 slopeW = (b->Pos.w - a->Pos.w) / f32( dx );\r
+ fp24 slopeW = (b->Pos.w - a->Pos.w) * invDeltaX;\r
fp24 dataW = a->Pos.w;\r
#endif\r
\r
+ f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+ tVideoSample color;\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+ tFixPoint r0, g0, b0;\r
+#ifdef IPOL_C0\r
+ sVec4 slopeC;\r
+ sVec4 C;\r
+ slopeC = (b->Color[0] - a->Color[0]) * invDeltaX;\r
+ C = a->Color[0];\r
+#endif\r
+\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32_color(dataW);\r
+#endif\r
+\r
+ vec4_to_fix( r0, g0, b0, a->Color[0], inversew);\r
+ color = fix_to_sample( r0, g0, b0 );\r
+\r
+#else\r
+ color = (tVideoSample) 0xFFFFFFFF;\r
+#endif\r
+\r
+\r
run = dx;\r
while ( run )\r
{\r
*z = dataW;\r
#endif\r
\r
- *dst = color;\r
+#ifdef IPOL_C0\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32_color(dataW);\r
+#endif\r
+ vec4_to_fix(r0, g0, b0, C,inversew);\r
+ color = fix_to_sample( r0, g0, b0 );\r
+#endif\r
+ *dst = color;\r
\r
}\r
\r
dst = (tVideoSample*) ( (u8*) dst + xInc0 ); // x += xInc\r
-#ifdef IPOL_Z\r
+#ifdef CMP_Z\r
z = (fp24*) ( (u8*) z + xInc1 );\r
#endif\r
-#ifdef IPOL_W\r
+#ifdef CMP_W\r
z = (fp24*) ( (u8*) z + xInc1 );\r
#endif\r
\r
if ( d > dx )\r
{\r
dst = (tVideoSample*) ( (u8*) dst + yInc0 ); // y += yInc\r
-#ifdef IPOL_Z\r
+#ifdef CMP_Z\r
z = (fp24*) ( (u8*) z + yInc1 );\r
#endif\r
-#ifdef IPOL_W\r
+#ifdef CMP_W\r
z = (fp24*) ( (u8*) z + yInc1 );\r
#endif\r
\r
#ifdef IPOL_W\r
dataW += slopeW;\r
#endif\r
+#ifdef IPOL_C0\r
+ C += slopeC;\r
+#endif\r
+\r
\r
}\r
\r
}\r
\r
-void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureWire2::scanline_bilinear()\r
{\r
- sScanLineData line;\r
+}\r
\r
+void CTRTextureWire2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
+{\r
// sort on height, y\r
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
\r
void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b)\r
{\r
-\r
// query access to TexMaps\r
\r
// sort on height, y\r
- if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);\r
+ if (F32_A_GREATER_B(a->Pos.y,b->Pos.y )) swapVertexPointer(&a, &b);\r
\r
renderLine ( a, b );\r
+}\r
\r
+void CTRTextureWire2::drawPoint(const s4DVertex *a)\r
+{\r
+ if ( (a->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) renderLine(a, a,1);\r
}\r
\r
\r
//! creates a flat triangle renderer\r
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver)\r
{\r
+ //ETR_TEXTURE_GOURAUD_WIRE\r
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
return new CTRTextureWire2(driver);\r
#else\r
--- /dev/null
+// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten\r
+// This file is part of the "Irrlicht Engine".\r
+// For conditions of distribution and use, see copyright notice in irrlicht.h\r
+\r
+#include "IrrCompileConfig.h"\r
+#include "IBurningShader.h"\r
+\r
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+// compile flag for this file\r
+#undef USE_ZBUFFER\r
+#undef IPOL_Z\r
+#undef CMP_Z\r
+#undef WRITE_Z\r
+\r
+#undef IPOL_W\r
+#undef CMP_W\r
+#undef WRITE_W\r
+\r
+#undef SUBTEXEL\r
+#undef INVERSE_W\r
+\r
+#undef IPOL_C0\r
+#undef IPOL_T0\r
+#undef IPOL_T1\r
+\r
+// define render case\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+\r
+#define USE_ZBUFFER\r
+#define IPOL_W\r
+#define CMP_W\r
+#define WRITE_W\r
+\r
+#define IPOL_C0\r
+#define IPOL_T0\r
+#define IPOL_T1\r
+\r
+// apply global override\r
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+ #undef INVERSE_W\r
+#endif\r
+\r
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL\r
+ #undef SUBTEXEL\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+ #undef IPOL_C0\r
+#endif\r
+\r
+#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
+ #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+ #undef IPOL_W\r
+ #endif\r
+ #define IPOL_Z\r
+\r
+ #ifdef CMP_W\r
+ #undef CMP_W\r
+ #define CMP_Z\r
+ #endif\r
+\r
+ #ifdef WRITE_W\r
+ #undef WRITE_W\r
+ #define WRITE_Z\r
+ #endif\r
+\r
+#endif\r
+\r
+namespace irr\r
+{\r
+\r
+namespace video\r
+{\r
+\r
+class CTR_transparent_reflection_2_layer : public IBurningShader\r
+{\r
+public:\r
+\r
+ //! constructor\r
+ CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver);\r
+\r
+ //! draws an indexed triangle list\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
+\r
+private:\r
+ void fragmentShader();\r
+\r
+ E_MATERIAL_TYPE MaterialType;\r
+\r
+};\r
+\r
+//! constructor\r
+CTR_transparent_reflection_2_layer::CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver)\r
+: IBurningShader(driver)\r
+{\r
+ #ifdef _DEBUG\r
+ setDebugName("CTR_transparent_reflection_2_layer");\r
+ #endif\r
+}\r
+\r
+void CTR_transparent_reflection_2_layer::OnSetMaterial(const SBurningShaderMaterial& material)\r
+{\r
+ MaterialType = material.org.MaterialType;\r
+\r
+}\r
+\r
+/*!\r
+*/\r
+void CTR_transparent_reflection_2_layer::fragmentShader()\r
+{\r
+ tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+ fp24 *z;\r
+#endif\r
+\r
+ s32 xStart;\r
+ s32 xEnd;\r
+ s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+ f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ sVec4 slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+ // apply top-left fill-convention, left\r
+ xStart = fill_convention_left( line.x[0] );\r
+ xEnd = fill_convention_right( line.x[1] );\r
+\r
+ dx = xEnd - xStart;\r
+\r
+ if ( dx < 0 )\r
+ return;\r
+\r
+ // slopes\r
+ const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
+\r
+#ifdef IPOL_Z\r
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+ slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ( (f32) xStart ) - line.x[0];\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+ dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+ z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+#endif\r
+\r
+\r
+ f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+ tFixPoint r0, g0, b0;\r
+ tFixPoint r1, g1, b1;\r
+\r
+#ifdef IPOL_C0\r
+ tFixPoint a1;\r
+#endif\r
+\r
+ switch(MaterialType) {\r
+ default:\r
+ case EMT_REFLECTION_2_LAYER:\r
+ for (s32 i = 0; i <= dx; ++i)\r
+ {\r
+#ifdef CMP_Z\r
+ if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+ if (line.w[0] >= z[i])\r
+#endif\r
+ {\r
+\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+\r
+ getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));\r
+ getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));\r
+\r
+ r0 = imulFix_tex1(r0, r1);\r
+ g0 = imulFix_tex1(g0, g1);\r
+ b0 = imulFix_tex1(b0, b1);\r
+\r
+#ifdef IPOL_C0\r
+ vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);\r
+ r0 = imulFix_simple(r1, r0);\r
+ g0 = imulFix_simple(g1, g0);\r
+ b0 = imulFix_simple(b1, b0);\r
+#endif\r
+\r
+ dst[i] = fix_to_sample(r0, g0, b0);\r
+\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+#endif\r
+ }\r
+\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1];\r
+#endif\r
+ }\r
+ break;\r
+\r
+ case EMT_TRANSPARENT_REFLECTION_2_LAYER:\r
+ for (s32 i = 0; i <= dx; ++i)\r
+ {\r
+#ifdef CMP_Z\r
+ if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+ if (line.w[0] >= z[i])\r
+#endif\r
+ {\r
+\r
+#ifdef INVERSE_W\r
+ inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+\r
+ getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));\r
+ getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));\r
+\r
+ r0 = imulFix_tex1(r0, r1);\r
+ g0 = imulFix_tex1(g0, g1);\r
+ b0 = imulFix_tex1(b0, b1);\r
+\r
+#ifdef IPOL_C0\r
+ vec4_to_fix(a1, r1, g1, b1, line.c[0][0], inversew);\r
+ r0 = imulFix_simple(r1, r0);\r
+ g0 = imulFix_simple(g1, g0);\r
+ b0 = imulFix_simple(b1, b0);\r
+\r
+ //vertex alpha blend EMT_TRANSPARENT_REFLECTION_2_LAYER\r
+ if (a1 + 2 < FIX_POINT_ONE)\r
+ {\r
+ color_to_fix(r1, g1, b1, dst[i]);\r
+ r0 = r1 + imulFix(a1, r0 - r1);\r
+ g0 = g1 + imulFix(a1, g0 - g1);\r
+ b0 = b1 + imulFix(a1, b0 - b1);\r
+ }\r
+#endif\r
+\r
+ dst[i] = fix_to_sample(r0, g0, b0);\r
+\r
+#ifdef WRITE_Z\r
+ //z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ //z[i] = line.w[0];\r
+#endif\r
+ }\r
+\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1];\r
+#endif\r
+ }\r
+ break;\r
+\r
+ }\r
+\r
+\r
+}\r
+\r
+void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )\r
+{\r
+ // sort on height, y\r
+ if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
+ if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
+ if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
+\r
+ const f32 ca = c->Pos.y - a->Pos.y;\r
+ const f32 ba = b->Pos.y - a->Pos.y;\r
+ const f32 cb = c->Pos.y - b->Pos.y;\r
+ // calculate delta y of the edges\r
+ scan.invDeltaY[0] = reciprocal_zero( ca );\r
+ scan.invDeltaY[1] = reciprocal_zero( ba );\r
+ scan.invDeltaY[2] = reciprocal_zero( cb );\r
+\r
+ if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
+ return;\r
+\r
+ // find if the major edge is left or right aligned\r
+ f32 temp[4];\r
+\r
+ temp[0] = a->Pos.x - c->Pos.x;\r
+ temp[1] = -ca;\r
+ temp[2] = b->Pos.x - a->Pos.x;\r
+ temp[3] = ba;\r
+\r
+ scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;\r
+ scan.right = 1 - scan.left;\r
+\r
+ // calculate slopes for the major edge\r
+ scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];\r
+ scan.x[0] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];\r
+ scan.z[0] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];\r
+ scan.w[0] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
+ scan.c[0][0] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
+ scan.t[0][0] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];\r
+ scan.t[1][0] = a->Tex[1];\r
+#endif\r
+\r
+ // top left fill convention y run\r
+ s32 yStart;\r
+ s32 yEnd;\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+ // rasterize upper sub-triangle\r
+ if ( F32_GREATER_0(scan.invDeltaY[1]) )\r
+ {\r
+ // calculate slopes for top edge\r
+ scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
+ scan.x[1] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];\r
+ scan.z[1] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];\r
+ scan.w[1] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
+ scan.c[0][1] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
+ scan.t[0][1] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];\r
+ scan.t[1][1] = a->Tex[1];\r
+#endif\r
+\r
+ // apply top-left fill convention, top part\r
+ yStart = fill_convention_left( a->Pos.y );\r
+ yEnd = fill_convention_right( b->Pos.y );\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ( (f32) yStart ) - a->Pos.y;\r
+\r
+ // correct to pixel center\r
+ scan.x[0] += scan.slopeX[0] * subPixel;\r
+ scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0] * subPixel;\r
+ scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0] * subPixel;\r
+ scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+ // rasterize the edge scanlines\r
+ for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+ {\r
+ line.x[scan.left] = scan.x[0];\r
+ line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+ line.z[scan.left] = scan.z[0];\r
+ line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ line.w[scan.left] = scan.w[0];\r
+ line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ line.c[0][scan.left] = scan.c[0][0];\r
+ line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ line.t[0][scan.left] = scan.t[0][0];\r
+ line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ line.t[1][scan.left] = scan.t[1][0];\r
+ line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+ // render a scanline\r
+ fragmentShader();\r
+\r
+ scan.x[0] += scan.slopeX[0];\r
+ scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0];\r
+ scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0];\r
+ scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0];\r
+ scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0];\r
+ scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0];\r
+ scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+\r
+ }\r
+ }\r
+\r
+ // rasterize lower sub-triangle\r
+ if ( F32_GREATER_0(scan.invDeltaY[2]) )\r
+ {\r
+ // advance to middle point\r
+ if( F32_GREATER_0(scan.invDeltaY[1]) )\r
+ {\r
+ temp[0] = b->Pos.y - a->Pos.y; // dy\r
+\r
+ scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];\r
+#ifdef IPOL_Z\r
+ scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_W\r
+ scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];\r
+#endif\r
+\r
+ }\r
+\r
+ // calculate slopes for bottom edge\r
+ scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];\r
+ scan.x[1] = b->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];\r
+ scan.z[1] = b->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];\r
+ scan.w[1] = b->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
+ scan.c[0][1] = b->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
+ scan.t[0][1] = b->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];\r
+ scan.t[1][1] = b->Tex[1];\r
+#endif\r
+\r
+ // apply top-left fill convention, top part\r
+ yStart = fill_convention_left( b->Pos.y );\r
+ yEnd = fill_convention_right( c->Pos.y );\r
+\r
+#ifdef SUBTEXEL\r
+\r
+ subPixel = ( (f32) yStart ) - b->Pos.y;\r
+\r
+ // correct to pixel center\r
+ scan.x[0] += scan.slopeX[0] * subPixel;\r
+ scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0] * subPixel;\r
+ scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0] * subPixel;\r
+ scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+ // rasterize the edge scanlines\r
+ for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+ {\r
+ line.x[scan.left] = scan.x[0];\r
+ line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+ line.z[scan.left] = scan.z[0];\r
+ line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ line.w[scan.left] = scan.w[0];\r
+ line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ line.c[0][scan.left] = scan.c[0][0];\r
+ line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ line.t[0][scan.left] = scan.t[0][0];\r
+ line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ line.t[1][scan.left] = scan.t[1][0];\r
+ line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+ // render a scanline\r
+ fragmentShader();\r
+\r
+ scan.x[0] += scan.slopeX[0];\r
+ scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0];\r
+ scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0];\r
+ scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0];\r
+ scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0];\r
+ scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0];\r
+ scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+\r
+ }\r
+ }\r
+\r
+}\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+namespace irr\r
+{\r
+namespace video\r
+{\r
+\r
+//! creates a flat triangle renderer\r
+IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver)\r
+{\r
+ /*\r
+ ETR_TRANSPARENT_REFLECTION_2_LAYER \r
+ Irrlicht EMT_REFLECTION_2_LAYER,EMT_TRANSPARENT_REFLECTION_2_LAYER\r
+ */\r
+ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+ return new CTR_transparent_reflection_2_layer(driver);\r
+ #else\r
+ return 0;\r
+ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+}\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+\r
+\r
s16 uv2type = -1;\r
s16 tangenttype = -1;\r
s16 binormaltype = -1;\r
+\r
+ (void)tangentpos; // disable unused variable warnings\r
+ (void)binormalpos; // disable unused variable warnings\r
+ (void)tangenttype; // disable unused variable warnings\r
+ (void)binormaltype; // disable unused variable warnings\r
+\r
for (j=0; j<dcnt; ++j)\r
{\r
const u32 type = readInt();\r
#include "SoftwareDriver2_compile_config.h"\r
#include "IBurningShader.h"\r
#include "CSoftwareDriver2.h"\r
+#include "IShaderConstantSetCallBack.h"\r
\r
namespace irr\r
{\r
+\r
+\r
namespace video\r
{\r
\r
0xf0,0x70,0xd0,0x50\r
};\r
\r
- IBurningShader::IBurningShader(CBurningVideoDriver* driver)\r
- {\r
- #ifdef _DEBUG\r
- setDebugName("IBurningShader");\r
- #endif\r
-\r
- for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )\r
- {\r
- IT[i].Texture = 0;\r
- }\r
-\r
- Driver = driver;\r
- RenderTarget = 0;\r
- ColorMask = COLOR_BRIGHT_WHITE;\r
- DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();\r
- if ( DepthBuffer )\r
- DepthBuffer->grab();\r
-\r
- Stencil = (CStencilBuffer*) driver->getStencilBuffer ();\r
- if ( Stencil )\r
- Stencil->grab();\r
+void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)\r
+{\r
+ #ifdef _DEBUG\r
+ setDebugName("IBurningShader");\r
+ #endif\r
\r
+ EdgeTestPass = edge_test_pass;\r
+ EdgeTestPass_stack = edge_test_pass;\r
+\r
+ for ( u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i )\r
+ {\r
+ IT[i].Texture = 0;\r
}\r
\r
+ Driver = driver;\r
+ CallBack = 0;\r
+\r
+ RenderTarget = 0;\r
+ ColorMask = COLOR_BRIGHT_WHITE;\r
+ DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();\r
+ if ( DepthBuffer )\r
+ DepthBuffer->grab();\r
+\r
+ Stencil = (CStencilBuffer*) driver->getStencilBuffer ();\r
+ if ( Stencil )\r
+ Stencil->grab();\r
+\r
+ stencilOp[0] = StencilOp_KEEP;\r
+ stencilOp[1] = StencilOp_KEEP;\r
+ stencilOp[2] = StencilOp_KEEP;\r
+ AlphaRef = 0;\r
+ RenderPass_ShaderIsTransparent = 0;\r
+ PrimitiveColor = COLOR_BRIGHT_WHITE;\r
+ TL_Flag = 0;\r
+}\r
+\r
+IBurningShader::IBurningShader(CBurningVideoDriver* driver)\r
+{\r
+ constructor_IBurningShader(driver);\r
+}\r
+\r
+//! Constructor\r
+IBurningShader::IBurningShader(\r
+ CBurningVideoDriver* driver,\r
+ s32& outMaterialTypeNr,\r
+ const c8* vertexShaderProgram,\r
+ const c8* vertexShaderEntryPointName,\r
+ E_VERTEX_SHADER_TYPE vsCompileTarget,\r
+ const c8* pixelShaderProgram,\r
+ const c8* pixelShaderEntryPointName,\r
+ E_PIXEL_SHADER_TYPE psCompileTarget,\r
+ const c8* geometryShaderProgram ,\r
+ const c8* geometryShaderEntryPointName,\r
+ E_GEOMETRY_SHADER_TYPE gsCompileTarget,\r
+ scene::E_PRIMITIVE_TYPE inType,\r
+ scene::E_PRIMITIVE_TYPE outType,\r
+ u32 verticesOut,\r
+ IShaderConstantSetCallBack* callback,\r
+ E_MATERIAL_TYPE baseMaterial,\r
+ s32 userData)\r
+{\r
+ constructor_IBurningShader(driver);\r
+ BaseMaterial = baseMaterial;\r
+ CallBack = callback;\r
+ if (CallBack)\r
+ CallBack->grab();\r
+\r
+ // register myself as new material\r
+ outMaterialTypeNr = Driver->addMaterialRenderer(this);\r
+}\r
+\r
+\r
+//! destructor\r
+IBurningShader::~IBurningShader()\r
+{\r
+ if (RenderTarget)\r
+ RenderTarget->drop();\r
\r
- //! destructor\r
- IBurningShader::~IBurningShader()\r
+ if (DepthBuffer)\r
+ DepthBuffer->drop();\r
+\r
+ if (Stencil)\r
+ Stencil->drop();\r
+\r
+ for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )\r
{\r
- if (RenderTarget)\r
- RenderTarget->drop();\r
+ if ( IT[i].Texture )\r
+ IT[i].Texture->drop();\r
+ }\r
\r
- if (DepthBuffer)\r
- DepthBuffer->drop();\r
+ if (CallBack)\r
+ CallBack->drop();\r
\r
- if (Stencil)\r
- Stencil->drop();\r
+}\r
\r
- for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )\r
- {\r
- if ( IT[i].Texture )\r
- IT[i].Texture->drop();\r
- }\r
+//! sets a render target\r
+void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)\r
+{\r
+ if (RenderTarget)\r
+ RenderTarget->drop();\r
+\r
+ RenderTarget = (video::CImage* ) surface;\r
+\r
+ if (RenderTarget)\r
+ {\r
+ RenderTarget->grab();\r
+\r
+ //(fp24*) DepthBuffer->lock() = DepthBuffer->lock();\r
}\r
+}\r
+\r
\r
- //! sets a render target\r
- void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)\r
+//! sets the Texture\r
+void IBurningShader::setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor)\r
+{\r
+ sInternalTexture *it = &IT[stage];\r
+\r
+ if ( it->Texture)\r
+ it->Texture->drop();\r
+\r
+ it->Texture = texture;\r
+\r
+ if ( it->Texture)\r
{\r
- if (RenderTarget)\r
- RenderTarget->drop();\r
+ it->Texture->grab();\r
\r
- RenderTarget = (video::CImage* ) surface;\r
+ // select mignify and magnify\r
+ it->lodFactor = lodFactor;\r
\r
- if (RenderTarget)\r
- {\r
- RenderTarget->grab();\r
+ //only mipmap chain (means positive lodFactor)\r
+ u32 existing_level = it->Texture->getMipmapLevel(lodFactor);\r
+ it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY, existing_level, 0);\r
\r
- //(fp24*) DepthBuffer->lock() = DepthBuffer->lock();\r
- }\r
+ // prepare for optimal fixpoint\r
+ it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );\r
+\r
+ const core::dimension2d<u32> &dim = it->Texture->getSize();\r
+ it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;\r
+ it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;\r
}\r
+}\r
+\r
+//emulate a line with degenerate triangle and special shader mode (not perfect...)\r
+void IBurningShader::drawLine ( const s4DVertex *a,const s4DVertex *b)\r
+{\r
+ sVec2 d;\r
+ d.x = b->Pos.x - a->Pos.x; d.x *= d.x;\r
+ d.y = b->Pos.y - a->Pos.y; d.y *= d.y;\r
+ //if ( d.x * d.y < 0.001f ) return;\r
+\r
+ if ( a->Pos.x > b->Pos.x ) swapVertexPointer(&a, &b);\r
+\r
+ s4DVertex c = *a;\r
+\r
+ const f32 w = (f32)RenderTarget->getDimension().Width-1;\r
+ const f32 h = (f32)RenderTarget->getDimension().Height-1;\r
+\r
+ if ( d.x < 2.f ) { c.Pos.x = b->Pos.x + 1.f + d.y; if ( c.Pos.x > w ) c.Pos.x = w; }\r
+ else c.Pos.x = b->Pos.x;\r
+ if ( d.y < 2.f ) { c.Pos.y = b->Pos.y + 1.f; if ( c.Pos.y > h ) c.Pos.y = h; EdgeTestPass |= edge_test_first_line; }\r
+\r
+ drawTriangle ( a,b,&c );\r
+ EdgeTestPass &= ~edge_test_first_line;\r
+\r
+}\r
\r
+void IBurningShader::drawPoint(const s4DVertex *a)\r
+{\r
+}\r
\r
- //! sets the Texture\r
- void IBurningShader::setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel)\r
+void IBurningShader::drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+{\r
+ if ( EdgeTestPass & edge_test_pass ) drawTriangle(a, b, c);\r
+ else if (EdgeTestPass & edge_test_point)\r
+ {\r
+ drawPoint(a);\r
+ drawPoint(b);\r
+ drawPoint(c);\r
+ }\r
+ else\r
{\r
- sInternalTexture *it = &IT[stage];\r
+ drawLine(a, b);\r
+ drawLine(b, c);\r
+ drawLine(a, c);\r
+ }\r
+}\r
\r
- if ( it->Texture)\r
- it->Texture->drop();\r
\r
- it->Texture = texture;\r
+void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,\r
+ bool resetAllRenderstates, IMaterialRendererServices* services)\r
+{\r
+ if (Driver)\r
+ Driver->setFallback_Material(BaseMaterial);\r
+ services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);\r
+ if (CallBack)\r
+ CallBack->OnSetMaterial(material);\r
\r
- if ( it->Texture)\r
- {\r
- it->Texture->grab();\r
+}\r
\r
- // select mignify and magnify ( lodLevel )\r
- //SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS\r
- it->lodLevel = lodLevel;\r
- it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY,\r
- core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 ), 0);\r
+void IBurningShader::OnUnsetMaterial()\r
+{\r
+}\r
\r
- // prepare for optimal fixpoint\r
- it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );\r
+bool IBurningShader::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)\r
+{\r
+ // call callback to set shader constants\r
+ if (CallBack)\r
+ CallBack->OnSetConstants(this, UserData);\r
+ return true;\r
+}\r
+\r
+\r
+//! Returns if the material is transparent.\r
+bool IBurningShader::isTransparent() const\r
+{\r
+ return RenderPass_ShaderIsTransparent != 0;\r
+}\r
+\r
+//! Access the callback provided by the users when creating shader materials\r
+IShaderConstantSetCallBack* IBurningShader::getShaderConstantSetCallBack() const\r
+{\r
+ return CallBack;\r
+}\r
\r
- const core::dimension2d<u32> &dim = it->Texture->getSize();\r
- it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;\r
- it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;\r
- }\r
+// implementations for the render services\r
+void IBurningShader::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates)\r
+{\r
+ // forward\r
+ Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);\r
+}\r
+\r
+s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags,const c8* name)\r
+{\r
+ if (!name || !name[0])\r
+ return -1;\r
+\r
+ BurningUniform add;\r
+ tiny_strcpy(add.name, name);\r
+ add.type = flags;\r
+\r
+ s32 index = UniformInfo.linear_search(add);\r
+ if (index < 0)\r
+ {\r
+ UniformInfo.push_back(add);\r
+ index = UniformInfo.size() - 1;\r
+ }\r
+\r
+ return index;\r
+}\r
+\r
+const char* tiny_itoa(s32 value, int base)\r
+{\r
+ static char b[32];\r
+ int p = 31;\r
+\r
+ //int sign = 0;\r
+ //if (value < 0) { sign = 1; value = -value; }\r
+\r
+ b[p] = '\0';\r
+ do {\r
+ b[--p] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[value%base];\r
+ value /= base;\r
+ } while (value && p > 0);\r
+\r
+ //if (sign && p > 0) { b[--p] = '-'; }\r
+\r
+ return b + p;\r
+}\r
+\r
+bool IBurningShader::setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count)\r
+{\r
+ if ((u32)index >= UniformInfo.size())\r
+ return false;\r
+#if 0\r
+ BurningUniform add;\r
+ while ((u32)index >= UniformInfo.size())\r
+ {\r
+ tiny_strcpy(add.name, tiny_itoa(UniformInfo.size(),10));\r
+ add.type = flags;\r
+ UniformInfo.push_back(add);\r
}\r
+#endif\r
+\r
+ BurningUniform& use = UniformInfo[index];\r
+ use.type = flags;\r
+\r
+ const u32* s = (u32*)data;\r
+ u32* d = (u32*)use.data;\r
+\r
+ if (!s) u32_count = 0;\r
+ if (u32_count > array_size(use.data)) u32_count = array_size(use.data);\r
+ for (size_t i = 0; i < u32_count; ++i)\r
+ {\r
+ d[i] = s[i];\r
+ }\r
+\r
+ return true;\r
+}\r
+\r
+\r
+s32 IBurningShader::getVertexShaderConstantID(const c8* name)\r
+{\r
+ return getShaderConstantID(BL_VERTEX_PROGRAM, name);\r
+}\r
+\r
+s32 IBurningShader::getPixelShaderConstantID(const c8* name)\r
+{\r
+ return getShaderConstantID(BL_FRAGMENT_PROGRAM, name);\r
+}\r
+\r
+void IBurningShader::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
+{\r
+ c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];\r
+ tiny_strcpy(name, tiny_itoa(startRegister, 10));\r
+\r
+ setShaderConstantID(BL_VERTEX_FLOAT, getShaderConstantID(BL_VERTEX_PROGRAM,name), data, constantAmount);\r
+}\r
+\r
+void IBurningShader::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
+{\r
+ c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];\r
+ tiny_strcpy(name, tiny_itoa(startRegister, 10));\r
+\r
+ setShaderConstantID(BL_FRAGMENT_FLOAT, getShaderConstantID(BL_FRAGMENT_PROGRAM, name), data, constantAmount);\r
+}\r
+\r
+bool IBurningShader::setVertexShaderConstant(s32 index, const f32* floats, int count)\r
+{\r
+ return setShaderConstantID(BL_VERTEX_FLOAT, index, floats, count);\r
+}\r
+\r
+bool IBurningShader::setVertexShaderConstant(s32 index, const s32* ints, int count)\r
+{\r
+ return setShaderConstantID(BL_VERTEX_INT, index, ints, count);\r
+}\r
+\r
+bool IBurningShader::setVertexShaderConstant(s32 index, const u32* ints, int count)\r
+{\r
+ return setShaderConstantID(BL_VERTEX_UINT, index, ints, count);\r
+}\r
+\r
+bool IBurningShader::setPixelShaderConstant(s32 index, const f32* floats, int count)\r
+{\r
+ return setShaderConstantID(BL_FRAGMENT_FLOAT, index, floats, count);\r
+}\r
+\r
+bool IBurningShader::setPixelShaderConstant(s32 index, const s32* ints, int count)\r
+{\r
+ return setShaderConstantID(BL_FRAGMENT_INT, index, ints, count);\r
+}\r
+\r
+bool IBurningShader::setPixelShaderConstant(s32 index, const u32* ints, int count)\r
+{\r
+ return setShaderConstantID(BL_FRAGMENT_UINT, index, ints, count);\r
+}\r
+\r
+void IBurningShader::setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass)\r
+{\r
+ stencilOp[0] = sfail;\r
+ stencilOp[1] = dpfail;\r
+ stencilOp[2] = dppass;\r
+}\r
+\r
+\r
+IVideoDriver* IBurningShader::getVideoDriver()\r
+{\r
+ return Driver;\r
+}\r
\r
\r
} // end namespace video\r
#include "SLight.h"\r
#include "SMaterial.h"\r
#include "os.h"\r
-\r
+#include "IMaterialRenderer.h"\r
+#include "IMaterialRendererServices.h"\r
+#include "IGPUProgrammingServices.h"\r
\r
namespace irr\r
{\r
struct SBurningShaderLight\r
{\r
//SLight org;\r
- bool LightIsOn;\r
+\r
+ sVec4 pos; //light position input\r
+ sVec4 pos4; //light position Model*View (Identity*View)\r
\r
E_LIGHT_TYPE Type;\r
- f32 radius;\r
f32 linearAttenuation;\r
f32 constantAttenuation;\r
f32 quadraticAttenuation;\r
- sVec4 pos;\r
\r
- sVec3 AmbientColor;\r
- sVec3 DiffuseColor;\r
- sVec3 SpecularColor;\r
- sVec4 pos_objectspace;\r
+ sVec4 spotDirection;\r
+ sVec4 spotDirection4;\r
+ f32 spotCosCutoff;\r
+ f32 spotCosInnerCutoff;\r
+ f32 spotExponent;\r
+ bool LightIsOn;\r
+\r
+ sVec3Color AmbientColor;\r
+ sVec3Color DiffuseColor;\r
+ sVec3Color SpecularColor;\r
};\r
\r
- enum eLightFlags\r
+ enum eTransformLightFlags\r
{\r
- ENABLED = 0x01,\r
- POINTLIGHT = 0x02,\r
- SPECULAR = 0x04,\r
- FOG = 0x08,\r
- NORMALIZE = 0x10,\r
- VERTEXTRANSFORM = 0x20,\r
+ //ENABLED = 0x01,\r
+ TL_SCISSOR = 0x02,\r
+ TL_LIGHT = 0x04,\r
+ TL_SPECULAR = 0x08,\r
+ TL_FOG = 0x10,\r
+ TL_NORMALIZE_NORMALS = 0x20,\r
+ TL_TEXTURE_TRANSFORM = 0x40,\r
+ TL_LIGHT_LOCAL_VIEWER = 0x80,\r
+ TL_LIGHT0_IS_NORMAL_MAP = 0x100 //sVec4 Light Vector is used as normal or specular\r
};\r
\r
- struct SBurningShaderLightSpace\r
+ struct SBurningShaderEyeSpace\r
{\r
+ SBurningShaderEyeSpace() {}\r
+ virtual ~SBurningShaderEyeSpace() {}\r
void reset ()\r
{\r
Light.set_used ( 0 );\r
- Global_AmbientLight.set ( 0.f, 0.f, 0.f );\r
- Flags = 0;\r
+ Global_AmbientLight.set ( 0.f );\r
+\r
+ TL_Flag = TL_LIGHT_LOCAL_VIEWER;\r
+ }\r
+ void resetFog()\r
+ {\r
+ fog_scale = 0.f;\r
+ //cam_distance = 0.f;\r
}\r
+\r
core::array<SBurningShaderLight> Light;\r
- sVec3 Global_AmbientLight;\r
- sVec4 FogColor;\r
- sVec4 campos;\r
- sVec4 vertex;\r
- sVec4 normal;\r
- u32 Flags;\r
+ sVec3Color Global_AmbientLight;\r
+\r
+ //sVec4 cam_eye_pos; //Camera Position in eye Space (0,0,-1)\r
+ //sVec4 cam_world_pos; //Camera Position in world Space\r
+ //sVec4 vertex4; //eye coordinate position of vertex\r
+ sVec4 normal; //transformed normal\r
+ sVec4 vertex; //eye coordinate position of vertex projected\r
+\r
+ //derivative of vertex\r
+ //f32 cam_distance; // vertex.length();\r
+ sVec4 cam_dir; //vertex.normalize();\r
+\r
+ f32 fog_scale; // 1 / (fog.end-fog.start)\r
+\r
+ size_t TL_Flag; // eTransformLightFlags\r
+ };\r
+\r
+ enum eBurningCullFlag\r
+ {\r
+ CULL_FRONT = 1,\r
+ CULL_BACK = 2,\r
+ CULL_INVISIBLE = 4, //primitive smaller than a pixel (AreaMinDrawSize)\r
+ CULL_FRONT_AND_BACK = 8,\r
+ };\r
+\r
+ enum eBurningStencilOp\r
+ {\r
+ StencilOp_KEEP = 0x1E00,\r
+ StencilOp_INCR = 0x1E02,\r
+ StencilOp_DECR = 0x1E03\r
};\r
\r
struct SBurningShaderMaterial\r
{\r
SMaterial org;\r
+ SMaterial lastMaterial;\r
+ bool resetRenderStates;\r
+\r
+ E_MATERIAL_TYPE Fallback_MaterialType;\r
\r
- sVec3 AmbientColor;\r
- sVec3 DiffuseColor;\r
- sVec3 SpecularColor;\r
- sVec3 EmissiveColor;\r
+ SMaterial mat2D;\r
+ //SMaterial save3D;\r
+\r
+ size_t CullFlag; //eCullFlag\r
+ u32 depth_write;\r
+ u32 depth_test;\r
+\r
+ sVec3Color AmbientColor;\r
+ sVec3Color DiffuseColor;\r
+ sVec3Color SpecularColor;\r
+ sVec3Color EmissiveColor;\r
\r
};\r
\r
ETR_TEXTURE_GOURAUD_DETAIL_MAP,\r
ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD,\r
\r
- ETR_GOURAUD_ALPHA,\r
+ ETR_GOURAUD_NOZ,\r
+ //ETR_GOURAUD_ALPHA,\r
ETR_GOURAUD_ALPHA_NOZ,\r
\r
ETR_TEXTURE_GOURAUD_ALPHA,\r
ETR_TEXTURE_GOURAUD_ALPHA_NOZ,\r
+ ETR_TEXTURE_GOURAUD_ALPHA_NOZ_NOPERSPECTIVE_CORRECT,\r
\r
ETR_NORMAL_MAP_SOLID,\r
ETR_STENCIL_SHADOW,\r
\r
ETR_TEXTURE_BLEND,\r
- ETR_REFERENCE,\r
+ ETR_TRANSPARENT_REFLECTION_2_LAYER,\r
+\r
+ ETR_COLOR,\r
+\r
+ //ETR_REFERENCE,\r
ETR_INVALID,\r
\r
ETR2_COUNT\r
};\r
\r
+ typedef enum\r
+ {\r
+ BL_VERTEX_PROGRAM = 1,\r
+ BL_FRAGMENT_PROGRAM = 2,\r
+ BL_TYPE_FLOAT = 4,\r
+ BL_TYPE_INT = 8,\r
+ BL_TYPE_UINT = 16,\r
+\r
+ BL_VERTEX_FLOAT = (BL_VERTEX_PROGRAM | BL_TYPE_FLOAT),\r
+ BL_VERTEX_INT = (BL_VERTEX_PROGRAM | BL_TYPE_INT),\r
+ BL_VERTEX_UINT = (BL_VERTEX_PROGRAM | BL_TYPE_UINT),\r
+ BL_FRAGMENT_FLOAT = (BL_FRAGMENT_PROGRAM | BL_TYPE_FLOAT),\r
+ BL_FRAGMENT_INT = (BL_FRAGMENT_PROGRAM | BL_TYPE_INT),\r
+ BL_FRAGMENT_UINT = (BL_FRAGMENT_PROGRAM | BL_TYPE_UINT),\r
+\r
+ BL_ACTIVE_UNIFORM_MAX_LENGTH = 28\r
+ } EBurningUniformFlags;\r
+\r
+ struct BurningUniform\r
+ {\r
+ c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];\r
+ u32 type; //EBurningUniformFlags\r
+ //int location; // UniformLocation is index\r
+ f32 data[16]; // simple LocalParameter\r
+\r
+ bool operator==(const BurningUniform& other) const\r
+ {\r
+ return tiny_istoken(name, other.name);\r
+ }\r
+\r
+ };\r
+\r
\r
class CBurningVideoDriver;\r
- class IBurningShader : public virtual IReferenceCounted\r
+ class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices\r
{\r
public:\r
+ //! Constructor\r
IBurningShader(CBurningVideoDriver* driver);\r
\r
+ //! Constructor\r
+ IBurningShader(\r
+ CBurningVideoDriver* driver,\r
+ s32& outMaterialTypeNr,\r
+ const c8* vertexShaderProgram = 0,\r
+ const c8* vertexShaderEntryPointName = 0,\r
+ E_VERTEX_SHADER_TYPE vsCompileTarget = video::EVST_VS_1_1,\r
+ const c8* pixelShaderProgram = 0,\r
+ const c8* pixelShaderEntryPointName = 0,\r
+ E_PIXEL_SHADER_TYPE psCompileTarget = video::EPST_PS_1_1,\r
+ const c8* geometryShaderProgram = 0,\r
+ const c8* geometryShaderEntryPointName = "main",\r
+ E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,\r
+ scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,\r
+ scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,\r
+ u32 verticesOut = 0,\r
+ IShaderConstantSetCallBack* callback = 0,\r
+ E_MATERIAL_TYPE baseMaterial = EMT_SOLID,\r
+ s32 userData = 0);\r
+\r
//! destructor\r
virtual ~IBurningShader();\r
\r
virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort);\r
\r
//! sets the Texture\r
- virtual void setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel);\r
- virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) = 0;\r
- virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) {};\r
+ virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor);\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) {};\r
+ virtual void drawLine ( const s4DVertex *a,const s4DVertex *b);\r
+ virtual void drawPoint(const s4DVertex *a);\r
+\r
+ void drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );\r
+\r
+ virtual void OnSetMaterial( const SBurningShaderMaterial& material ) {};\r
+\r
+ void pushEdgeTest(const int wireFrame,const int point,int save)\r
+ {\r
+ if ( save ) EdgeTestPass_stack = EdgeTestPass;\r
+ EdgeTestPass = point ? edge_test_point : wireFrame ? edge_test_left : edge_test_pass;\r
+ }\r
+ void popEdgeTest() { EdgeTestPass = EdgeTestPass_stack; }\r
+ virtual bool canWireFrame () { return false; }\r
+ virtual bool canPointCloud() { return false; }\r
+\r
+ void setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass);\r
\r
- virtual void setParam ( u32 index, f32 value) {};\r
- virtual void setZCompareFunc ( u32 func) {};\r
+ //IMaterialRenderer\r
\r
- virtual void setMaterial ( const SBurningShaderMaterial &material ) {};\r
+ virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,\r
+ bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_;\r
+\r
+ virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_;\r
+\r
+ virtual void OnUnsetMaterial() _IRR_OVERRIDE_;\r
+\r
+ //! Returns if the material is transparent.\r
+ virtual bool isTransparent() const _IRR_OVERRIDE_;\r
+\r
+ //! Access the callback provided by the users when creating shader materials\r
+ virtual IShaderConstantSetCallBack* getShaderConstantSetCallBack() const _IRR_OVERRIDE_;\r
+\r
+ // implementations for the render services\r
+ virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) _IRR_OVERRIDE_;\r
+ virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;\r
+ virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;\r
+ virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) _IRR_OVERRIDE_;\r
+ virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) _IRR_OVERRIDE_;\r
+ virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;\r
+ virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;\r
+ virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;\r
+ virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;\r
+ virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;\r
+ virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;\r
+ virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;\r
+\r
+ //used if no color interpolation is defined\r
+ void setPrimitiveColor(const video::SColor& color)\r
+ {\r
+ #if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8\r
+ PrimitiveColor = color.color;\r
+ #else\r
+ PrimitiveColor = color.toA1R5G5B5();\r
+ #endif\r
+ }\r
+ void setTLFlag(size_t in /*eTransformLightFlags*/)\r
+ {\r
+ TL_Flag = in;\r
+ }\r
+ void setFog(SColor color_fog)\r
+ {\r
+#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8\r
+ fog_color_sample = color_fog.color;\r
+#else\r
+ fog_color_sample = color_fog.toA1R5G5B5();\r
+#endif\r
+ color_to_fix(fog_color, fog_color_sample);\r
+ }\r
+ void setScissor(const AbsRectangle& scissor)\r
+ {\r
+ Scissor = scissor;\r
+ }\r
\r
protected:\r
\r
+ void constructor_IBurningShader(CBurningVideoDriver* driver);\r
+\r
CBurningVideoDriver *Driver;\r
+ IShaderConstantSetCallBack* CallBack;\r
+ E_MATERIAL_TYPE BaseMaterial;\r
+ s32 UserData;\r
+\r
+ core::array<BurningUniform> UniformInfo;\r
+ s32 getShaderConstantID(EBurningUniformFlags program, const c8* name);\r
+ bool setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count);\r
\r
video::CImage* RenderTarget;\r
CDepthBuffer* DepthBuffer;\r
- CStencilBuffer * Stencil;\r
+ CStencilBuffer* Stencil;\r
tVideoSample ColorMask;\r
\r
sInternalTexture IT[ BURNING_MATERIAL_MAX_TEXTURES ];\r
\r
static const tFixPointu dithermask[ 4 * 4];\r
+\r
+ //draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham\r
+ int EdgeTestPass; //edge_test_flag\r
+ int EdgeTestPass_stack;\r
+\r
+ eBurningStencilOp stencilOp[4];\r
+ tFixPoint AlphaRef;\r
+ int RenderPass_ShaderIsTransparent;\r
+\r
+ sScanConvertData scan;\r
+ sScanLineData line;\r
+ tVideoSample PrimitiveColor; //used if no color interpolation is defined\r
+\r
+ size_t /*eTransformLightFlags*/ TL_Flag;\r
+ tFixPoint fog_color[4];\r
+ tVideoSample fog_color_sample;\r
+\r
+ AbsRectangle Scissor;\r
};\r
\r
\r
\r
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver);\r
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver);\r
+ IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver);\r
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver);\r
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);\r
IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver);\r
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);\r
\r
IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver);\r
+ IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver);\r
\r
-\r
+ IBurningShader* create_burning_shader_color(CBurningVideoDriver* driver);\r
\r
} // end namespace video\r
} // end namespace irr\r
virtual ~IDepthBuffer() {};\r
\r
//! clears the zbuffer\r
- virtual void clear() = 0;\r
+ virtual void clear(f32 value) = 0;\r
\r
//! sets the new size of the zbuffer\r
virtual void setSize(const core::dimension2d<u32>& size) = 0;\r
//! destructor\r
virtual ~IStencilBuffer() {};\r
\r
- //! clears the zbuffer\r
- virtual void clear() = 0;\r
+ //! clears the stencil buffer\r
+ virtual void clear(u8 value) = 0;\r
\r
//! sets the new size of the zbuffer\r
virtual void setSize(const core::dimension2d<u32>& size) = 0;\r
\r
- //! returns the size of the zbuffer\r
+ //! returns the size of the stencil buffer\r
virtual const core::dimension2d<u32>& getSize() const = 0;\r
\r
- //! locks the zbuffer\r
+ //! locks the stencil buffer\r
virtual void* lock() = 0;\r
\r
- //! unlocks the zbuffer\r
+ //! unlocks the stencil buffer\r
virtual void unlock() = 0;\r
\r
- //! returns pitch of depthbuffer (in bytes)\r
+ //! returns pitch of stencil buffer (in bytes)\r
virtual u32 getPitch() const = 0;\r
\r
};\r
\r
\r
//! creates a Stencil Buffer\r
- IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size);\r
+ IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size, u32 bit);\r
\r
} // end namespace video\r
} // end namespace irr\r
<Unit filename="CTRGouraud2.cpp" />
<Unit filename="CTRGouraudAlpha2.cpp" />
<Unit filename="CTRGouraudAlphaNoZ2.cpp" />
+ <Unit filename="CTRGouraudNoZ2.cpp" />
<Unit filename="CTRGouraudWire.cpp" />
<Unit filename="CTRNormalMap.cpp" />
<Unit filename="CTRStencilShadow.cpp" />
<Unit filename="CTRTextureLightMap2_M4.cpp" />
<Unit filename="CTRTextureLightMapGouraud2_M4.cpp" />
<Unit filename="CTRTextureWire2.cpp" />
+ <Unit filename="CTR_transparent_reflection_2_layer.cpp" />
<Unit filename="CTarReader.cpp" />
<Unit filename="CTarReader.h" />
<Unit filename="CTerrainSceneNode.cpp" />
<Unit filename="aesGladman/sha1.h" />
<Unit filename="aesGladman/sha2.cpp" />
<Unit filename="aesGladman/sha2.h" />
+ <Unit filename="burning_shader_color.cpp" />
+ <Unit filename="burning_shader_color_fraq.h" />
+ <Unit filename="burning_shader_compile_fragment_default.h" />
+ <Unit filename="burning_shader_compile_fragment_end.h" />
+ <Unit filename="burning_shader_compile_fragment_start.h" />
+ <Unit filename="burning_shader_compile_start.h" />
+ <Unit filename="burning_shader_compile_triangle.h" />
+ <Unit filename="burning_shader_compile_verify.h" />
<Unit filename="bzip2/blocksort.c">
<Option compilerVar="CC" />
</Unit>
<ClInclude Include="..\..\include\IGUIToolbar.h" />\r
<ClInclude Include="..\..\include\IGUITreeView.h" />\r
<ClInclude Include="..\..\include\IGUIWindow.h" />\r
+ <ClInclude Include="burning_shader_color_fraq.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_default.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_end.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_start.h" />\r
+ <ClInclude Include="burning_shader_compile_start.h" />\r
+ <ClInclude Include="burning_shader_compile_triangle.h" />\r
+ <ClInclude Include="burning_shader_compile_verify.h" /> \r
<ClInclude Include="CB3DMeshWriter.h" />\r
<ClInclude Include="CD3D9RenderTarget.h" />\r
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />\r
<None Include="..\..\readme.txt" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ClCompile Include="burning_shader_color.cpp" />\r
<ClCompile Include="CB3DMeshWriter.cpp" />\r
<ClCompile Include="CD3D9RenderTarget.cpp" />\r
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />\r
<ClCompile Include="CQ3LevelMesh.cpp" />\r
<ClCompile Include="CSkinnedMesh.cpp" />\r
<ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
<ClCompile Include="CWGLManager.cpp" />\r
<ClCompile Include="CXMeshFileLoader.cpp" />\r
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
</ClInclude>\r
<ClInclude Include="..\..\include\IOctreeSceneNode.h">\r
<Filter>include\scene</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_color_fraq.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_default.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_end.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_start.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_start.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_triangle.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_verify.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
</ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
</ClCompile>\r
<ClCompile Include="CWGLManager.cpp">\r
<Filter>Irrlicht\video\OpenGL Context</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="burning_shader_color.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
</ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\..\include\IGUIToolbar.h" />\r
<ClInclude Include="..\..\include\IGUITreeView.h" />\r
<ClInclude Include="..\..\include\IGUIWindow.h" />\r
+ <ClInclude Include="burning_shader_color_fraq.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_default.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_end.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_start.h" />\r
+ <ClInclude Include="burning_shader_compile_start.h" />\r
+ <ClInclude Include="burning_shader_compile_triangle.h" />\r
+ <ClInclude Include="burning_shader_compile_verify.h" />\r
<ClInclude Include="CB3DMeshWriter.h" />\r
<ClInclude Include="CD3D9RenderTarget.h" />\r
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />\r
<None Include="..\..\readme.txt" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ClCompile Include="burning_shader_color.cpp" />\r
<ClCompile Include="CB3DMeshWriter.cpp" />\r
<ClCompile Include="CD3D9RenderTarget.cpp" />\r
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />\r
<ClCompile Include="CQ3LevelMesh.cpp" />\r
<ClCompile Include="CSkinnedMesh.cpp" />\r
<ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
<ClCompile Include="CWGLManager.cpp" />\r
<ClCompile Include="CXMeshFileLoader.cpp" />\r
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
<ClInclude Include="..\..\include\IOctreeSceneNode.h">\r
<Filter>include\scene</Filter>\r
</ClInclude>\r
+ <ClInclude Include="burning_shader_color_fraq.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_default.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_end.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_start.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_start.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_triangle.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_verify.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<None Include="..\..\changes.txt">\r
<ClCompile Include="CWGLManager.cpp">\r
<Filter>Irrlicht\video\OpenGL Context</Filter>\r
</ClCompile>\r
+ <ClCompile Include="burning_shader_color.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="Irrlicht.rc" />\r
<ClCompile Include="CQ3LevelMesh.cpp" />\r
<ClCompile Include="CSkinnedMesh.cpp" />\r
<ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
<ClCompile Include="CWGLManager.cpp" />\r
<ClCompile Include="CXMeshFileLoader.cpp" />\r
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
<ClCompile Include="CWGLManager.cpp">\r
<Filter>Irrlicht\video\OpenGL Context</Filter>\r
</ClCompile>\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="Irrlicht.rc" />\r
<ClInclude Include="..\..\include\IGUIToolbar.h" />\r
<ClInclude Include="..\..\include\IGUITreeView.h" />\r
<ClInclude Include="..\..\include\IGUIWindow.h" />\r
+ <ClInclude Include="burning_shader_color_fraq.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_default.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_end.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_start.h" />\r
+ <ClInclude Include="burning_shader_compile_start.h" />\r
+ <ClInclude Include="burning_shader_compile_triangle.h" />\r
+ <ClInclude Include="burning_shader_compile_verify.h" />\r
<ClInclude Include="CB3DMeshWriter.h" />\r
+ <ClInclude Include="CBlit.h" />\r
<ClInclude Include="CD3D9RenderTarget.h" />\r
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />\r
<ClInclude Include="CDefaultSceneNodeFactory.h" />\r
<None Include="..\..\readme.txt" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ClCompile Include="burning_shader_color.cpp" />\r
<ClCompile Include="CB3DMeshWriter.cpp" />\r
<ClCompile Include="CD3D9RenderTarget.cpp" />\r
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />\r
<ClCompile Include="CQ3LevelMesh.cpp" />\r
<ClCompile Include="CSkinnedMesh.cpp" />\r
<ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
<ClCompile Include="CWGLManager.cpp" />\r
<ClCompile Include="CXMeshFileLoader.cpp" />\r
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
<ClInclude Include="..\..\include\IOctreeSceneNode.h">\r
<Filter>include\scene</Filter>\r
</ClInclude>\r
+ <ClInclude Include="burning_shader_color_fraq.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_default.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_end.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_start.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_start.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_triangle.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_verify.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="CBlit.h">\r
+ <Filter>Irrlicht\video\Null</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<None Include="..\..\changes.txt">\r
<ClCompile Include="CWGLManager.cpp">\r
<Filter>Irrlicht\video\OpenGL Context</Filter>\r
</ClCompile>\r
+ <ClCompile Include="burning_shader_color.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="Irrlicht.rc" />\r
<ClInclude Include="..\..\include\IGUIToolbar.h" />\r
<ClInclude Include="..\..\include\IGUITreeView.h" />\r
<ClInclude Include="..\..\include\IGUIWindow.h" />\r
+ <ClInclude Include="burning_shader_color_fraq.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_default.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_end.h" />\r
+ <ClInclude Include="burning_shader_compile_fragment_start.h" />\r
+ <ClInclude Include="burning_shader_compile_start.h" />\r
+ <ClInclude Include="burning_shader_compile_triangle.h" />\r
+ <ClInclude Include="burning_shader_compile_verify.h" />\r
<ClInclude Include="CB3DMeshWriter.h" />\r
<ClInclude Include="CD3D9RenderTarget.h" />\r
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />\r
<None Include="Irrlicht.ruleset" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ClCompile Include="burning_shader_color.cpp" />\r
<ClCompile Include="CB3DMeshWriter.cpp" />\r
<ClCompile Include="CD3D9RenderTarget.cpp" />\r
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />\r
<ClCompile Include="CQ3LevelMesh.cpp" />\r
<ClCompile Include="CSkinnedMesh.cpp" />\r
<ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
<ClCompile Include="CWGLManager.cpp" />\r
<ClCompile Include="CXMeshFileLoader.cpp" />\r
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
<ClInclude Include="..\..\include\SOverrideMaterial.h">\r
<Filter>include\video</Filter>\r
</ClInclude>\r
+ <ClInclude Include="burning_shader_color_fraq.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_default.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_end.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_fragment_start.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_start.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_triangle.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="burning_shader_compile_verify.h">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<None Include="..\..\changes.txt">\r
<ClCompile Include="CWGLManager.cpp">\r
<Filter>Irrlicht\video\OpenGL Context</Filter>\r
</ClCompile>\r
+ <ClCompile Include="burning_shader_color.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+ <Filter>Irrlicht\video\Burning Video</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<ResourceCompile Include="Irrlicht.rc" />\r
IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderDDS.o CImageLoaderJPG.o CImageLoaderPCX.o CImageLoaderPNG.o CImageLoaderPSD.o CImageLoaderPVR.o CImageLoaderTGA.o CImageLoaderPPM.o CImageLoaderWAL.o CImageLoaderRGB.o \\r
CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o\r
IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)\r
-IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRNormalMap.o CTRStencilShadow.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o\r
+IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRNormalMap.o \\r
+ CTRStencilShadow.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o \\r
+ CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o \\r
+ CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o \\r
+ CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o \\r
+ CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o \\r
+ CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o CTR_transparent_reflection_2_layer.o CTRGouraudNoZ2.o burning_shader_color.o\r
IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CWADReader.o CZipReader.o CPakReader.o CNPKReader.o CTarReader.o CMountPointReader.o irrXML.o CAttributes.o lzma/LzmaDec.o\r
IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceConsole.o CIrrDeviceStub.o CIrrDeviceWin32.o CIrrDeviceFB.o CLogger.o COSOperator.o Irrlicht.o os.o leakHunter.o CProfiler.o utf8.o\r
IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUITable.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o CGUIImageList.o CGUITreeView.o CGUIProfiler.o\r
#include "SoftwareDriver2_compile_config.h"\r
#include "SoftwareDriver2_helper.h"\r
#include "irrAllocator.h"\r
+#include "EPrimitiveTypes.h"\r
\r
namespace irr\r
{\r
namespace video\r
{\r
\r
+//! sVec2 used in BurningShader texture coordinates\r
struct sVec2\r
{\r
f32 x;\r
}\r
\r
// f = a * t + b * ( 1 - t )\r
- void interpolate(const sVec2& a, const sVec2& b, const f32 t)\r
+ void interpolate(const sVec2& burning_restrict a, const sVec2& burning_restrict b, const ipoltype t)\r
{\r
- x = b.x + ( ( a.x - b.x ) * t );\r
- y = b.y + ( ( a.y - b.y ) * t );\r
+ x = (f32)(b.x + ( ( a.x - b.x ) * t ));\r
+ y = (f32)(b.y + ( ( a.y - b.y ) * t ));\r
}\r
\r
sVec2 operator-(const sVec2& other) const\r
\r
};\r
\r
-// A8R8G8B8\r
-struct sVec4;\r
-struct sCompressedVec4\r
+#include "irrpack.h"\r
+\r
+//! sVec3Pack used in BurningShader, packed direction\r
+struct sVec3Pack\r
{\r
- u32 argb;\r
+ f32 x, y, z;\r
+ //f32 _can_pack;\r
+\r
+ sVec3Pack() {}\r
+ sVec3Pack(f32 _x, f32 _y, f32 _z)\r
+ : x(_x), y(_y), z(_z) {}\r
\r
- void setA8R8G8B8 ( u32 value )\r
+ // f = a * t + b * ( 1 - t )\r
+ void interpolate(const sVec3Pack& burning_restrict v0, const sVec3Pack& burning_restrict v1, const ipoltype t)\r
{\r
- argb = value;\r
+ x = (f32)(v1.x + ((v0.x - v1.x) * t));\r
+ y = (f32)(v1.y + ((v0.y - v1.y) * t));\r
+ z = (f32)(v1.z + ((v0.z - v1.z) * t));\r
}\r
\r
- void setColorf ( const video::SColorf & color )\r
+ sVec3Pack operator-(const sVec3Pack& other) const\r
{\r
- argb = core::floor32_fast( color.a * 255.f ) << 24 |\r
- core::floor32_fast( color.r * 255.f ) << 16 |\r
- core::floor32_fast( color.g * 255.f ) << 8 |\r
- core::floor32_fast( color.b * 255.f );\r
+ return sVec3Pack(x - other.x, y - other.y, z - other.z);\r
}\r
\r
- void setVec4 ( const sVec4 & v );\r
+ sVec3Pack operator+(const sVec3Pack& other) const\r
+ {\r
+ return sVec3Pack(x + other.x, y + other.y, z + other.z);\r
+ }\r
\r
- // f = a * t + b * ( 1 - t )\r
- void interpolate(const sCompressedVec4& a, const sCompressedVec4& b, const f32 t)\r
+ sVec3Pack operator*(const f32 s) const\r
{\r
- argb = PixelBlend32 ( b.argb, a.argb, core::floor32_fast( t * 256.f ) );\r
+ return sVec3Pack(x * s, y * s, z * s);\r
}\r
\r
+ void operator+=(const sVec3Pack& other)\r
+ {\r
+ x += other.x;\r
+ y += other.y;\r
+ z += other.z;\r
+ }\r
\r
-};\r
+ void operator=(const sVec3Pack& other)\r
+ {\r
+ x = other.x;\r
+ y = other.y;\r
+ z = other.z;\r
+ }\r
\r
+} PACK_STRUCT;\r
\r
+#include "irrunpack.h"\r
+\r
+//! sVec4 used in Driver,BurningShader, direction/color\r
struct sVec4\r
{\r
union\r
{\r
struct { f32 x, y, z, w; };\r
struct { f32 a, r, g, b; };\r
-// struct { sVec2 xy, zw; }; // sorry, this does not compile with gcc\r
};\r
\r
-\r
-\r
sVec4 () {}\r
-\r
- sVec4 ( f32 s) : x ( s ), y ( s ), z ( s ), w ( s ) {}\r
-\r
sVec4 ( f32 _x, f32 _y, f32 _z, f32 _w )\r
: x ( _x ), y ( _y ), z( _z ), w ( _w ){}\r
\r
- void set ( f32 _x, f32 _y, f32 _z, f32 _w )\r
- {\r
- x = _x;\r
- y = _y;\r
- z = _z;\r
- w = _w;\r
- }\r
-\r
- void setA8R8G8B8 ( u32 argb )\r
- {\r
- x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f );\r
- y = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f );\r
- z = ( ( argb & 0x0000FF00 ) >> 8 ) * ( 1.f / 255.f );\r
- w = ( ( argb & 0x000000FF ) ) * ( 1.f / 255.f );\r
- }\r
-\r
-\r
- void setColorf ( const video::SColorf & color )\r
- {\r
- x = color.a;\r
- y = color.r;\r
- z = color.g;\r
- w = color.b;\r
- }\r
-\r
-\r
// f = a * t + b * ( 1 - t )\r
- void interpolate(const sVec4& a, const sVec4& b, const f32 t)\r
+ void interpolate(const sVec4& burning_restrict a, const sVec4& burning_restrict b, const ipoltype t)\r
{\r
- x = b.x + ( ( a.x - b.x ) * t );\r
- y = b.y + ( ( a.y - b.y ) * t );\r
- z = b.z + ( ( a.z - b.z ) * t );\r
- w = b.w + ( ( a.w - b.w ) * t );\r
+ x = (f32)(b.x + ( ( a.x - b.x ) * t ));\r
+ y = (f32)(b.y + ( ( a.y - b.y ) * t ));\r
+ z = (f32)(b.z + ( ( a.z - b.z ) * t ));\r
+ w = (f32)(b.w + ( ( a.w - b.w ) * t ));\r
}\r
\r
-\r
- f32 dotProduct(const sVec4& other) const\r
+ sVec4 operator-(const sVec4& other) const\r
{\r
- return x*other.x + y*other.y + z*other.z + w*other.w;\r
+ return sVec4(x - other.x, y - other.y, z - other.z,w - other.w);\r
}\r
\r
- f32 dot_xyz( const sVec4& other) const\r
+ sVec4 operator+(const sVec4& other) const\r
{\r
- return x*other.x + y*other.y + z*other.z;\r
+ return sVec4(x + other.x, y + other.y, z + other.z,w + other.w);\r
}\r
\r
- f32 get_length_xyz_square () const\r
+ void operator+=(const sVec4& other)\r
{\r
- return x * x + y * y + z * z;\r
+ x += other.x;\r
+ y += other.y;\r
+ z += other.z;\r
+ w += other.w;\r
}\r
\r
- f32 get_length_xyz () const\r
+ sVec4 operator*(const f32 s) const\r
{\r
- return core::squareroot ( x * x + y * y + z * z );\r
+ return sVec4(x * s , y * s, z * s,w * s);\r
}\r
\r
- void normalize_xyz ()\r
+ sVec4 operator*(const sVec4 &other) const\r
{\r
- const f32 l = core::reciprocal_squareroot ( x * x + y * y + z * z );\r
-\r
- x *= l;\r
- y *= l;\r
- z *= l;\r
+ return sVec4(x * other.x , y * other.y, z * other.z,w * other.w);\r
}\r
\r
- void project_xyz ()\r
+ void operator*=(const sVec4 &other)\r
{\r
- w = core::reciprocal ( w );\r
- x *= w;\r
- y *= w;\r
- z *= w;\r
+ x *= other.x;\r
+ y *= other.y;\r
+ z *= other.z;\r
+ w *= other.w;\r
}\r
\r
- sVec4 operator-(const sVec4& other) const\r
+ void operator=(const sVec4& other)\r
{\r
- return sVec4(x - other.x, y - other.y, z - other.z,w - other.w);\r
+ x = other.x;\r
+ y = other.y;\r
+ z = other.z;\r
+ w = other.w;\r
}\r
\r
- sVec4 operator+(const sVec4& other) const\r
+ //outside shader\r
+ void set(f32 _x, f32 _y, f32 _z, f32 _w)\r
{\r
- return sVec4(x + other.x, y + other.y, z + other.z,w + other.w);\r
+ x = _x;\r
+ y = _y;\r
+ z = _z;\r
+ w = _w;\r
}\r
-\r
- void operator+=(const sVec4& other)\r
+ void setA8R8G8B8(const u32 argb)\r
{\r
- x += other.x;\r
- y += other.y;\r
- z += other.z;\r
- w += other.w;\r
+ a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);\r
+ r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);\r
+ g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);\r
+ b = ((argb & 0x000000FF) ) * (1.f / 255.f);\r
}\r
\r
- sVec4 operator*(const f32 s) const\r
+ REALINLINE ipoltype dot_xyzw(const sVec4& other) const\r
{\r
- return sVec4(x * s , y * s, z * s,w * s);\r
+ return (ipoltype)x * other.x + (ipoltype)y * other.y + (ipoltype)z * other.z + (ipoltype)w * other.w;\r
}\r
\r
- sVec4 operator*(const sVec4 &other) const\r
+ REALINLINE f32 dot_xyz(const sVec4& other) const\r
{\r
- return sVec4(x * other.x , y * other.y, z * other.z,w * other.w);\r
+ return x * other.x + y * other.y + z * other.z;\r
}\r
\r
- void mulReciprocal ( f32 s )\r
+ REALINLINE f32 dot_minus_xyz(const sVec4& other) const\r
{\r
- const f32 i = core::reciprocal ( s );\r
- x = (f32) ( x * i );\r
- y = (f32) ( y * i );\r
- z = (f32) ( z * i );\r
- w = (f32) ( w * i );\r
+ return -x * other.x + -y * other.y + -z * other.z;\r
}\r
\r
- void mul ( const f32 s )\r
+ void mul_xyz(const f32 s)\r
{\r
x *= s;\r
y *= s;\r
z *= s;\r
- w *= s;\r
}\r
\r
-/*\r
- void operator*=(f32 s)\r
+ f32 length_xyz() const\r
{\r
- x *= s;\r
- y *= s;\r
- z *= s;\r
- w *= s;\r
+ return sqrtf(x * x + y * y + z * z);\r
}\r
-*/\r
- void operator*=(const sVec4 &other)\r
+\r
+ void normalize_dir_xyz()\r
{\r
- x *= other.x;\r
- y *= other.y;\r
- z *= other.z;\r
- w *= other.w;\r
+ //const f32 l = core::reciprocal_squareroot(x * x + y * y + z * z);\r
+ f32 l = x * x + y * y + z * z;\r
+ l = l > 0.0000001f ? 1.f / sqrtf(l) : 1.f;\r
+ x *= l;\r
+ y *= l;\r
+ z *= l;\r
}\r
\r
- void operator=(const sVec4& other)\r
+\r
+ //unpack sVec3 to aligned during runtime\r
+ sVec4(const sVec3Pack& other)\r
{\r
x = other.x;\r
y = other.y;\r
z = other.z;\r
- w = other.w;\r
+ w = 0.f;\r
}\r
-};\r
\r
-struct sVec3\r
-{\r
- union\r
+ void normalize_pack_xyz(sVec3Pack& out, const f32 len, const f32 ofs) const\r
{\r
- struct { f32 r, g, b; };\r
- struct { f32 x, y, z; };\r
- };\r
+ //const f32 l = len * core::reciprocal_squareroot ( r * r + g * g + b * b );\r
+ f32 l = x * x + y * y + z * z;\r
\r
+ l = l > 0.0000001f ? len / sqrtf(l) : 0.f;\r
+ out.x = (x*l) + ofs;\r
+ out.y = (y*l) + ofs;\r
+ out.z = (z*l) + ofs;\r
+ }\r
\r
- sVec3 () {}\r
- sVec3 ( f32 _x, f32 _y, f32 _z )\r
- : r ( _x ), g ( _y ), b( _z ) {}\r
+};\r
\r
- sVec3 ( const sVec4 &v )\r
- : r ( v.x ), g ( v.y ), b( v.z ) {}\r
+//!during runtime sVec3Pack\r
+typedef sVec4 sVec3Pack_unpack;\r
\r
- void set ( f32 _r, f32 _g, f32 _b )\r
+//!sVec4 is argb. sVec3Color is rgba\r
+struct sVec3Color\r
+{\r
+ f32 r, g, b,a;\r
+\r
+ void set(const f32 s)\r
{\r
- r = _r;\r
- g = _g;\r
- b = _b;\r
+ r = s;\r
+ g = s;\r
+ b = s;\r
+ a = s;\r
}\r
\r
- void setR8G8B8 ( u32 argb )\r
+ void setA8R8G8B8(const u32 argb)\r
{\r
- r = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f );\r
- g = ( ( argb & 0x0000FF00 ) >> 8 ) * ( 1.f / 255.f );\r
- b = ( ( argb & 0x000000FF ) ) * ( 1.f / 255.f );\r
+ r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);\r
+ g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);\r
+ b = ((argb & 0x000000FF) ) * (1.f / 255.f);\r
+ a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);\r
}\r
\r
- void setColorf ( const video::SColorf & color )\r
+ void setColorf(const video::SColorf & color)\r
{\r
r = color.r;\r
g = color.g;\r
b = color.b;\r
+ a = color.a;\r
}\r
\r
- void add (const sVec3& other)\r
+ void add_rgb(const sVec3Color& other)\r
{\r
r += other.r;\r
g += other.g;\r
b += other.b;\r
}\r
\r
- void mulAdd(const sVec3& other, const f32 v)\r
+ void mad_rgb(const sVec3Color& other, const f32 v)\r
{\r
r += other.r * v;\r
g += other.g * v;\r
b += other.b * v;\r
}\r
\r
- void mulAdd(const sVec3& v0, const sVec3& v1)\r
+ void mad_rgbv(const sVec3Color& v0, const sVec3Color& v1)\r
{\r
r += v0.r * v1.r;\r
g += v0.g * v1.g;\r
b += v0.b * v1.b;\r
}\r
\r
- void saturate ( sVec4 &dest, u32 argb )\r
- {\r
- dest.x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f );\r
- dest.y = core::min_ ( r, 1.f );\r
- dest.z = core::min_ ( g, 1.f );\r
- dest.w = core::min_ ( b, 1.f );\r
- }\r
-\r
- // f = a * t + b * ( 1 - t )\r
- void interpolate(const sVec3& v0, const sVec3& v1, const f32 t)\r
- {\r
- r = v1.r + ( ( v0.r - v1.r ) * t );\r
- g = v1.g + ( ( v0.g - v1.g ) * t );\r
- b = v1.b + ( ( v0.b - v1.b ) * t );\r
- }\r
-\r
- sVec3 operator-(const sVec3& other) const\r
+ //sVec4 is a,r,g,b, alpha pass\r
+ void sat(sVec4 &dest, const u32 argb) const\r
{\r
- return sVec3(r - other.r, b - other.b, g - other.g);\r
+ dest.a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);\r
+ dest.r = r <= 1.f ? r : 1.f;\r
+ dest.g = g <= 1.f ? g : 1.f;\r
+ dest.b = b <= 1.f ? b : 1.f;\r
}\r
\r
- sVec3 operator+(const sVec3& other) const\r
+ void sat_xyz(sVec3Pack &dest, const sVec3Color& v1) const\r
{\r
- return sVec3(r + other.r, g + other.g, b + other.b);\r
+ f32 v;\r
+ v = r * v1.r; dest.x = v < 1.f ? v : 1.f;\r
+ v = g * v1.g; dest.y = v < 1.f ? v : 1.f;\r
+ v = b * v1.b; dest.z = v < 1.f ? v : 1.f;\r
}\r
\r
- sVec3 operator*(const f32 s) const\r
+ void sat_xyz(sVec4 &dest, const sVec3Color& v1) const\r
{\r
- return sVec3(r * s , g * s, b * s);\r
+ f32 v;\r
+ dest.a = 1.f;\r
+ v = r * v1.r; dest.r = v < 1.f ? v : 1.f;\r
+ v = g * v1.g; dest.g = v < 1.f ? v : 1.f;\r
+ v = b * v1.b; dest.b = v < 1.f ? v : 1.f;\r
}\r
\r
- sVec3 operator/(const f32 s) const\r
- {\r
- f32 inv = 1.f / s;\r
- return sVec3(r * inv , g * inv, b * inv);\r
- }\r
-\r
- sVec3 operator*(const sVec3 &other) const\r
- {\r
- return sVec3(r * other.r , b * other.b, g * other.g);\r
- }\r
-\r
- void operator+=(const sVec3& other)\r
- {\r
- r += other.r;\r
- g += other.g;\r
- b += other.b;\r
- }\r
-\r
- void setLength ( f32 len )\r
- {\r
- const f32 l = len * core::reciprocal_squareroot ( r * r + g * g + b * b );\r
-\r
- r *= l;\r
- g *= l;\r
- b *= l;\r
- }\r
\r
};\r
\r
-\r
-\r
-inline void sCompressedVec4::setVec4 ( const sVec4 & v )\r
-{\r
- argb = core::floor32_fast( v.x * 255.f ) << 24 |\r
- core::floor32_fast( v.y * 255.f ) << 16 |\r
- core::floor32_fast( v.z * 255.f ) << 8 |\r
- core::floor32_fast( v.w * 255.f );\r
-}\r
-\r
-\r
+//internal BurningShaderFlag for a Vertex\r
enum e4DVertexFlag\r
{\r
- VERTEX4D_INSIDE = 0x0000003F,\r
- VERTEX4D_CLIPMASK = 0x0000003F,\r
- VERTEX4D_PROJECTED = 0x00000100,\r
+ VERTEX4D_CLIPMASK = 0x0000003F,\r
+ VERTEX4D_CLIP_NEAR = 0x00000001,\r
+ VERTEX4D_CLIP_FAR = 0x00000002,\r
+ VERTEX4D_CLIP_LEFT = 0x00000004,\r
+ VERTEX4D_CLIP_RIGHT = 0x00000008,\r
+ VERTEX4D_CLIP_BOTTOM = 0x00000010,\r
+ VERTEX4D_CLIP_TOP = 0x00000020,\r
+ VERTEX4D_INSIDE = 0x0000003F,\r
+\r
+ VERTEX4D_PROJECTED = 0x00000100,\r
+ VERTEX4D_VAL_ZERO = 0x00000200,\r
+ VERTEX4D_VAL_ONE = 0x00000400,\r
\r
VERTEX4D_FORMAT_MASK = 0xFFFF0000,\r
\r
\r
VERTEX4D_FORMAT_MASK_COLOR = 0x00F00000,\r
VERTEX4D_FORMAT_COLOR_1 = 0x00100000,\r
- VERTEX4D_FORMAT_COLOR_2 = 0x00200000,\r
+ VERTEX4D_FORMAT_COLOR_2_FOG = 0x00200000,\r
+ VERTEX4D_FORMAT_COLOR_3 = 0x00300000,\r
+ VERTEX4D_FORMAT_COLOR_4 = 0x00400000,\r
+\r
+ VERTEX4D_FORMAT_MASK_LIGHT = 0x0F000000,\r
+ VERTEX4D_FORMAT_LIGHT_1 = 0x01000000,\r
+ VERTEX4D_FORMAT_LIGHT_2 = 0x02000000,\r
\r
- VERTEX4D_FORMAT_MASK_BUMP = 0x0F000000,\r
- VERTEX4D_FORMAT_BUMP_DOT3 = 0x01000000,\r
+ VERTEX4D_FORMAT_MASK_TANGENT = 0xF0000000,\r
+ VERTEX4D_FORMAT_BUMP_DOT3 = 0x10000000,\r
+ VERTEX4D_FORMAT_SPECULAR = 0x20000000,\r
\r
};\r
\r
-const u32 MATERIAL_MAX_COLORS = 1;\r
-const u32 BURNING_MATERIAL_MAX_TEXTURES = 2;\r
-const u32 BURNING_MATERIAL_MAX_TANGENT = 1;\r
+//! vertex layout\r
+enum e4DVertexType\r
+{\r
+ E4VT_STANDARD = 0, // EVT_STANDARD, video::S3DVertex.\r
+ E4VT_2TCOORDS = 1, // EVT_2TCOORDS, video::S3DVertex2TCoords.\r
+ E4VT_TANGENTS = 2, // EVT_TANGENTS, video::S3DVertexTangents\r
+ E4VT_REFLECTION_MAP = 3,\r
+ E4VT_SHADOW = 4, // float * 3\r
+ E4VT_NO_TEXTURE = 5, // runtime if texture missing\r
+ E4VT_LINE = 6,\r
+\r
+ E4VT_COUNT\r
+};\r
+\r
+enum e4DIndexType\r
+{\r
+ E4IT_16BIT = 1, // EIT_16BIT,\r
+ E4IT_32BIT = 2, // EIT_32BIT,\r
+ E4IT_NONE = 4, //\r
+};\r
+\r
+#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
+ #define BURNING_MATERIAL_MAX_TEXTURES 4\r
+ #define BURNING_MATERIAL_MAX_COLORS 4\r
+ #define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1\r
+\r
+ //ensure handcrafted sizeof(s4DVertex)\r
+ #define sizeof_s4DVertex 128\r
+\r
+#else\r
+ #define BURNING_MATERIAL_MAX_TEXTURES 2\r
+ #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+ #define BURNING_MATERIAL_MAX_COLORS 1\r
+ #else\r
+ #define BURNING_MATERIAL_MAX_COLORS 0\r
+ #endif\r
+ #define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1\r
+\r
+ //ensure handcrafted sizeof(s4DVertex)\r
+ #define sizeof_s4DVertex 64\r
+#endif\r
\r
// dummy Vertex. used for calculation vertex memory size\r
struct s4DVertex_proxy\r
{\r
- u32 flag;\r
sVec4 Pos;\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
sVec2 Tex[BURNING_MATERIAL_MAX_TEXTURES];\r
-\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
- sVec4 Color[MATERIAL_MAX_COLORS];\r
#endif\r
-\r
- sVec3 LightTangent[BURNING_MATERIAL_MAX_TANGENT];\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+ sVec4 Color[BURNING_MATERIAL_MAX_COLORS];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+ sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];\r
+#endif\r
+ u32 flag; // e4DVertexFlag\r
\r
};\r
\r
-#define SIZEOF_SVERTEX 64\r
-#define SIZEOF_SVERTEX_LOG2 6\r
\r
/*!\r
Internal BurningVideo Vertex\r
*/\r
struct s4DVertex\r
{\r
- u32 flag;\r
-\r
sVec4 Pos;\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
sVec2 Tex[ BURNING_MATERIAL_MAX_TEXTURES ];\r
-\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
- sVec4 Color[ MATERIAL_MAX_COLORS ];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+ sVec4 Color[ BURNING_MATERIAL_MAX_COLORS ];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+ sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];\r
#endif\r
\r
- sVec3 LightTangent[BURNING_MATERIAL_MAX_TANGENT];\r
+ u32 flag; // e4DVertexFlag\r
\r
- //u8 fill [ SIZEOF_SVERTEX - sizeof (s4DVertex_proxy) ];\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 1 || BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1\r
+ u8 __align [sizeof_s4DVertex - sizeof (s4DVertex_proxy) ];\r
+#endif\r
\r
// f = a * t + b * ( 1 - t )\r
- void interpolate(const s4DVertex& b, const s4DVertex& a, const f32 t)\r
+ void interpolate(const s4DVertex& burning_restrict b, const s4DVertex& burning_restrict a, const ipoltype t)\r
{\r
- u32 i;\r
- u32 size;\r
-\r
Pos.interpolate ( a.Pos, b.Pos, t );\r
+#if 0\r
+ Tex[0].interpolate(a.Tex[0], b.Tex[0], t);\r
+ Tex[1].interpolate(a.Tex[1], b.Tex[1], t);\r
+ Color[0].interpolate(a.Color[0], b.Color[0], t);\r
+ LightTangent[0].interpolate(a.LightTangent[0], b.LightTangent[0], t);\r
+#endif\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
- size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;\r
+ size_t i;\r
+ size_t size;\r
+\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
+ size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;\r
for ( i = 0; i!= size; ++i )\r
{\r
- Color[i].interpolate ( a.Color[i], b.Color[i], t );\r
+ Tex[i].interpolate ( a.Tex[i], b.Tex[i], t );\r
}\r
#endif\r
\r
- size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+ size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;\r
for ( i = 0; i!= size; ++i )\r
{\r
- Tex[i].interpolate ( a.Tex[i], b.Tex[i], t );\r
+ Color[i].interpolate ( a.Color[i], b.Color[i], t );\r
}\r
+#endif\r
\r
- size = (flag & VERTEX4D_FORMAT_MASK_BUMP) >> 24;\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+ size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24;\r
for ( i = 0; i!= size; ++i )\r
{\r
LightTangent[i].interpolate ( a.LightTangent[i], b.LightTangent[i], t );\r
}\r
+#endif\r
\r
}\r
};\r
\r
// ----------------- Vertex Cache ---------------------------\r
\r
-struct SAlignedVertex\r
+// Buffer is used as pairs of S4DVertex (0 ... ndc, 1 .. dc and projected)\r
+typedef s4DVertex s4DVertexPair;\r
+#define sizeof_s4DVertexPairRel 2\r
+#define s4DVertex_ofs(index) ((index)*sizeof_s4DVertexPairRel)\r
+#define s4DVertex_proj(index) ((index)*sizeof_s4DVertexPairRel) + 1\r
+\r
+struct SAligned4DVertex\r
{\r
- SAlignedVertex ( u32 element, u32 aligned )\r
- : ElementSize ( element )\r
+ SAligned4DVertex()\r
+ :data(0),mem(0), ElementSize(0) {}\r
+\r
+ virtual ~SAligned4DVertex ()\r
{\r
- u32 byteSize = (ElementSize << SIZEOF_SVERTEX_LOG2 ) + aligned;\r
- mem = new u8 [ byteSize ];\r
- data = (s4DVertex*) mem;\r
+ if (mem)\r
+ {\r
+ delete[] mem;\r
+ mem = 0;\r
+ }\r
}\r
\r
- virtual ~SAlignedVertex ()\r
+ void resize(size_t element)\r
{\r
- delete [] mem;\r
+ if (element > ElementSize)\r
+ {\r
+ if (mem) delete[] mem;\r
+ size_t byteSize = align_next(element * sizeof_s4DVertex, 4096);\r
+ mem = new u8[byteSize];\r
+ }\r
+ ElementSize = element;\r
+ data = (s4DVertex*)mem;\r
}\r
\r
- s4DVertex *data;\r
- u8 *mem;\r
- u32 ElementSize;\r
+ s4DVertex* data; //align to 16 byte\r
+ u8* mem;\r
+ size_t ElementSize;\r
};\r
\r
+//#define memcpy_s4DVertexPair(dst,src) memcpy(dst,src,sizeof_s4DVertex * 2)\r
+static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const void* burning_restrict src)\r
+{\r
+ //test alignment -> if already in aligned data\r
+#if 0\r
+ if (((size_t)dst & 0xC) | ((size_t)src & 0xC))\r
+ {\r
+ int g = 1;\r
+ }\r
+#endif\r
+\r
+#if defined(ENV64BIT) && (sizeof_s4DVertex * sizeof_s4DVertexPairRel == 128)\r
+ u64* burning_restrict dst64 = (u64*)dst;\r
+ const u64* burning_restrict src64 = (const u64*)src;\r
+\r
+ dst64[0] = src64[0];\r
+ dst64[1] = src64[1];\r
+ dst64[2] = src64[2];\r
+ dst64[3] = src64[3];\r
+ dst64[4] = src64[4];\r
+ dst64[5] = src64[5];\r
+ dst64[6] = src64[6];\r
+ dst64[7] = src64[7];\r
+\r
+ dst64[8] = src64[8];\r
+ dst64[9] = src64[9];\r
+ dst64[10] = src64[10];\r
+ dst64[11] = src64[11];\r
+ dst64[12] = src64[12];\r
+ dst64[13] = src64[13];\r
+ dst64[14] = src64[14];\r
+ dst64[15] = src64[15];\r
+\r
+#elif defined(ENV64BIT) && (sizeof_s4DVertex * sizeof_s4DVertexPairRel == 256)\r
+ u64* burning_restrict dst64 = (u64*)dst;\r
+ const u64* burning_restrict src64 = (const u64*)src;\r
+\r
+ dst64[0] = src64[0];\r
+ dst64[1] = src64[1];\r
+ dst64[2] = src64[2];\r
+ dst64[3] = src64[3];\r
+ dst64[4] = src64[4];\r
+ dst64[5] = src64[5];\r
+ dst64[6] = src64[6];\r
+ dst64[7] = src64[7];\r
+\r
+ dst64[8] = src64[8];\r
+ dst64[9] = src64[9];\r
+ dst64[10] = src64[10];\r
+ dst64[11] = src64[11];\r
+ dst64[12] = src64[12];\r
+ dst64[13] = src64[13];\r
+ dst64[14] = src64[14];\r
+ dst64[15] = src64[15];\r
+\r
+ dst64[16] = src64[16];\r
+ dst64[17] = src64[17];\r
+ dst64[18] = src64[18];\r
+ dst64[19] = src64[19];\r
+ dst64[20] = src64[20];\r
+ dst64[21] = src64[21];\r
+ dst64[22] = src64[22];\r
+ dst64[23] = src64[23];\r
+\r
+ dst64[24] = src64[24];\r
+ dst64[25] = src64[25];\r
+ dst64[26] = src64[26];\r
+ dst64[27] = src64[27];\r
+ dst64[28] = src64[28];\r
+ dst64[29] = src64[29];\r
+ dst64[30] = src64[30];\r
+ dst64[31] = src64[31];\r
\r
-// hold info for different Vertex Types\r
+#else\r
+ u32* dst32 = (u32*)dst;\r
+ const u32* src32 = (const u32*)src;\r
+\r
+ size_t len = sizeof_s4DVertex * sizeof_s4DVertexPairRel;\r
+ while (len >= 32)\r
+ {\r
+ *dst32++ = *src32++;\r
+ *dst32++ = *src32++;\r
+ *dst32++ = *src32++;\r
+ *dst32++ = *src32++;\r
+ *dst32++ = *src32++;\r
+ *dst32++ = *src32++;\r
+ *dst32++ = *src32++;\r
+ *dst32++ = *src32++;\r
+ len -= 32;\r
+ }\r
+/*\r
+ while (len >= 4)\r
+ {\r
+ *dst32++ = *src32++;\r
+ len -= 4;\r
+ }\r
+*/\r
+#endif\r
+}\r
+\r
+\r
+//! hold info for different Vertex Types\r
struct SVSize\r
{\r
- u32 Format;\r
- u32 Pitch;\r
- u32 TexSize;\r
+ size_t Format; // e4DVertexFlag VERTEX4D_FORMAT_MASK_TEXTURE\r
+ size_t Pitch; // sizeof Vertex\r
+ size_t TexSize; // amount Textures\r
+ size_t TexCooSize; // sizeof TextureCoordinates\r
};\r
\r
\r
u32 hit;\r
};\r
\r
-#define VERTEXCACHE_ELEMENT 16\r
+//must at least hold all possible (clipped) vertices of primitive.\r
+#define VERTEXCACHE_ELEMENT 16 \r
#define VERTEXCACHE_MISS 0xFFFFFFFF\r
struct SVertexCache\r
{\r
- SVertexCache (): mem ( VERTEXCACHE_ELEMENT * 2, 128 ) {}\r
+ SVertexCache () {}\r
+ ~SVertexCache() {}\r
+\r
+ //VertexType\r
+ SVSize vSize[E4VT_COUNT];\r
\r
SCacheInfo info[VERTEXCACHE_ELEMENT];\r
+ SCacheInfo info_temp[VERTEXCACHE_ELEMENT];\r
\r
\r
// Transformed and lite, clipping state\r
// + Clipped, Projected\r
- SAlignedVertex mem;\r
+ SAligned4DVertex mem;\r
\r
// source\r
const void* vertices;\r
const void* indices;\r
u32 indexCount;\r
u32 indicesIndex;\r
-\r
u32 indicesRun;\r
+ u32 indicesPitch;\r
\r
// primitives consist of x vertices\r
- u32 primitivePitch;\r
+ size_t primitiveHasVertex;\r
\r
- u32 vType; //E_VERTEX_TYPE\r
- u32 pType; //scene::E_PRIMITIVE_TYPE\r
- u32 iType; //E_INDEX_TYPE iType\r
+ e4DVertexType vType; //E_VERTEX_TYPE\r
+ scene::E_PRIMITIVE_TYPE pType; //scene::E_PRIMITIVE_TYPE\r
+ e4DIndexType iType; //E_INDEX_TYPE iType\r
\r
};\r
\r
// internal scan convert\r
struct sScanConvertData\r
{\r
- u8 left; // major edge left/right\r
- u8 right; // !left\r
+ u32 left; // major edge left/right\r
+ u32 right; // !left\r
+ u32 _unused_pack[2];\r
\r
- f32 invDeltaY[3]; // inverse edge delta y\r
+ f32 invDeltaY[4]; // inverse edge delta for screen space sorted triangle \r
\r
f32 x[2]; // x coordinate\r
f32 slopeX[2]; // x slope along edges\r
f32 slopeZ[2]; // z slope along edges\r
#endif\r
\r
- sVec4 c[MATERIAL_MAX_COLORS][2]; // color\r
- sVec4 slopeC[MATERIAL_MAX_COLORS][2]; // color slope along edges\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+ sVec4 c[BURNING_MATERIAL_MAX_COLORS][2]; // color\r
+ sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS][2]; // color slope along edges\r
+#endif\r
\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture\r
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture slope along edges\r
+#endif\r
\r
- sVec3 l[BURNING_MATERIAL_MAX_TANGENT][2]; // Light Tangent\r
- sVec3 slopeL[BURNING_MATERIAL_MAX_TEXTURES][2]; // tanget slope along edges\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+ sVec3Pack_unpack l[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2]; // Light Tangent\r
+ sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2]; // tanget slope along edges\r
+#endif\r
};\r
\r
// passed to scan Line\r
struct sScanLineData\r
{\r
s32 y; // y position of scanline\r
+ u32 _unused_pack[1];\r
f32 x[2]; // x start, x end of scanline\r
\r
#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )\r
f32 z[2]; // z start, z end of scanline\r
#endif\r
\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
- sVec4 c[MATERIAL_MAX_COLORS][2]; // color start, color end of scanline\r
+ u32 _unused_pack_1[2];\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+ sVec4 c[BURNING_MATERIAL_MAX_COLORS][2]; // color start, color end of scanline\r
#endif\r
\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture start, texture end of scanline\r
- sVec3 l[BURNING_MATERIAL_MAX_TANGENT][2]; // Light Tangent start, end\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+ sVec3Pack_unpack l[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2]; // Light Tangent start, end\r
+#endif\r
};\r
\r
// passed to pixel Shader\r
/*\r
load a color value\r
*/\r
-inline void getTexel_plain2 ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sVec4 &v\r
- )\r
+REALINLINE void getTexel_plain2 ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )\r
{\r
- r = tofix(v.y, FIX_POINT_F32_MUL);\r
- g = tofix(v.z, FIX_POINT_F32_MUL);\r
- b = tofix(v.w, FIX_POINT_F32_MUL);\r
+ r = tofix(v.r, FIX_POINT_F32_MUL);\r
+ g = tofix(v.g, FIX_POINT_F32_MUL);\r
+ b = tofix(v.b, FIX_POINT_F32_MUL);\r
}\r
\r
+#if 0\r
/*\r
load a color value\r
*/\r
-inline void getSample_color ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sVec4 &v\r
- )\r
+REALINLINE void getSample_color ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const sVec4 &v )\r
{\r
- a = tofix(v.x, FIX_POINT_F32_MUL);\r
- r = tofix ( v.y, COLOR_MAX * FIX_POINT_F32_MUL);\r
- g = tofix ( v.z, COLOR_MAX * FIX_POINT_F32_MUL);\r
- b = tofix ( v.w, COLOR_MAX * FIX_POINT_F32_MUL);\r
+ a = tofix ( v.a, FIX_POINT_F32_MUL);\r
+ r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL);\r
+ g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);\r
+ b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL);\r
}\r
\r
/*\r
load a color value\r
*/\r
-inline void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )\r
+REALINLINE void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )\r
{\r
- r = tofix ( v.y, COLOR_MAX * FIX_POINT_F32_MUL);\r
- g = tofix ( v.z, COLOR_MAX * FIX_POINT_F32_MUL);\r
- b = tofix ( v.w, COLOR_MAX * FIX_POINT_F32_MUL);\r
+ r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL);\r
+ g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);\r
+ b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL);\r
}\r
+#endif\r
\r
/*\r
- load a color value\r
+ load a color value. mulby controls [0;1] or [0;ColorMax]\r
+ aka getSample_color\r
*/\r
-inline void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sVec4 &v, const f32 mulby )\r
+REALINLINE void vec4_to_fix(tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby )\r
{\r
- r = tofix ( v.y, mulby);\r
- g = tofix ( v.z, mulby);\r
- b = tofix ( v.w, mulby);\r
+ r = tofix(v.r, mulby);\r
+ g = tofix(v.g, mulby);\r
+ b = tofix(v.b, mulby);\r
}\r
\r
+REALINLINE void vec4_to_fix(tFixPoint &a,tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby)\r
+{\r
+ a = tofix(v.a, mulby);\r
+ r = tofix(v.r, mulby);\r
+ g = tofix(v.g, mulby);\r
+ b = tofix(v.b, mulby);\r
+}\r
\r
\r
}\r
\r
#include "IrrCompileConfig.h"\r
\r
-\r
// Generic Render Flags for burning's video rasterizer\r
// defined now in irrlicht compile config\r
\r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
+ #undef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
+\r
+ //#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+ #define SOFTWARE_DRIVER_2_SUBTEXEL\r
+ //#define SOFTWARE_DRIVER_2_BILINEAR\r
+ #define SOFTWARE_DRIVER_2_LIGHTING\r
+ #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+ #define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR\r
+ #define SOFTWARE_DRIVER_2_32BIT\r
+ #define SOFTWARE_DRIVER_2_MIPMAPPING\r
+ #define SOFTWARE_DRIVER_2_USE_WBUFFER\r
+ #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
+ #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256\r
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+ #define SOFTWARE_DRIVER_2_CLIPPING\r
+ #define SOFTWARE_DRIVER_2_2D_AS_2D\r
+#endif\r
+\r
\r
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
#define SOFTWARE_DRIVER_2_BILINEAR\r
#define SOFTWARE_DRIVER_2_LIGHTING\r
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+ #define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR\r
#define SOFTWARE_DRIVER_2_32BIT\r
#define SOFTWARE_DRIVER_2_MIPMAPPING\r
#define SOFTWARE_DRIVER_2_USE_WBUFFER\r
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0\r
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+ #define SOFTWARE_DRIVER_2_CLIPPING\r
+ #define SOFTWARE_DRIVER_2_2D_AS_3D\r
#endif\r
\r
//! Set Flags for Windows Mobile\r
#define SOFTWARE_DRIVER_2_MIPMAPPING\r
#define SOFTWARE_DRIVER_2_USE_WBUFFER\r
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
- #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128\r
+ #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 64\r
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+ //#define SOFTWARE_DRIVER_2_CLIPPING\r
+ #define SOFTWARE_DRIVER_2_2D_AS_2D\r
#endif\r
\r
#ifdef BURNINGVIDEO_RENDERER_FAST\r
#define SOFTWARE_DRIVER_2_SUBTEXEL\r
//#define SOFTWARE_DRIVER_2_BILINEAR\r
//#define SOFTWARE_DRIVER_2_LIGHTING\r
- //#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
- #define SOFTWARE_DRIVER_2_32BIT\r
+ #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+ //#define SOFTWARE_DRIVER_2_32BIT\r
+ #define SOFTWARE_DRIVER_2_16BIT\r
#define SOFTWARE_DRIVER_2_MIPMAPPING\r
#define SOFTWARE_DRIVER_2_USE_WBUFFER\r
- #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0\r
+ #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256\r
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+ #define SOFTWARE_DRIVER_2_CLIPPING\r
+ #define SOFTWARE_DRIVER_2_2D_AS_2D\r
#endif\r
\r
#ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST\r
#define BURNINGVIDEO_RENDERER_FAST\r
\r
//#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
- #define SOFTWARE_DRIVER_2_SUBTEXEL\r
+ //#define SOFTWARE_DRIVER_2_SUBTEXEL\r
//#define SOFTWARE_DRIVER_2_BILINEAR\r
//#define SOFTWARE_DRIVER_2_LIGHTING\r
- //#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+ #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
//#define SOFTWARE_DRIVER_2_32BIT\r
- #define SOFTWARE_DRIVER_2_MIPMAPPING\r
- #define SOFTWARE_DRIVER_2_USE_WBUFFER\r
- #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0\r
+ #define SOFTWARE_DRIVER_2_16BIT\r
+ //#define SOFTWARE_DRIVER_2_MIPMAPPING\r
+ //#define SOFTWARE_DRIVER_2_USE_WBUFFER\r
+ //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
+ #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128\r
+ #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+ //#define SOFTWARE_DRIVER_2_CLIPPING\r
+ #define SOFTWARE_DRIVER_2_2D_AS_2D\r
#endif\r
\r
// Derivate flags\r
#define BURNINGSHADER_COLOR_FORMAT ECF_A1R5G5B5\r
#endif\r
\r
-// mip mapping\r
+// mip mapping - precalculated texture filter\r
#if defined ( SOFTWARE_DRIVER_2_MIPMAPPING )\r
#if defined( BURNINGVIDEO_RENDERER_BEAUTIFUL )\r
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16\r
- #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0\r
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1\r
#elif defined ( BURNINGVIDEO_RENDERER_CE )\r
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4\r
- #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0\r
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8\r
#else\r
- #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8\r
- #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0\r
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4\r
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8\r
#endif\r
#else\r
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1\r
- #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0\r
+ #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1\r
#endif\r
\r
-#define SOFTWARE_DRIVER_2_MIPMAPPING_SCALE (16/SOFTWARE_DRIVER_2_MIPMAPPING_MAX)\r
+\r
\r
#ifndef REALINLINE\r
#ifdef _MSC_VER\r
#endif\r
#endif\r
\r
+\r
+// null check necessary (burningvideo only)\r
+#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f)\r
+static inline float reciprocal_zero2(float x) { return x != 0.f ? 1.f / x : 0.f; }\r
+#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)\r
+\r
+#define fill_convention_left(x) (s32) ceilf(x)\r
+#define fill_convention_right(x) ((s32) ceilf(x))-1\r
+#define fill_convention_none(x) (s32) (x)\r
+//#define fill_convention_left(x) 65536 - int(65536.0f - x)\r
+//#define fill_convention_right(x) 65535 - int(65536.0f - x)\r
+\r
+\r
+//Check coordinates are in render target/window space\r
+//#define SOFTWARE_DRIVER_2_DO_CLIPCHECK\r
+#if defined (SOFTWARE_DRIVER_2_DO_CLIPCHECK) && defined(_WIN32)\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK if( xStart < 0 || xStart + dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK_REF if( pShader.xStart < 0 || pShader.xStart + pShader.dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE if( aposx < 0 || aposx >= (s32)RenderTarget->getDimension().Width || aposy < 0 || aposy >= (s32) RenderTarget->getDimension().Height ) __debugbreak()\r
+\r
+inline float reciprocal_zero_no(const float x)\r
+{\r
+ if (x*x <= 0.00001f) __debugbreak();\r
+ return 1.f / x;\r
+}\r
+#else\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK_REF\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE\r
+\r
+#define reciprocal_zero_no(x) 1.f/x\r
#endif\r
+\r
+//!scanline renderer emulate line\r
+enum edge_test_flag\r
+{\r
+ edge_test_pass = 1, //! not wireframe\r
+ edge_test_left = 0,\r
+ edge_test_first_line = 2,\r
+ edge_test_point = 4\r
+};\r
+//if any edge test flag is set result=1 else 0. ( pass height test for degenerate triangle )\r
+#define reciprocal_edge(x) ((x) != 0.f ? 1.f / (x):(~EdgeTestPass)&1)\r
+\r
+//! normalize from fixed point Color Max to fixed point [0;1]\r
+#define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2\r
+\r
+//! from 1 bit to 5 bit\r
+#ifdef SOFTWARE_DRIVER_2_32BIT\r
+ #define fix_alpha_color_max(x)\r
+#else\r
+ #define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1\r
+#endif\r
+\r
+// Check windows\r
+#if _WIN32 || _WIN64\r
+#if _WIN64\r
+ #define ENV64BIT\r
+#else\r
+ #define ENV32BIT\r
+#endif\r
+#endif\r
+\r
+// Check GCC\r
+#if __GNUC__\r
+#if __x86_64__ || __ppc64__\r
+ #define ENV64BIT\r
+#else\r
+ #define ENV32BIT\r
+#endif\r
+#endif\r
+\r
+#if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL)\r
+ typedef float ipoltype;\r
+#else\r
+ typedef float ipoltype;\r
+#endif\r
+\r
+#define ipol_lower_equal_0(n) ((n) <= (ipoltype)0.0)\r
+#define ipol_greater_0(n) ((n) > (ipoltype)0.0)\r
+\r
+#if (_MSC_VER > 1700 )\r
+ #define burning_restrict __restrict\r
+#else\r
+ #define burning_restrict\r
+#endif\r
+\r
+/*\r
+ if (condition) state |= mask; else state &= ~mask;\r
+*/\r
+static inline void burning_setbit(size_t &state, int condition, size_t mask)\r
+{\r
+ if (condition) state |= mask;\r
+ else state &= ~mask;\r
+}\r
+\r
+/*\r
+ if (condition) state |= m; else state &= ~m;\r
+*/\r
+REALINLINE void burning_setbit32(unsigned int &state, int condition, const unsigned int mask)\r
+{\r
+ // 0, or any positive to mask\r
+ //s32 conmask = -condition >> 31;\r
+ state ^= ((-condition >> 31) ^ state) & mask;\r
+}\r
+\r
+#define burning_stringify(s) #s\r
+#define burning_create_indirect(s) create_##s\r
+#define burning_create(s) burning_create_indirect(s)\r
+\r
+\r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
+#define getData lock\r
+#define snprintf_irr sprintf_s\r
+\r
+#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#ifdef SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR\r
+#define BURNING_MATERIAL_MAX_COLORS 2\r
+#else\r
+#define BURNING_MATERIAL_MAX_COLORS 1\r
+#endif\r
+#else\r
+#define BURNING_MATERIAL_MAX_COLORS 0\r
+#endif\r
+\r
+#ifndef _IRR_OVERRIDE_\r
+#define _IRR_OVERRIDE_ /**/\r
+#endif\r
+\r
+#define fix_to_color fix_to_sample\r
+#define fix4_to_color fix4_to_sample\r
+#define vec4_to_fix getSample_color\r
+#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0\r
+\r
+namespace irr {\r
+\r
+ REALINLINE void memcpy32_small(void * dest, const void *source, size_t bytesize)\r
+ {\r
+ size_t c = bytesize >> 2;\r
+\r
+ do\r
+ {\r
+ ((unsigned int *)dest)[c - 1] = ((unsigned int *)source)[c - 1];\r
+ } while (--c);\r
+\r
+ }\r
+\r
+} // namespace irr\r
+#endif // #if defined(PATCH_SUPERTUX_8_0_1)\r
+\r
+\r
+#endif // __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__\r
\r
#ifdef SOFTWARE_DRIVER_2_32BIT\r
typedef u32 tVideoSample;\r
+ typedef u32 tStencilSample;\r
\r
#define MASK_A 0xFF000000\r
#define MASK_R 0x00FF0000\r
#define MASK_G 0x0000FF00\r
#define MASK_B 0x000000FF\r
\r
- #define SHIFT_A 24\r
- #define SHIFT_R 16\r
- #define SHIFT_G 8\r
- #define SHIFT_B 0\r
+ #define SHIFT_A (unsigned)24\r
+ #define SHIFT_R (unsigned)16\r
+ #define SHIFT_G (unsigned)8\r
+ #define SHIFT_B (unsigned)0\r
\r
#define COLOR_MAX 0xFF\r
#define COLOR_MAX_LOG2 8\r
#define COLOR_BRIGHT_WHITE 0xFFFFFFFF\r
\r
- #define VIDEO_SAMPLE_GRANULARITY 2\r
+ #define VIDEO_SAMPLE_GRANULARITY (unsigned)2\r
\r
#else\r
typedef u16 tVideoSample;\r
+ typedef u8 tStencilSample;\r
\r
#define MASK_A 0x8000\r
#define MASK_R 0x7C00\r
#define MASK_G 0x03E0\r
#define MASK_B 0x001F\r
\r
- #define SHIFT_A 15\r
- #define SHIFT_R 10\r
- #define SHIFT_G 5\r
- #define SHIFT_B 0\r
+ #define SHIFT_A (unsigned)15\r
+ #define SHIFT_R (unsigned)10\r
+ #define SHIFT_G (unsigned)5\r
+ #define SHIFT_B (unsigned)0\r
\r
#define COLOR_MAX 0x1F\r
#define COLOR_MAX_LOG2 5\r
#define COLOR_BRIGHT_WHITE 0xFFFF\r
- #define VIDEO_SAMPLE_GRANULARITY 1\r
+ #define VIDEO_SAMPLE_GRANULARITY (unsigned)1\r
\r
#endif\r
\r
\r
\r
// ----------------------- Generic ----------------------------------\r
+//! align_next - align to next upper 2^n\r
+#define align_next(num,to) (((num) + (to-1)) & (~(to-1)))\r
\r
-//! a more useful memset for pixel\r
+//! a more useful memset for pixel. dest must be aligned at least to 4 byte\r
// (standard memset only works with 8-bit values)\r
-inline void memset32(void * dest, const u32 value, u32 bytesize)\r
+inline void memset32(void * dest, const u32 value, size_t bytesize)\r
{\r
u32 * d = (u32*) dest;\r
\r
- u32 i;\r
+ size_t i;\r
\r
// loops unrolled to reduce the number of increments by factor ~8.\r
i = bytesize >> (2 + 3);\r
}\r
}\r
\r
-//! a more useful memset for pixel\r
+//! a more useful memset for pixel. dest must be aligned at least to 2 byte\r
// (standard memset only works with 8-bit values)\r
-inline void memset16(void * dest, const u16 value, u32 bytesize)\r
+inline void memset16(void * dest, const u16 value, size_t bytesize)\r
{\r
u16 * d = (u16*) dest;\r
\r
- u32 i;\r
+ size_t i;\r
\r
// loops unrolled to reduce the number of increments by factor ~8.\r
i = bytesize >> (1 + 3);\r
}\r
}\r
\r
-/*\r
- use biased loop counter\r
- --> 0 byte copy is forbidden\r
-*/\r
-REALINLINE void memcpy32_small ( void * dest, const void *source, u32 bytesize )\r
-{\r
- u32 c = bytesize >> 2;\r
\r
- do\r
- {\r
- ((u32*) dest ) [ c-1 ] = ((u32*) source) [ c-1 ];\r
- } while ( --c );\r
+// byte-align structures\r
+#include "irrpack.h"\r
\r
-}\r
+//IEEE Standard for Floating - Point Arithmetic(IEEE 754)\r
+typedef union {\r
+ float f;\r
+ unsigned int u;\r
+ struct { unsigned int frac:23; unsigned exp:8; unsigned int sign:1; } fields;\r
+ struct { unsigned int frac_exp:31; } abs;\r
+} ieee754 PACK_STRUCT;\r
\r
+// Default alignment\r
+#include "irrunpack.h"\r
\r
+// 0.5f as integer\r
+#define ieee754_zero_dot_5 0x3f000000\r
+#define ieee754_one 0x3f800000\r
+#define ieee754_two 0x40000000\r
\r
-// integer log2 of a float ieee 754. TODO: non ieee floating point\r
+#if 0\r
+// integer log2 of a float ieee 754. [not used anymore]\r
static inline s32 s32_log2_f32( f32 f)\r
{\r
- u32 x = IR ( f );\r
- return ((x & 0x7F800000) >> 23) - 127;\r
+ //u32 x = IR ( f ); return ((x & 0x7F800000) >> 23) - 127;\r
+ ieee754 _log2;\r
+ _log2.f = f;\r
+ return _log2.fields.exp ? _log2.fields.exp - 127 : 10000000; /*denormal very high number*/\r
}\r
+#endif\r
\r
-static inline s32 s32_log2_s32(u32 x)\r
+// integer log2 of an integer. returning 0 as denormal\r
+static inline s32 s32_log2_s32(u32 in)\r
{\r
- return s32_log2_f32( (f32) x);\r
+ s32 ret = 0;\r
+ while (in > 1)\r
+ {\r
+ in >>= 1;\r
+ ret++;\r
+ }\r
+ return ret;\r
+ //return s32_log2_f32( (f32) x);\r
+ //ieee754 _log2;_log2.f = (f32) in; return _log2.fields.exp - 127; \r
}\r
\r
+#if 0\r
static inline s32 s32_abs(s32 x)\r
{\r
s32 b = x >> 31;\r
{\r
return ( mask & ( a ^ b ) ) ^ b;\r
}\r
+#endif\r
\r
// ------------------ Video---------------------------------------\r
/*!\r
Pixel = dest * ( 1 - alpha ) + source * alpha\r
alpha [0;256]\r
*/\r
-REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, u32 alpha )\r
+REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, const u32 alpha )\r
{\r
u32 srcRB = c1 & 0x00FF00FF;\r
u32 srcXG = c1 & 0x0000FF00;\r
Pixel = dest * ( 1 - alpha ) + source * alpha\r
alpha [0;32]\r
*/\r
-inline u16 PixelBlend16 ( const u16 c2, const u32 c1, const u16 alpha )\r
+inline u16 PixelBlend16 ( const u16 c2, const u16 c1, const u16 alpha )\r
{\r
const u16 srcRB = c1 & 0x7C1F;\r
const u16 srcXG = c1 & 0x03E0;\r
return (c1 & 0xFF000000) | rb | xg;\r
}\r
\r
-/*!\r
- Pixel =>\r
- color = sourceAlpha > 0 ? source, else dest\r
- alpha = max(destAlpha, sourceAlpha)\r
-*/\r
-inline u16 PixelCombine16 ( const u16 c2, const u16 c1 )\r
-{\r
- if ( video::getAlpha(c1) > 0 )\r
- return c1;\r
- else\r
- return c2;\r
-}\r
-\r
-/*!\r
- Pixel =>\r
- color = dest * ( 1 - SourceAlpha ) + source * SourceAlpha,\r
- alpha = destAlpha * ( 1 - SourceAlpha ) + sourceAlpha\r
-\r
- where "1" means "full scale" (255)\r
-*/\r
-inline u32 PixelCombine32 ( const u32 c2, const u32 c1 )\r
-{\r
- // alpha test\r
- u32 alpha = c1 & 0xFF000000;\r
-\r
- if ( 0 == alpha )\r
- return c2;\r
- if ( 0xFF000000 == alpha )\r
- {\r
- return c1;\r
- }\r
-\r
- alpha >>= 24;\r
-\r
- // add highbit alpha, if ( alpha > 127 ) alpha += 1;\r
- // stretches [0;255] to [0;256] to avoid division by 255. use division 256 == shr 8\r
- alpha += ( alpha >> 7);\r
-\r
- u32 srcRB = c1 & 0x00FF00FF;\r
- u32 srcXG = c1 & 0x0000FF00;\r
-\r
- u32 dstRB = c2 & 0x00FF00FF;\r
- u32 dstXG = c2 & 0x0000FF00;\r
-\r
-\r
- u32 rb = srcRB - dstRB;\r
- u32 xg = srcXG - dstXG;\r
-\r
- rb *= alpha;\r
- xg *= alpha;\r
- rb >>= 8;\r
- xg >>= 8;\r
-\r
- rb += dstRB;\r
- xg += dstXG;\r
-\r
- rb &= 0x00FF00FF;\r
- xg &= 0x0000FF00;\r
-\r
- u32 sa = c1 >> 24;\r
- u32 da = c2 >> 24;\r
- u32 blendAlpha_fix8 = (sa*256 + da*(256-alpha))>>8;\r
- return blendAlpha_fix8 << 24 | rb | xg;\r
-}\r
-\r
\r
\r
// ------------------ Fix Point ----------------------------------\r
\r
+#if defined(ENV64BIT)\r
typedef s32 tFixPoint;\r
typedef u32 tFixPointu;\r
+#else\r
+typedef s32 tFixPoint;\r
+typedef u32 tFixPointu;\r
+#endif\r
\r
-// Fix Point 12\r
+// Fix Point 12 (overflow on s32)\r
#if 0\r
#define FIX_POINT_PRE 12\r
#define FIX_POINT_FRACT_MASK 0xFFF\r
- #define FIX_POINT_SIGNED_MASK 0xFFFFF000\r
#define FIX_POINT_UNSIGNED_MASK 0x7FFFF000\r
#define FIX_POINT_ONE 0x1000\r
#define FIX_POINT_ZERO_DOT_FIVE 0x0800\r
#define FIX_POINT_F32_MUL 4096.f\r
#endif\r
\r
+// Fix Point 11 (overflow on s32)\r
+#if 0\r
+ #define FIX_POINT_PRE 11\r
+ #define FIX_POINT_FRACT_MASK 0x7FF\r
+ #define FIX_POINT_UNSIGNED_MASK 0xFFFFF800\r
+ #define FIX_POINT_ONE 0x800\r
+ #define FIX_POINT_ZERO_DOT_FIVE 0x400\r
+ #define FIX_POINT_F32_MUL 2048.f\r
+#endif\r
+\r
// Fix Point 10\r
#if 1\r
#define FIX_POINT_PRE 10\r
- #define FIX_POINT_FRACT_MASK 0x3FF\r
- #define FIX_POINT_SIGNED_MASK 0xFFFFFC00\r
+ #define FIX_POINT_FRACT_MASK 0x000003FF\r
#define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00\r
- #define FIX_POINT_ONE 0x400\r
- #define FIX_POINT_ZERO_DOT_FIVE 0x200\r
+ #define FIX_POINT_ONE 0x00000400\r
+ #define FIX_POINT_ZERO_DOT_FIVE 0x00000200\r
#define FIX_POINT_F32_MUL 1024.f\r
#endif\r
\r
#if 0\r
#define FIX_POINT_PRE 9\r
#define FIX_POINT_FRACT_MASK 0x1FF\r
- #define FIX_POINT_SIGNED_MASK 0xFFFFFE00\r
#define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00\r
#define FIX_POINT_ONE 0x200\r
#define FIX_POINT_ZERO_DOT_FIVE 0x100\r
#if 0\r
#define FIX_POINT_PRE 7\r
#define FIX_POINT_FRACT_MASK 0x7F\r
- #define FIX_POINT_SIGNED_MASK 0xFFFFFF80\r
#define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80\r
#define FIX_POINT_ONE 0x80\r
#define FIX_POINT_ZERO_DOT_FIVE 0x40\r
#endif\r
\r
#define FIXPOINT_COLOR_MAX ( COLOR_MAX << FIX_POINT_PRE )\r
-#define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )\r
+\r
+#if FIX_POINT_PRE == 10 && COLOR_MAX == 255\r
+ #define FIX_POINT_HALF_COLOR 0x1FE00\r
+ #define FIX_POINT_COLOR_ERROR 4\r
+#elif FIX_POINT_PRE == 12 && COLOR_MAX == 255\r
+ #define FIX_POINT_HALF_COLOR 0x7F800\r
+ #define FIX_POINT_COLOR_ERROR 16\r
+#elif FIX_POINT_PRE == 10 && COLOR_MAX == 31\r
+ #define FIX_POINT_HALF_COLOR 0x3E00\r
+ #define FIX_POINT_COLOR_ERROR 32\r
+#else\r
+ #define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )\r
+ #define FIX_POINT_COLOR_ERROR (1<<(FIX_POINT_PRE-COLOR_MAX_LOG2))\r
+#endif\r
\r
\r
/*\r
\r
inline u32 fixPointu_to_u32 (const tFixPointu x)\r
{\r
- return x >> FIX_POINT_PRE;\r
+ return (u32)(x >> FIX_POINT_PRE);\r
}\r
\r
\r
// 1/x * FIX_POINT\r
#define fix_inverse32(x) (FIX_POINT_F32_MUL / (x))\r
+#define fix_inverse32_color(x) ((FIX_POINT_F32_MUL*COLOR_MAX) / (x))\r
\r
\r
/*\r
hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different\r
others should use their favourite assembler..\r
*/\r
+#if 0\r
static inline int f_round2(f32 f)\r
{\r
f += (3<<22);\r
return IR(f) - 0x4b400000;\r
}\r
+#endif\r
\r
/*\r
convert f32 to Fix Point.\r
multiply is needed anyway, so scale mulby\r
*/\r
+/*\r
REALINLINE tFixPoint tofix0 (const f32 x, const f32 mulby = FIX_POINT_F32_MUL )\r
{\r
return (tFixPoint) (x * mulby);\r
}\r
+*/\r
#define tofix(x,y) (tFixPoint)(x * y)\r
\r
+\r
/*\r
Fix Point , Fix Point Multiply\r
*/\r
+/*\r
REALINLINE tFixPointu imulFixu(const tFixPointu x, const tFixPointu y)\r
{\r
return (x * y) >> (tFixPointu) FIX_POINT_PRE;\r
}\r
+*/\r
+#define imulFixu(x,y) (((x) * (y)) >> (tFixPointu) FIX_POINT_PRE)\r
+\r
\r
/*\r
Fix Point , Fix Point Multiply\r
*/\r
REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y)\r
{\r
- return ( x * y) >> ( FIX_POINT_PRE );\r
+ return (x * y) >> FIX_POINT_PRE;\r
}\r
\r
+#define imulFix_simple(x,y) ((x*y)>>FIX_POINT_PRE)\r
+\r
+#if 0\r
/*\r
Fix Point , Fix Point Multiply x * y * 2\r
*/\r
{\r
return ( x * y) >> ( FIX_POINT_PRE -1 );\r
}\r
-\r
+#endif\r
\r
/*\r
- Multiply x * y * 1\r
+ Multiply x * y * 1 FIXPOINT_COLOR_MAX\r
*/\r
REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y)\r
{\r
- return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 4 );\r
+#ifdef SOFTWARE_DRIVER_2_32BIT\r
+ return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4);\r
+#else\r
+ return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5);\r
+#endif\r
}\r
\r
/*\r
}\r
\r
/*\r
- Multiply x * y * 4\r
+ Multiply x * y * 4 clamp\r
*/\r
+\r
REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)\r
{\r
#ifdef SOFTWARE_DRIVER_2_32BIT\r
- return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 );\r
+ register tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2);\r
#else\r
- return ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) );\r
+ register tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3);\r
#endif\r
+ register tFixPoint mask = (a - FIXPOINT_COLOR_MAX) >> 31;\r
+ return (a & mask) | (FIXPOINT_COLOR_MAX & ~mask);\r
}\r
\r
+\r
+#if 0\r
+#define imulFix_tex1(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 4))\r
+#define imulFix_tex2(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 3))\r
+\r
+#ifdef SOFTWARE_DRIVER_2_32BIT\r
+#define imulFix_tex4(x,y) ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 )\r
+#else\r
+#define imulFix_tex4(x,y) ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) )\r
+#endif\r
+#endif\r
+\r
/*!\r
- clamp FixPoint to maxcolor in FixPoint, min(a,31)\r
+ clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX)\r
*/\r
REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a)\r
{\r
- tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;\r
+ register tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;\r
return (a & c) | ( FIXPOINT_COLOR_MAX & ~c);\r
}\r
\r
+\r
/*!\r
clamp FixPoint to 0 in FixPoint, max(a,0)\r
*/\r
// rount fixpoint to int\r
inline s32 roundFix ( const tFixPoint x )\r
{\r
- return ( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE;\r
+ return (s32)(( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE);\r
}\r
\r
\r
\r
// x in [0;1[\r
+#if 0\r
inline s32 f32_to_23Bits(const f32 x)\r
{\r
f32 y = x + 1.f;\r
return IR(y) & 0x7FFFFF; // last 23 bits\r
}\r
+#endif\r
\r
/*!\r
- return VideoSample from fixpoint\r
+ fixpoint in [0..Fixpoint_color] to VideoSample xrgb\r
*/\r
-REALINLINE tVideoSample fix_to_color ( const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
+REALINLINE tVideoSample fix_to_sample ( const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
{\r
return ( FIXPOINT_COLOR_MAX & FIXPOINT_COLOR_MAX) << ( SHIFT_A - FIX_POINT_PRE ) |\r
( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |\r
\r
\r
/*!\r
- return VideoSample from fixpoint\r
+ fixpoint to VideoSample argb\r
+ a in [0;1]\r
+ rgb in [0;255] colormax\r
*/\r
-REALINLINE tVideoSample fix4_to_color ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
+REALINLINE tVideoSample fix4_to_sample ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
{\r
return ( a & (FIX_POINT_FRACT_MASK - 1 )) << ( SHIFT_A - 1 ) |\r
( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |\r
}\r
\r
/*!\r
- return fixpoint from VideoSample granularity COLOR_MAX\r
+ return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
*/\r
inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )\r
{\r
}\r
\r
/*!\r
- return fixpoint from VideoSample granularity COLOR_MAX\r
+ return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
*/\r
inline void color_to_fix ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )\r
{\r
(tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
(tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
(tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );\r
+\r
+ //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
+ r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+ g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+ b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
}\r
\r
/*!\r
(tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
(tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
(tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );\r
+\r
+ //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
+ a += (a & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+ r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+ g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+ b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+\r
+}\r
+\r
+/*!\r
+ return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
+*/\r
+inline void color_to_fix(tFixPoint c[4], const tVideoSample t00)\r
+{\r
+ c[0] = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
+ c[1] = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+ c[2] = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+ c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
+}\r
+\r
+/*!\r
+ return fixpoint from VideoSample granularity 0..FIX_POINT_ONE\r
+*/\r
+inline void color_to_fix1(tFixPoint c[4], const tVideoSample t00)\r
+{\r
+ c[0] = (t00 & MASK_A) >> (SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
+ c[1] = (t00 & MASK_R) >> (SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
+ c[2] = (t00 & MASK_G) >> (SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
+ c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - COLOR_MAX_LOG2);\r
+\r
+ //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
+ c[0] += (c[0] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+ c[1] += (c[1] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+ c[2] += (c[2] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+ c[3] += (c[3] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+\r
}\r
\r
\r
\r
-// ----- FP24 ---- floating point z-buffer\r
+//! ----- FP24 1.23 fix point z-buffer\r
\r
#if 1\r
typedef f32 fp24;\r
\r
struct sInternalTexture\r
{\r
- u32 textureXMask;\r
- u32 textureYMask;\r
+ //power-of-two\r
+ void* data; //tVideoSample* Texture->lock(miplevel)\r
+ size_t textureXMask;\r
+ size_t textureYMask;\r
\r
- u32 pitchlog2;\r
- void *data;\r
+ size_t pitchlog2;\r
\r
video::CSoftwareTexture2 *Texture;\r
- s32 lodLevel;\r
+ s32 lodFactor; // magnify/minify\r
};\r
\r
\r
\r
// get video sample plain\r
-inline tVideoSample getTexel_plain ( const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty )\r
+static inline tVideoSample getTexel_plain ( const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty )\r
{\r
- u32 ofs;\r
+ register size_t ofs;\r
\r
ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
\r
// get video sample to fix\r
inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
+ const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty\r
)\r
{\r
- u32 ofs;\r
+ register size_t ofs;\r
\r
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+ ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
+ ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
\r
// texel\r
- tVideoSample t00;\r
+ register tVideoSample t00;\r
t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
\r
r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
\r
}\r
\r
-// get video sample to fixpoint\r
-REALINLINE void getTexel_fix ( tFixPoint &a,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty)\r
+// get video sample to fixpoint colormax\r
+inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+ const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty\r
+)\r
{\r
- u32 ofs;\r
+ register size_t ofs;\r
\r
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+ ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+ ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
\r
// texel\r
- tVideoSample t00;\r
- t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+ register tVideoSample t00;\r
+ t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
\r
- a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);\r
-}\r
+ a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
+ r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+ g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+ b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
\r
+}\r
\r
-inline void getSample_texture_dither ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty,\r
- const u32 x, const u32 y\r
- )\r
+#if 0\r
+// get video sample to fixpoint\r
+static REALINLINE void getTexel_fix ( tFixPoint &a,\r
+ const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty)\r
{\r
- static const tFixPointu dithermask[] =\r
- {\r
- 0x00,0x80,0x20,0xa0,\r
- 0xc0,0x40,0xe0,0x60,\r
- 0x30,0xb0,0x10,0x90,\r
- 0xf0,0x70,0xd0,0x50\r
- };\r
-\r
- const u32 index = (y & 3 ) << 2 | (x & 3);\r
-\r
- const tFixPointu _ntx = (tx + dithermask [ index ] ) & t->textureXMask;\r
- const tFixPointu _nty = (ty + dithermask [ index ] ) & t->textureYMask;\r
+ size_t ofs;\r
\r
- u32 ofs;\r
- ofs = ( ( _nty ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- ofs |= ( _ntx ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+ ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
+ ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
\r
// texel\r
- const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
-\r
- (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
- (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
- (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
+ tVideoSample t00;\r
+ t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
\r
+ a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);\r
}\r
+#endif\r
\r
/*\r
load a sample from internal texture at position tx,ty to fixpoint\r
*/\r
-#ifndef SOFTWARE_DRIVER_2_BILINEAR\r
-\r
-// get Sample linear == getSample_fixpoint\r
+#if defined(SOFTWARE_DRIVER_2_BILINEAR)\r
\r
-inline void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
- )\r
+#if 0\r
+// texture2D in fixpoint color range bilinear\r
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+ const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
+)\r
{\r
- u32 ofs;\r
-\r
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
-\r
- // texel\r
- const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+#if 0\r
+ if (t->lodFactor > 0)\r
+ {\r
+ register size_t ofs;\r
\r
- (tFixPointu &) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
- (tFixPointu &) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
- (tFixPointu &) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
-}\r
+ ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+ ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
\r
-inline void getSample_texture ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
- )\r
-{\r
- u32 ofs;\r
+ // texel\r
+ tVideoSample t00;\r
+ t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
\r
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+ r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+ g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+ b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
+ return;\r
+ }\r
+#endif\r
\r
- // texel\r
- const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+ tFixPointu r00, g00, b00;\r
+ tFixPointu r01, g01, b01;\r
+ tFixPointu r10, g10, b10;\r
+ tFixPointu r11, g11, b11;\r
+\r
+ size_t o0, o1, o2, o3;\r
+ register tVideoSample t00;\r
+\r
+ //wraps positive (ignoring negative)\r
+ o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+ o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+ o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+ o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+\r
+ t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2)));\r
+ r00 = (t00 & MASK_R) >> SHIFT_R;\r
+ g00 = (t00 & MASK_G) >> SHIFT_G;\r
+ b00 = (t00 & MASK_B);\r
+\r
+ t00 = *((tVideoSample*)((u8*)t->data + (o0 + o3)));\r
+ r10 = (t00 & MASK_R) >> SHIFT_R;\r
+ g10 = (t00 & MASK_G) >> SHIFT_G;\r
+ b10 = (t00 & MASK_B);\r
+\r
+ t00 = *((tVideoSample*)((u8*)t->data + (o1 + o2)));\r
+ r01 = (t00 & MASK_R) >> SHIFT_R;\r
+ g01 = (t00 & MASK_G) >> SHIFT_G;\r
+ b01 = (t00 & MASK_B);\r
+\r
+ t00 = *((tVideoSample*)((u8*)t->data + (o1 + o3)));\r
+ r11 = (t00 & MASK_R) >> SHIFT_R;\r
+ g11 = (t00 & MASK_G) >> SHIFT_G;\r
+ b11 = (t00 & MASK_B);\r
+\r
+\r
+ register tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;\r
+ register tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;\r
+\r
+ //w00 w01 w10 w11\r
+ tFixPointu w[4];\r
+ w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);\r
+ w[1] = imulFixu(FIX_POINT_ONE - fracx, fracy);\r
+ w[2] = imulFixu(fracx, FIX_POINT_ONE - fracy);\r
+ w[3] = imulFixu(fracx, fracy);\r
+\r
+ r = (r00 * w[0]) +\r
+ (r01 * w[1]) +\r
+ (r10 * w[2]) +\r
+ (r11 * w[3]);\r
+\r
+ g = (g00 * w[0]) +\r
+ (g01 * w[1]) +\r
+ (g10 * w[2]) +\r
+ (g11 * w[3]);\r
+\r
+ b = (b00 * w[0]) +\r
+ (b01 * w[1]) +\r
+ (b10 * w[2]) +\r
+ (b11 * w[3]);\r
\r
- (tFixPointu &)a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);\r
- (tFixPointu &)r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
- (tFixPointu &)g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
- (tFixPointu &)b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
}\r
\r
-\r
#else\r
\r
-\r
-// get sample linear\r
-REALINLINE void getSample_linear ( tFixPointu &r, tFixPointu &g, tFixPointu &b,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
- )\r
+// texture2D in fixpoint color range bilinear\r
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+ const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty\r
+)\r
{\r
- u32 ofs;\r
+#if 0\r
+ if (tex->lodFactor > 1)\r
+ {\r
+ //nearest neighbor\r
+ register size_t ofs;\r
+ ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+ ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+\r
+ register tVideoSample t00;\r
+ t00 = *((tVideoSample*)((u8*)tex->data + ofs));\r
+\r
+ r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+ g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+ b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
+ return;\r
+ }\r
+#endif\r
+ //w00 w01 w10 w11\r
+ tFixPointu w[4];\r
+ {\r
+ register tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;\r
+ register tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;\r
+ w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);\r
+ w[1] = imulFixu(fracx, FIX_POINT_ONE - fracy);\r
+ w[2] = imulFixu(FIX_POINT_ONE - fracx, fracy);\r
+ w[3] = imulFixu(fracx, fracy);\r
+ }\r
\r
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+ //wraps positive (ignoring negative)\r
+ tVideoSample t[4];\r
+ {\r
+ register size_t o0, o1, o2, o3;\r
+ o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+ o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+ o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+ o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+\r
+ t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));\r
+ t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));\r
+ t[2] = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));\r
+ t[3] = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));\r
+ }\r
\r
- // texel\r
- tVideoSample t00;\r
- t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+ r = (((t[0] & MASK_R) >> SHIFT_R) * w[0]) +\r
+ (((t[1] & MASK_R) >> SHIFT_R) * w[1]) +\r
+ (((t[2] & MASK_R) >> SHIFT_R) * w[2]) +\r
+ (((t[3] & MASK_R) >> SHIFT_R) * w[3]);\r
\r
- r = (t00 & MASK_R) >> SHIFT_R;\r
- g = (t00 & MASK_G) >> SHIFT_G;\r
- b = (t00 & MASK_B);\r
+ g = (((t[0] & MASK_G) >> SHIFT_G) * w[0]) +\r
+ (((t[1] & MASK_G) >> SHIFT_G) * w[1]) +\r
+ (((t[2] & MASK_G) >> SHIFT_G) * w[2]) +\r
+ (((t[3] & MASK_G) >> SHIFT_G) * w[3]);\r
+\r
+ b = ((t[0] & MASK_B) * w[0]) +\r
+ ((t[1] & MASK_B) * w[1]) +\r
+ ((t[2] & MASK_B) * w[2]) +\r
+ ((t[3] & MASK_B) * w[3]);\r
}\r
\r
+#endif\r
+\r
// get Sample bilinear\r
-REALINLINE void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
- )\r
+static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+ const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty\r
+)\r
{\r
\r
- tFixPointu r00,g00,b00;\r
- tFixPointu r01,g01,b01;\r
- tFixPointu r10,g10,b10;\r
- tFixPointu r11,g11,b11;\r
-\r
-#if 0\r
- getSample_linear ( r00, g00, b00, t, tx,ty );\r
- getSample_linear ( r10, g10, b10, t, tx + FIX_POINT_ONE,ty );\r
- getSample_linear ( r01, g01, b01, t, tx,ty + FIX_POINT_ONE );\r
- getSample_linear ( r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE );\r
-#else\r
- u32 o0, o1,o2,o3;\r
- tVideoSample t00;\r
-\r
- o0 = ( ( (ty) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- o1 = ( ( (ty+FIX_POINT_ONE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- o2 = ( (tx) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
- o3 = ( (tx+FIX_POINT_ONE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
-\r
- t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o2 ) ));\r
- r00 = (t00 & MASK_R) >> SHIFT_R;\r
- g00 = (t00 & MASK_G) >> SHIFT_G;\r
- b00 = (t00 & MASK_B);\r
-\r
- t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o3 ) ));\r
- r10 = (t00 & MASK_R) >> SHIFT_R;\r
- g10 = (t00 & MASK_G) >> SHIFT_G;\r
- b10 = (t00 & MASK_B);\r
-\r
- t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o2 ) ));\r
- r01 = (t00 & MASK_R) >> SHIFT_R;\r
- g01 = (t00 & MASK_G) >> SHIFT_G;\r
- b01 = (t00 & MASK_B);\r
-\r
- t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o3 ) ));\r
- r11 = (t00 & MASK_R) >> SHIFT_R;\r
- g11 = (t00 & MASK_G) >> SHIFT_G;\r
- b11 = (t00 & MASK_B);\r
-\r
-#endif\r
+ tFixPointu a00, r00, g00, b00;\r
+ tFixPointu a01, r01, g01, b01;\r
+ tFixPointu a10, r10, g10, b10;\r
+ tFixPointu a11, r11, g11, b11;\r
+\r
+ size_t o0, o1, o2, o3;\r
+ register tVideoSample t00;\r
+\r
+ o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+ o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+ o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+ o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+\r
+ t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));\r
+ a00 = (t00 & MASK_A) >> SHIFT_A;\r
+ r00 = (t00 & MASK_R) >> SHIFT_R;\r
+ g00 = (t00 & MASK_G) >> SHIFT_G;\r
+ b00 = (t00 & MASK_B);\r
+\r
+ t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));\r
+ a10 = (t00 & MASK_A) >> SHIFT_A;\r
+ r10 = (t00 & MASK_R) >> SHIFT_R;\r
+ g10 = (t00 & MASK_G) >> SHIFT_G;\r
+ b10 = (t00 & MASK_B);\r
+\r
+ t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));\r
+ a01 = (t00 & MASK_A) >> SHIFT_A;\r
+ r01 = (t00 & MASK_R) >> SHIFT_R;\r
+ g01 = (t00 & MASK_G) >> SHIFT_G;\r
+ b01 = (t00 & MASK_B);\r
+\r
+ t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));\r
+ a11 = (t00 & MASK_A) >> SHIFT_A;\r
+ r11 = (t00 & MASK_R) >> SHIFT_R;\r
+ g11 = (t00 & MASK_G) >> SHIFT_G;\r
+ b11 = (t00 & MASK_B);\r
\r
const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;\r
const tFixPointu txFractInv = FIX_POINT_ONE - txFract;\r
const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;\r
const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;\r
\r
- const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv );\r
- const tFixPointu w10 = imulFixu ( txFract , tyFractInv );\r
- const tFixPointu w01 = imulFixu ( txFractInv, tyFract );\r
- const tFixPointu w11 = imulFixu ( txFract , tyFract );\r
+ const tFixPointu w00 = imulFixu(txFractInv, tyFractInv);\r
+ const tFixPointu w10 = imulFixu(txFract, tyFractInv);\r
+ const tFixPointu w01 = imulFixu(txFractInv, tyFract);\r
+ const tFixPointu w11 = imulFixu(txFract, tyFract);\r
+\r
+ a = (a00 * w00) +\r
+ (a01 * w01) +\r
+ (a10 * w10) +\r
+ (a11 * w11);\r
\r
- r = (r00 * w00 ) +\r
- (r01 * w01 ) +\r
- (r10 * w10 ) +\r
- (r11 * w11 );\r
+ fix_alpha_color_max(a);\r
\r
- g = (g00 * w00 ) +\r
- (g01 * w01 ) +\r
- (g10 * w10 ) +\r
- (g11 * w11 );\r
+ r = (r00 * w00) +\r
+ (r01 * w01) +\r
+ (r10 * w10) +\r
+ (r11 * w11);\r
\r
- b = (b00 * w00 ) +\r
- (b01 * w01 ) +\r
- (b10 * w10 ) +\r
- (b11 * w11 );\r
+ g = (g00 * w00) +\r
+ (g01 * w01) +\r
+ (g10 * w10) +\r
+ (g11 * w11);\r
+\r
+ b = (b00 * w00) +\r
+ (b01 * w01) +\r
+ (b10 * w10) +\r
+ (b11 * w11);\r
\r
}\r
\r
+#else // SOFTWARE_DRIVER_2_BILINEAR\r
\r
-// get sample linear\r
-REALINLINE void getSample_linear ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
- )\r
-{\r
- u32 ofs;\r
+// get Sample linear == getSample_fixpoint\r
\r
- ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
- ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+ const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
+)\r
+{\r
+ register size_t ofs;\r
+ ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+ ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
\r
// texel\r
- tVideoSample t00;\r
- t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+ const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
\r
- a = (t00 & MASK_A) >> SHIFT_A;\r
- r = (t00 & MASK_R) >> SHIFT_R;\r
- g = (t00 & MASK_G) >> SHIFT_G;\r
- b = (t00 & MASK_B);\r
+ (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+ (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+ (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
}\r
\r
-// get Sample bilinear\r
-REALINLINE void getSample_texture ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
- const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
- )\r
+static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+ const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
+)\r
{\r
+ register size_t ofs;\r
+ ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+ ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
\r
- tFixPointu a00, r00,g00,b00;\r
- tFixPointu a01, r01,g01,b01;\r
- tFixPointu a10, r10,g10,b10;\r
- tFixPointu a11, r11,g11,b11;\r
-\r
- getSample_linear ( a00, r00, g00, b00, t, tx,ty );\r
- getSample_linear ( a10, r10, g10, b10, t, tx + FIX_POINT_ONE,ty );\r
- getSample_linear ( a01, r01, g01, b01, t, tx,ty + FIX_POINT_ONE );\r
- getSample_linear ( a11, r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE );\r
-\r
- const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;\r
- const tFixPointu txFractInv = FIX_POINT_ONE - txFract;\r
-\r
- const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;\r
- const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;\r
-\r
- const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv );\r
- const tFixPointu w10 = imulFixu ( txFract , tyFractInv );\r
- const tFixPointu w01 = imulFixu ( txFractInv, tyFract );\r
- const tFixPointu w11 = imulFixu ( txFract , tyFract );\r
-\r
- a = (a00 * w00 ) +\r
- (a01 * w01 ) +\r
- (a10 * w10 ) +\r
- (a11 * w11 );\r
-\r
- r = (r00 * w00 ) +\r
- (r01 * w01 ) +\r
- (r10 * w10 ) +\r
- (r11 * w11 );\r
-\r
- g = (g00 * w00 ) +\r
- (g01 * w01 ) +\r
- (g10 * w10 ) +\r
- (g11 * w11 );\r
-\r
- b = (b00 * w00 ) +\r
- (b01 * w01 ) +\r
- (b10 * w10 ) +\r
- (b11 * w11 );\r
+ // texel\r
+ const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
\r
+ (tFixPointu &)a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
+ fix_alpha_color_max(a);\r
+ (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+ (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+ (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
}\r
\r
\r
-#endif\r
+#endif // SOFTWARE_DRIVER_2_BILINEAR\r
+\r
\r
-// some 2D Defines\r
+// 2D Region closed [x0;x1]\r
struct AbsRectangle\r
{\r
s32 x0;\r
return dest.x0 < dest.x1 && dest.y0 < dest.y1;\r
}\r
\r
+#if 0\r
// some 1D defines\r
struct sIntervall\r
{\r
return core::s32_min( a.end, b.end ) - core::s32_max( a.start, b.start );\r
}\r
\r
+#endif\r
+\r
+// strings\r
+static inline void tiny_strncpy(char* to, const char* from, const size_t count)\r
+{\r
+ for (size_t r = 0; r < count && (*to = *from) != '\0'; ++from, ++to, ++r);\r
+ *to = '\0';\r
+}\r
+\r
+#define tiny_strcpy(a, b) tiny_strncpy(a,b,sizeof(a)-1)\r
+\r
+\r
+// tiny_isequal = !strncmp(a,b,sizeof(a)-1)\r
+static inline int tiny_isequal(const char *s1, const char *s2, size_t n)\r
+{\r
+ do {\r
+ if (*s1 != *s2++) return 0;\r
+ if (*s1++ == 0)\r
+ break;\r
+ } while (--n != 0);\r
+ return 1;\r
+}\r
+\r
+#define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0\r
+//! Size of a static C-style array.\r
+#define array_size(_arr) ((sizeof(_arr)/sizeof(*_arr)))\r
+\r
\r
} // end namespace irr\r
\r
--- /dev/null
+// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten\r
+// This file is part of the "Irrlicht Engine".\r
+// For conditions of distribution and use, see copyright notice in irrlicht.h\r
+\r
+#include "IrrCompileConfig.h"\r
+#include "IBurningShader.h"\r
+\r
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+namespace irr\r
+{\r
+\r
+namespace video\r
+{\r
+\r
+#define burning_shader_class burning_shader_color\r
+#define burning_shader_frag "burning_shader_color_fraq.h"\r
+#include "burning_shader_compile_fragment_default.h"\r
+\r
+\r
+/*!\r
+*/\r
+void burning_shader_class::OnSetMaterial(const SBurningShaderMaterial& material)\r
+{\r
+ switch (material.org.MaterialType)\r
+ {\r
+ case EMT_TRANSPARENT_ADD_COLOR:\r
+ case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:\r
+ case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:\r
+ //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);\r
+\r
+ case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
+ //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
+\r
+ case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:\r
+ //? glBlendFunc(GL_ONE,GL_ZERO) or glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
+\r
+ case EMT_TRANSPARENT_REFLECTION_2_LAYER:\r
+\r
+ case EMT_TRANSPARENT_VERTEX_ALPHA:\r
+ case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:\r
+ case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:\r
+ RenderPass_ShaderIsTransparent = 1;\r
+ AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);\r
+ break;\r
+ default:\r
+ RenderPass_ShaderIsTransparent = 0;\r
+ AlphaRef = 0;\r
+ break;\r
+ }\r
+\r
+ if (0 == RenderPass_ShaderIsTransparent)\r
+ {\r
+ if (material.org.ZBuffer == ECFN_LESSEQUAL)\r
+ {\r
+ if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;\r
+ else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_one_zero;\r
+ }\r
+ else /*if (material.org.ZBuffer == ECFN_DISABLED)*/\r
+ {\r
+ //check triangle on w = 1.f instead..\r
+#ifdef SOFTWARE_DRIVER_2_BILINEAR\r
+ if (material.org.TextureLayer[0].BilinearFilter) fragmentShader = &burning_shader_class::fragment_nodepth_perspective_blend_one_zero;\r
+ else\r
+#endif\r
+ fragmentShader = &burning_shader_class::fragment_nodepth_noperspective_blend_one_zero;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ if (material.org.ZBuffer == ECFN_LESSEQUAL)\r
+ {\r
+ if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha;\r
+ else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha;\r
+ }\r
+ else /*if (material.org.ZBuffer == ECFN_DISABLED)*/\r
+ {\r
+ //check triangle on w = 1.f instead..\r
+#ifdef SOFTWARE_DRIVER_2_BILINEAR\r
+ if (material.org.TextureLayer[0].BilinearFilter) fragmentShader = &burning_shader_class::fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha;\r
+ else\r
+#endif\r
+ fragmentShader = &burning_shader_class::fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha;\r
+ }\r
+ }\r
+\r
+}\r
+\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
--- /dev/null
+// pixelshader\r
+#ifdef IPOL_C0\r
+\r
+#ifdef IPOL_A0\r
+vec4_to_fix(a0, r0, g0, b0, line.c[0][0], inversew);\r
+if (a0 > AlphaRef)\r
+{\r
+ color_to_fix(r1, g1, b1, dst[i]);\r
+\r
+ fix_color_norm(a0);\r
+ r0 = r1 + imulFix(a0, r0 - r1);\r
+ g0 = g1 + imulFix(a0, g0 - g1);\r
+ b0 = b1 + imulFix(a0, b0 - b1);\r
+ dst[i] = fix_to_sample(r0, g0, b0);\r
+}\r
+#else\r
+vec4_to_fix(r0, g0, b0, line.c[0][0], inversew);\r
+dst[i] = fix_to_sample(r0, g0, b0);\r
+#endif\r
+\r
+#else\r
+dst[i] = PrimitiveColor;\r
+#endif\r
+\r
--- /dev/null
+\r
+\r
+class burning_shader_class : public IBurningShader\r
+{\r
+public:\r
+\r
+ //! constructor\r
+ burning_shader_class(CBurningVideoDriver* driver);\r
+\r
+ //! draws an indexed triangle list\r
+ virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+ virtual bool canWireFrame() { return true; }\r
+\r
+ virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
+\r
+private:\r
+\r
+ // fragment shader\r
+ typedef void (burning_shader_class::*tFragmentShader) ();\r
+ void fragment_depth_less_equal_depth_write_blend_one_zero();\r
+ void fragment_depth_less_equal_no_depth_write_blend_one_zero();\r
+ void fragment_nodepth_perspective_blend_one_zero();\r
+ void fragment_nodepth_noperspective_blend_one_zero(); // 2D Gradient\r
+\r
+ void fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha();\r
+ void fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha();\r
+ void fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha();\r
+ void fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha();\r
+\r
+\r
+ tFragmentShader fragmentShader;\r
+\r
+};\r
+\r
+\r
+//! constructor\r
+burning_shader_class::burning_shader_color(CBurningVideoDriver* driver)\r
+ : IBurningShader(driver)\r
+{\r
+#ifdef _DEBUG\r
+ setDebugName(burning_stringify(burning_shader_class) );\r
+#endif\r
+\r
+ fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;\r
+\r
+}\r
+\r
+\r
+IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver)\r
+{\r
+ return new burning_shader_class(driver);\r
+}\r
+\r
+\r
+\r
+// compile flag for this triangle\r
+#include "burning_shader_compile_start.h"\r
+#define SUBTEXEL\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#include "burning_shader_compile_triangle.h"\r
+\r
+// compile flag for this scanline fragment\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_nodepth_noperspective_blend_one_zero\r
+#define SUBTEXEL\r
+#define IPOL_C0\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_nodepth_perspective_blend_one_zero\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_blend_one_zero\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_depth_less_equal_depth_write_blend_one_zero\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#define WRITE_W\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+\r
+// compile flag for this scanline fragment\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha\r
+#define SUBTEXEL\r
+#define IPOL_C0\r
+#define IPOL_A0\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define IPOL_A0\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define IPOL_A0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define IPOL_A0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#define WRITE_W\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
--- /dev/null
+ }\r
+\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1];\r
+#endif\r
+ }\r
+\r
+}\r
--- /dev/null
+#include "burning_shader_compile_verify.h"\r
+\r
+/*!\r
+*/\r
+void burning_shader_class::burning_shader_fragment()\r
+{\r
+ tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+ fp24 *z;\r
+#endif\r
+\r
+ s32 xStart;\r
+ s32 xEnd;\r
+ s32 dx;\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+ f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+ fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+ sVec4 slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+ sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+ // apply top-left fill-convention, left\r
+ xStart = fill_convention_left(line.x[0]);\r
+ xEnd = fill_convention_right(line.x[1]);\r
+\r
+ dx = xEnd - xStart;\r
+ if (dx < 0)\r
+ return;\r
+\r
+ // slopes\r
+ const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+ slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+ slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+ slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+ slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+ slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+ line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+ line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+ line.c[0][0] += slopeC * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+ line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+ line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+ SOFTWARE_DRIVER_2_CLIPCHECK;\r
+ dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+ z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+ f32 inversew = INVERSE_W_RANGE;\r
+\r
+#ifdef IPOL_C0\r
+ tFixPoint r0, g0, b0;\r
+#endif\r
+\r
+#ifdef IPOL_A0\r
+ tFixPoint a0;\r
+ tFixPoint r1, g1, b1;\r
+#endif\r
+\r
+ for (s32 i = 0; i <= dx; ++i)\r
+ {\r
+ if ((0 == EdgeTestPass) & i) break;\r
+\r
+#ifdef CMP_Z\r
+ if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+ if (line.w[0] >= z[i])\r
+#endif\r
+ {\r
+#ifdef WRITE_Z\r
+ z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+ z[i] = line.w[0];\r
+#endif\r
+ /* Pixel Shader here */\r
+#ifdef INVERSE_W\r
+ inversew = (INVERSE_W_RANGE) / line.w[0]; /* fix_inverse32(line.w[0]);*/\r
+#endif\r
--- /dev/null
+// undef compile flag for this file\r
+#undef USE_ZBUFFER\r
+#undef IPOL_Z\r
+#undef CMP_Z\r
+#undef WRITE_Z\r
+\r
+#undef IPOL_W\r
+#undef CMP_W\r
+#undef WRITE_W\r
+\r
+#undef SUBTEXEL\r
+#undef INVERSE_W\r
+\r
+#undef IPOL_C0\r
+#undef IPOL_A0\r
+#undef IPOL_T0\r
+#undef IPOL_T1\r
+#undef IPOL_T2\r
+#undef IPOL_L0\r
+\r
+#undef burning_shader_fragment\r
+#undef ipol_test\r
+\r
+#undef INVERSE_W_RANGE\r
--- /dev/null
+#include "burning_shader_compile_verify.h"\r
+\r
+\r
+void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
+{\r
+ // sort on height, y\r
+ if (a->Pos.y > b->Pos.y) swapVertexPointer(&a, &b);\r
+ if (a->Pos.y > c->Pos.y) swapVertexPointer(&a, &c);\r
+ if (b->Pos.y > c->Pos.y) swapVertexPointer(&b, &c);\r
+\r
+ const f32 ca = c->Pos.y - a->Pos.y;\r
+ const f32 ba = b->Pos.y - a->Pos.y;\r
+ const f32 cb = c->Pos.y - b->Pos.y;\r
+\r
+ // calculate delta y of the edges\r
+ scan.invDeltaY[0] = reciprocal_edge(ca);\r
+ scan.invDeltaY[1] = reciprocal_edge(ba);\r
+ scan.invDeltaY[2] = reciprocal_edge(cb);\r
+\r
+ if (F32_LOWER_EQUAL_0(scan.invDeltaY[0]))\r
+ return;\r
+\r
+ // find if the major edge is left or right aligned\r
+ f32 temp[4];\r
+\r
+ temp[0] = a->Pos.x - c->Pos.x;\r
+ temp[1] = -ca;\r
+ temp[2] = b->Pos.x - a->Pos.x;\r
+ temp[3] = ba;\r
+\r
+ scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) > 0.f ? 0 : 1;\r
+ scan.right = 1 - scan.left;\r
+\r
+ // calculate slopes for the major edge\r
+ scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];\r
+ scan.x[0] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];\r
+ scan.z[0] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];\r
+ scan.w[0] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
+ scan.c[0][0] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
+ scan.t[0][0] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];\r
+ scan.t[1][0] = a->Tex[1];\r
+#endif\r
+\r
+ // top left fill convention y run\r
+ s32 yStart;\r
+ s32 yEnd;\r
+\r
+#ifdef SUBTEXEL\r
+ f32 subPixel;\r
+#endif\r
+\r
+\r
+ // rasterize upper sub-triangle\r
+ if (F32_GREATER_0(scan.invDeltaY[1]))\r
+ {\r
+ // calculate slopes for top edge\r
+ scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
+ scan.x[1] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];\r
+ scan.z[1] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];\r
+ scan.w[1] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
+ scan.c[0][1] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
+ scan.t[0][1] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];\r
+ scan.t[1][1] = a->Tex[1];\r
+#endif\r
+\r
+ // apply top-left fill convention, top part\r
+ yStart = fill_convention_left(a->Pos.y);\r
+ yEnd = fill_convention_right(b->Pos.y);\r
+\r
+#ifdef SUBTEXEL\r
+ subPixel = ((f32)yStart) - a->Pos.y;\r
+\r
+ // correct to pixel center\r
+ scan.x[0] += scan.slopeX[0] * subPixel;\r
+ scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0] * subPixel;\r
+ scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0] * subPixel;\r
+ scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+ // rasterize the edge scanlines\r
+ for (line.y = yStart; line.y <= yEnd; ++line.y)\r
+ {\r
+ line.x[scan.left] = scan.x[0];\r
+ line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+ line.z[scan.left] = scan.z[0];\r
+ line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ line.w[scan.left] = scan.w[0];\r
+ line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ line.c[0][scan.left] = scan.c[0][0];\r
+ line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ line.t[0][scan.left] = scan.t[0][0];\r
+ line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ line.t[1][scan.left] = scan.t[1][0];\r
+ line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+ // render a scanline\r
+ (this->*fragmentShader) ();\r
+ if (EdgeTestPass & edge_test_first_line) break;\r
+\r
+ scan.x[0] += scan.slopeX[0];\r
+ scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0];\r
+ scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0];\r
+ scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0];\r
+ scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0];\r
+ scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0];\r
+ scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+ }\r
+ }\r
+\r
+ // rasterize lower sub-triangle\r
+ if (F32_GREATER_0(scan.invDeltaY[2]))\r
+ {\r
+ // advance to middle point\r
+ if (F32_GREATER_0(scan.invDeltaY[1]))\r
+ {\r
+ temp[0] = b->Pos.y - a->Pos.y; // dy\r
+\r
+ scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];\r
+#ifdef IPOL_Z\r
+ scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_W\r
+ scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];\r
+#endif\r
+\r
+ }\r
+\r
+ // calculate slopes for bottom edge\r
+ scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];\r
+ scan.x[1] = b->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+ scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];\r
+ scan.z[1] = b->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];\r
+ scan.w[1] = b->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
+ scan.c[0][1] = b->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
+ scan.t[0][1] = b->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];\r
+ scan.t[1][1] = b->Tex[1];\r
+#endif\r
+\r
+ // apply top-left fill convention, top part\r
+ yStart = fill_convention_left(b->Pos.y);\r
+ yEnd = fill_convention_right(c->Pos.y);\r
+\r
+#ifdef SUBTEXEL\r
+\r
+ subPixel = ((f32)yStart) - b->Pos.y;\r
+\r
+ // correct to pixel center\r
+ scan.x[0] += scan.slopeX[0] * subPixel;\r
+ scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0] * subPixel;\r
+ scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0] * subPixel;\r
+ scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+ scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+ scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+ scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+ // rasterize the edge scanlines\r
+ for (line.y = yStart; line.y <= yEnd; ++line.y)\r
+ {\r
+ line.x[scan.left] = scan.x[0];\r
+ line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+ line.z[scan.left] = scan.z[0];\r
+ line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ line.w[scan.left] = scan.w[0];\r
+ line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ line.c[0][scan.left] = scan.c[0][0];\r
+ line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ line.t[0][scan.left] = scan.t[0][0];\r
+ line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ line.t[1][scan.left] = scan.t[1][0];\r
+ line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+ // render a scanline\r
+ (this->*fragmentShader) ();\r
+ if (EdgeTestPass & edge_test_first_line) break;\r
+\r
+ scan.x[0] += scan.slopeX[0];\r
+ scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+ scan.z[0] += scan.slopeZ[0];\r
+ scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+ scan.w[0] += scan.slopeW[0];\r
+ scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+ scan.c[0][0] += scan.slopeC[0][0];\r
+ scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+ scan.t[0][0] += scan.slopeT[0][0];\r
+ scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+ scan.t[1][0] += scan.slopeT[1][0];\r
+ scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+\r
+ }\r
+ }\r
+\r
+}\r
--- /dev/null
+// apply global override\r
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+#undef INVERSE_W\r
+#endif\r
+\r
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL\r
+#undef SUBTEXEL\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+#undef IPOL_C0\r
+#undef IPOL_A0\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1\r
+#undef IPOL_L0\r
+#endif\r
+\r
+\r
+// 1/x * FIX_POINT\r
+#if !defined(INVERSE_W_RANGE)\r
+ #define INVERSE_W_RANGE FIX_POINT_F32_MUL\r
+#endif\r
+\r
+#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )\r
+#else\r
+\r
+#ifdef IPOL_W\r
+ #undef IPOL_W\r
+ #define IPOL_Z\r
+#endif\r
+\r
+#ifdef CMP_W\r
+ #undef CMP_W\r
+ #define CMP_Z\r
+#endif\r
+\r
+#ifdef WRITE_W\r
+ #undef WRITE_W\r
+ #define WRITE_Z\r
+#endif\r
+\r
+#endif\r
Tests finished. 72 tests of 72 passed.\r
-Compiled as DEBUG\r
-Test suite pass at GMT Mon Feb 10 14:59:56 2020\r
+Compiled as RELEASE\r
+Test suite pass at GMT Sun Feb 23 02:59:02 2020\r
\r