Remove software renderer

This commit is contained in:
vlj
2014-09-28 00:48:20 +02:00
parent b5372c295d
commit a9ab147ae5
43 changed files with 0 additions and 24381 deletions

View File

@@ -31,7 +31,6 @@ if(UNIX AND USE_XRANDR)
endif()
set(IRRLICHT_SOURCES
source/Irrlicht/CTRStencilShadow.cpp
source/Irrlicht/CGUIListBox.cpp
source/Irrlicht/CZBuffer.cpp
source/Irrlicht/CGUIModalScreen.cpp
@@ -43,26 +42,18 @@ source/Irrlicht/CCubeSceneNode.cpp
source/Irrlicht/CGUIMeshViewer.cpp
source/Irrlicht/CBSPMeshFileLoader.cpp
source/Irrlicht/CParticleSphereEmitter.cpp
source/Irrlicht/CTRFlatWire.cpp
source/Irrlicht/CParticleAnimatedMeshSceneNodeEmitter.cpp
source/Irrlicht/CGUITabControl.cpp
source/Irrlicht/IBurningShader.cpp
source/Irrlicht/CSoftwareTexture.cpp
source/Irrlicht/CTRFlat.cpp
source/Irrlicht/CD3D9NormalMapRenderer.cpp
source/Irrlicht/CGUIToolBar.cpp
source/Irrlicht/CTerrainTriangleSelector.cpp
source/Irrlicht/CFileSystem.cpp
source/Irrlicht/CTerrainSceneNode.cpp
source/Irrlicht/CTRTextureFlat.cpp
source/Irrlicht/os.cpp
source/Irrlicht/CFPSCounter.cpp
source/Irrlicht/CGUIContextMenu.cpp
source/Irrlicht/CImageWriterJPG.cpp
source/Irrlicht/CAnimatedMeshMD2.cpp
source/Irrlicht/CTRTextureGouraudNoZ2.cpp
source/Irrlicht/CZipReader.cpp
source/Irrlicht/CTRTextureLightMap2_M4.cpp
source/Irrlicht/CImageLoaderPNG.cpp
source/Irrlicht/CImageLoaderBMP.cpp
source/Irrlicht/CIrrDeviceWinCE.cpp
@@ -70,14 +61,12 @@ source/Irrlicht/CVolumeLightSceneNode.cpp
source/Irrlicht/CDefaultSceneNodeAnimatorFactory.cpp
source/Irrlicht/CSkyDomeSceneNode.cpp
source/Irrlicht/CGUIFileOpenDialog.cpp
source/Irrlicht/CTRGouraudAlphaNoZ2.cpp
source/Irrlicht/CGUISpriteBank.cpp
source/Irrlicht/CParticleFadeOutAffector.cpp
source/Irrlicht/CGUIMenu.cpp
source/Irrlicht/CCgMaterialRenderer.cpp
source/Irrlicht/CMD2MeshFileLoader.cpp
source/Irrlicht/CImageWriterPSD.cpp
source/Irrlicht/CD3D9ParallaxMapRenderer.cpp
source/Irrlicht/CLWOMeshFileLoader.cpp
source/Irrlicht/CSphereSceneNode.cpp
source/Irrlicht/CLMTSMeshFileLoader.cpp
@@ -88,18 +77,13 @@ source/Irrlicht/CGUIMessageBox.cpp
source/Irrlicht/CParticleGravityAffector.cpp
source/Irrlicht/CGUISkin.cpp
source/Irrlicht/CBoneSceneNode.cpp
source/Irrlicht/CSoftwareTexture2.cpp
source/Irrlicht/CD3D8ParallaxMapRenderer.cpp
source/Irrlicht/CTRTextureLightMap2_M1.cpp
source/Irrlicht/CNPKReader.cpp
source/Irrlicht/CIrrMeshFileLoader.cpp
source/Irrlicht/COpenGLSLMaterialRenderer.cpp
source/Irrlicht/CParticleRotationAffector.cpp
source/Irrlicht/CAnimatedMeshHalfLife.cpp
source/Irrlicht/CD3D9HLSLMaterialRenderer.cpp
source/Irrlicht/CDepthBuffer.cpp
source/Irrlicht/CImageLoaderPSD.cpp
source/Irrlicht/CTRNormalMap.cpp
source/Irrlicht/CTriangleBBSelector.cpp
source/Irrlicht/CAnimatedMeshMD3.cpp
source/Irrlicht/CGUIComboBox.cpp
@@ -117,25 +101,17 @@ source/Irrlicht/CCSMLoader.cpp
source/Irrlicht/COBJMeshWriter.cpp
source/Irrlicht/CGUIScrollBar.cpp
source/Irrlicht/CAttributes.cpp
source/Irrlicht/CTRTextureGouraudAdd.cpp
source/Irrlicht/CGUIStaticText.cpp
source/Irrlicht/CSceneNodeAnimatorCollisionResponse.cpp
source/Irrlicht/CGUIFont.cpp
source/Irrlicht/CBurningShader_Raster_Reference.cpp
source/Irrlicht/CD3D8ShaderMaterialRenderer.cpp
source/Irrlicht/CTriangleSelector.cpp
source/Irrlicht/CTRTextureDetailMap2.cpp
source/Irrlicht/CParticlePointEmitter.cpp
source/Irrlicht/CD3D9Driver.cpp
source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp
source/Irrlicht/CTextSceneNode.cpp
source/Irrlicht/CD3D9CgMaterialRenderer.cpp
source/Irrlicht/COpenGLCgMaterialRenderer.cpp
source/Irrlicht/CIrrDeviceLinux.cpp
source/Irrlicht/CD3D9ShaderMaterialRenderer.cpp
source/Irrlicht/CIrrDeviceStub.cpp
source/Irrlicht/CQ3LevelMesh.cpp
source/Irrlicht/CTRTextureLightMap2_M2.cpp
source/Irrlicht/CDMFLoader.cpp
source/Irrlicht/CImageWriterPCX.cpp
source/Irrlicht/CGUIInOutFader.cpp
@@ -143,13 +119,11 @@ source/Irrlicht/CGUITreeView.cpp
source/Irrlicht/CAnimatedMeshSceneNode.cpp
source/Irrlicht/CGUICheckBox.cpp
source/Irrlicht/CGUIWindow.cpp
source/Irrlicht/CTRTextureWire2.cpp
source/Irrlicht/CPLYMeshFileLoader.cpp
source/Irrlicht/CSceneNodeAnimatorCameraMaya.cpp
source/Irrlicht/CSceneNodeAnimatorFlyCircle.cpp
source/Irrlicht/CColorConverter.cpp
source/Irrlicht/CMeshCache.cpp
source/Irrlicht/CTRTextureGouraudWire.cpp
source/Irrlicht/CIrrDeviceFB.cpp
source/Irrlicht/CMemoryFile.cpp
source/Irrlicht/CImageWriterPPM.cpp
@@ -158,8 +132,6 @@ source/Irrlicht/CMountPointReader.cpp
source/Irrlicht/CBillboardSceneNode.cpp
source/Irrlicht/CMS3DMeshFileLoader.cpp
source/Irrlicht/CGUIImageList.cpp
source/Irrlicht/CTRGouraud.cpp
source/Irrlicht/CTRTextureGouraudAlpha.cpp
source/Irrlicht/CSceneCollisionManager.cpp
source/Irrlicht/CIrrDeviceWin32.cpp
source/Irrlicht/CSceneLoaderIrr.cpp
@@ -176,7 +148,6 @@ source/Irrlicht/CGUIEditBox.cpp
source/Irrlicht/CLogger.cpp
source/Irrlicht/CMeshManipulator.cpp
source/Irrlicht/CLightSceneNode.cpp
source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp
source/Irrlicht/CImageLoaderDDS.cpp
source/Irrlicht/CSkyBoxSceneNode.cpp
source/Irrlicht/CWriteFile.cpp
@@ -187,10 +158,8 @@ source/Irrlicht/CFileList.cpp
source/Irrlicht/CXMeshFileLoader.cpp
source/Irrlicht/CImageLoaderPCX.cpp
source/Irrlicht/CIrrDeviceSDL.cpp
source/Irrlicht/CTRTextureGouraudNoZ.cpp
source/Irrlicht/COSOperator.cpp
source/Irrlicht/CImageLoaderJPG.cpp
source/Irrlicht/CTRGouraudWire.cpp
source/Irrlicht/CMD3MeshFileLoader.cpp
source/Irrlicht/CIrrMeshWriter.cpp
source/Irrlicht/COpenGLExtensionHandler.cpp
@@ -199,41 +168,27 @@ source/Irrlicht/CXMLWriter.cpp
source/Irrlicht/COCTLoader.cpp
source/Irrlicht/COBJMeshFileLoader.cpp
source/Irrlicht/CSceneNodeAnimatorCameraFPS.cpp
source/Irrlicht/CD3D8Texture.cpp
source/Irrlicht/CImageLoaderPPM.cpp
source/Irrlicht/CTRTextureLightMap2_Add.cpp
source/Irrlicht/CMY3DMeshFileLoader.cpp
source/Irrlicht/CTRGouraud2.cpp
source/Irrlicht/CGUIColorSelectDialog.cpp
source/Irrlicht/CSceneManager.cpp
source/Irrlicht/Irrlicht.cpp
source/Irrlicht/COpenGLShaderMaterialRenderer.cpp
source/Irrlicht/CImageLoaderTGA.cpp
source/Irrlicht/CTRTextureGouraud2.cpp
source/Irrlicht/COpenGLDriver.cpp
source/Irrlicht/CSceneNodeAnimatorFlyStraight.cpp
source/Irrlicht/irrXML.cpp
source/Irrlicht/CImageLoaderRGB.cpp
source/Irrlicht/CSoftwareDriver2.cpp
source/Irrlicht/CSoftwareDriver.cpp
source/Irrlicht/CD3D8Driver.cpp
source/Irrlicht/CD3D9Texture.cpp
source/Irrlicht/CTRTextureBlend.cpp
source/Irrlicht/CSkinnedMesh.cpp
source/Irrlicht/CTRGouraudAlpha2.cpp
source/Irrlicht/CXMLReader.cpp
source/Irrlicht/CDummyTransformationSceneNode.cpp
source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp
source/Irrlicht/C3DSMeshFileLoader.cpp
source/Irrlicht/CD3D8NormalMapRenderer.cpp
source/Irrlicht/CGUITable.cpp
source/Irrlicht/CB3DMeshFileLoader.cpp
source/Irrlicht/CGeometryCreator.cpp
source/Irrlicht/CNullDriver.cpp
source/Irrlicht/CCameraSceneNode.cpp
source/Irrlicht/CTRTextureGouraudAdd2.cpp
source/Irrlicht/CGUISpinBox.cpp
source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp
source/Irrlicht/CReadFile.cpp
source/Irrlicht/CColladaFileLoader.cpp
source/Irrlicht/CParticleRingEmitter.cpp
@@ -246,11 +201,9 @@ source/Irrlicht/CParticleScaleAffector.cpp
source/Irrlicht/CSceneNodeAnimatorDelete.cpp
source/Irrlicht/CPLYMeshWriter.cpp
source/Irrlicht/CImageWriterBMP.cpp
source/Irrlicht/CTRTextureGouraud.cpp
source/Irrlicht/CParticleMeshEmitter.cpp
source/Irrlicht/CSceneNodeAnimatorRotation.cpp
source/Irrlicht/COpenGLNormalMapRenderer.cpp
source/Irrlicht/CTRTextureFlatWire.cpp
source/Irrlicht/glext.h
source/Irrlicht/CB3DMeshFileLoader.h
source/Irrlicht/CIrrDeviceLinux.h
@@ -275,17 +228,14 @@ source/Irrlicht/CLWOMeshFileLoader.h
source/Irrlicht/CParticleRingEmitter.h
source/Irrlicht/COpenGLShaderMaterialRenderer.h
source/Irrlicht/CImageWriterTGA.h
source/Irrlicht/CD3D8MaterialRenderer.h
source/Irrlicht/CImageLoaderPNG.h
source/Irrlicht/COctreeTriangleSelector.h
source/Irrlicht/COpenGLTexture.h
source/Irrlicht/Octree.h
source/Irrlicht/os.h
source/Irrlicht/CD3D9MaterialRenderer.h
source/Irrlicht/CDefaultGUIElementFactory.h
source/Irrlicht/CAnimatedMeshHalfLife.h
source/Irrlicht/CSceneNodeAnimatorFlyCircle.h
source/Irrlicht/CD3D9ShaderMaterialRenderer.h
source/Irrlicht/CBSPMeshFileLoader.h
source/Irrlicht/CTriangleBBSelector.h
source/Irrlicht/S2DVertex.h
@@ -305,14 +255,10 @@ source/Irrlicht/dmfsupport.h
source/Irrlicht/CSTLMeshFileLoader.h
source/Irrlicht/CGUICheckBox.h
source/Irrlicht/CMeshManipulator.h
source/Irrlicht/CSoftware2MaterialRenderer.h
source/Irrlicht/CD3D9HLSLMaterialRenderer.h
source/Irrlicht/CSoftwareDriver.h
source/Irrlicht/IImagePresenter.h
source/Irrlicht/CGUIMeshViewer.h
source/Irrlicht/CMeshSceneNode.h
source/Irrlicht/CGUIImage.h
source/Irrlicht/CD3D8Driver.h
source/Irrlicht/CCameraSceneNode.h
source/Irrlicht/IZBuffer.h
source/Irrlicht/CAnimatedMeshSceneNode.h
@@ -336,7 +282,6 @@ source/Irrlicht/COpenGLDriver.h
source/Irrlicht/CGUIComboBox.h
source/Irrlicht/CPLYMeshFileLoader.h
source/Irrlicht/CVolumeLightSceneNode.h
source/Irrlicht/CSoftwareDriver2.h
source/Irrlicht/CSceneCollisionManager.h
source/Irrlicht/ISceneNodeAnimatorFinishing.h
source/Irrlicht/aesGladman/pwd2key.h
@@ -350,7 +295,6 @@ source/Irrlicht/aesGladman/aesopt.h
source/Irrlicht/COBJMeshWriter.h
source/Irrlicht/CGUITabControl.h
source/Irrlicht/CSphereSceneNode.h
source/Irrlicht/CSoftwareTexture2.h
source/Irrlicht/CIrrDeviceStub.h
source/Irrlicht/CDummyTransformationSceneNode.h
source/Irrlicht/CParticleBoxEmitter.h
@@ -390,7 +334,6 @@ source/Irrlicht/CWaterSurfaceSceneNode.h
source/Irrlicht/SoftwareDriver2_compile_config.h
source/Irrlicht/CSceneNodeAnimatorTexture.h
source/Irrlicht/CXMLReader.h
source/Irrlicht/CD3D9Driver.h
source/Irrlicht/CColladaFileLoader.h
source/Irrlicht/CEmptySceneNode.h
source/Irrlicht/CCgMaterialRenderer.h
@@ -398,20 +341,15 @@ source/Irrlicht/CParticleSystemSceneNode.h
source/Irrlicht/CImageWriterPNG.h
source/Irrlicht/CParticleScaleAffector.h
source/Irrlicht/CImageWriterPCX.h
source/Irrlicht/CD3D9Texture.h
source/Irrlicht/CD3D9NormalMapRenderer.h
source/Irrlicht/CLogger.h
source/Irrlicht/CMD3MeshFileLoader.h
source/Irrlicht/CImageLoaderJPG.h
source/Irrlicht/CBillboardSceneNode.h
source/Irrlicht/CD3D8ParallaxMapRenderer.h
source/Irrlicht/CD3D8ShaderMaterialRenderer.h
source/Irrlicht/CIrrDeviceSDL.h
source/Irrlicht/CSkyDomeSceneNode.h
source/Irrlicht/CPLYMeshWriter.h
source/Irrlicht/CDepthBuffer.h
source/Irrlicht/CGUIInOutFader.h
source/Irrlicht/CD3D9CgMaterialRenderer.h
source/Irrlicht/CGUIFont.h
source/Irrlicht/CGUIImageList.h
source/Irrlicht/CAnimatedMeshMD2.h
@@ -436,13 +374,10 @@ source/Irrlicht/CImageLoaderRGB.h
source/Irrlicht/CWriteFile.h
source/Irrlicht/CLMTSMeshFileLoader.h
source/Irrlicht/CSceneNodeAnimatorFollowSpline.h
source/Irrlicht/IBurningShader.h
source/Irrlicht/CQuake3ShaderSceneNode.h
source/Irrlicht/glxext.h
source/Irrlicht/CMetaTriangleSelector.h
source/Irrlicht/CSoftwareTexture.h
source/Irrlicht/CTarReader.h
source/Irrlicht/CD3D8NormalMapRenderer.h
source/Irrlicht/CXMLWriter.h
source/Irrlicht/CParticleCylinderEmitter.h
source/Irrlicht/ITriangleRenderer.h
@@ -454,19 +389,16 @@ source/Irrlicht/CTerrainTriangleSelector.h
source/Irrlicht/CSMFMeshFileLoader.h
source/Irrlicht/CAttributeImpl.h
source/Irrlicht/COgreMeshFileLoader.h
source/Irrlicht/CD3D8Texture.h
source/Irrlicht/CAnimatedMeshMD3.h
source/Irrlicht/CGeometryCreator.h
source/Irrlicht/CSkyBoxSceneNode.h
source/Irrlicht/CImageWriterBMP.h
source/Irrlicht/CD3D9ParallaxMapRenderer.h
source/Irrlicht/BuiltInFont.h
source/Irrlicht/CMemoryFile.h
source/Irrlicht/CFPSCounter.h
source/Irrlicht/CXMeshFileLoader.h
source/Irrlicht/CGUITreeView.h
source/Irrlicht/CGUIContextMenu.h
source/Irrlicht/CTRTextureGouraud.h
source/Irrlicht/CFileList.h
source/Irrlicht/CPakReader.h
source/Irrlicht/CLimitReadFile.h

View File

@@ -3,7 +3,6 @@
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_

View File

@@ -1,118 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_SOFTWARE2_MATERIAL_RENDERER_H_INCLUDED__
#define __C_SOFTWARE2_MATERIAL_RENDERER_H_INCLUDED__
#include "SoftwareDriver2_compile_config.h"
#include "IMaterialRenderer.h"
#include "CSoftwareDriver2.h"
namespace irr
{
namespace video
{
//! Base class for all internal Software2 material renderers
class CSoftware2MaterialRenderer : public IMaterialRenderer
{
public:
//! Constructor
CSoftware2MaterialRenderer(video::CBurningVideoDriver* driver)
: Driver(driver)
{
}
protected:
video::CBurningVideoDriver* Driver;
};
//! solid material renderer
class CSoftware2MaterialRenderer_SOLID : public CSoftware2MaterialRenderer
{
public:
CSoftware2MaterialRenderer_SOLID ( video::CBurningVideoDriver* driver )
:CSoftware2MaterialRenderer ( driver ) {}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return false;
}
};
//! Transparent material renderer
class CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR : public CSoftware2MaterialRenderer
{
public:
CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR ( video::CBurningVideoDriver* driver )
: CSoftware2MaterialRenderer ( driver ) {}
//! Returns if the material is transparent.
virtual bool isTransparent() const
{
return true;
}
};
//! unsupported material renderer
class CSoftware2MaterialRenderer_UNSUPPORTED : public CSoftware2MaterialRenderer
{
public:
CSoftware2MaterialRenderer_UNSUPPORTED ( video::CBurningVideoDriver* driver )
: CSoftware2MaterialRenderer ( driver ) {}
virtual s32 getRenderCapability() const { return 1; }
};
//! unsupported material renderer
class CBurningShader_REFERENCE : public CSoftware2MaterialRenderer
{
public:
CBurningShader_REFERENCE ( video::CBurningVideoDriver* driver )
: CSoftware2MaterialRenderer ( driver ) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
}
virtual void OnUnsetMaterial()
{
}
virtual bool isTransparent() const
{
return false;
}
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
return true;
};
virtual s32 getRenderCapability() const
{
return 1;
}
};
} // end namespace video
} // end namespace irr
#endif

View File

@@ -1,973 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CSoftwareDriver.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
#include "CSoftwareTexture.h"
#include "CBlit.h"
#include "os.h"
#include "S3DVertex.h"
namespace irr
{
namespace video
{
//! constructor
CSoftwareDriver::CSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter)
: CNullDriver(io, windowSize), BackBuffer(0), Presenter(presenter), WindowId(0),
SceneSourceRect(0), RenderTargetTexture(0), RenderTargetSurface(0),
CurrentTriangleRenderer(0), ZBuffer(0), Texture(0)
{
#ifdef _DEBUG
setDebugName("CSoftwareDriver");
#endif
// create backbuffer
BackBuffer = new CImage(ECF_A1R5G5B5, windowSize);
if (BackBuffer)
{
BackBuffer->fill(SColor(0));
// create z buffer
ZBuffer = video::createZBuffer(BackBuffer->getDimension());
}
DriverAttributes->setAttribute("MaxTextures", 1);
DriverAttributes->setAttribute("MaxIndices", 1<<16);
DriverAttributes->setAttribute("MaxTextureSize", 1024);
DriverAttributes->setAttribute("Version", 1);
// create triangle renderers
TriangleRenderers[ETR_FLAT] = createTriangleRendererFlat(ZBuffer);
TriangleRenderers[ETR_FLAT_WIRE] = createTriangleRendererFlatWire(ZBuffer);
TriangleRenderers[ETR_GOURAUD] = createTriangleRendererGouraud(ZBuffer);
TriangleRenderers[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire(ZBuffer);
TriangleRenderers[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat(ZBuffer);
TriangleRenderers[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire(ZBuffer);
TriangleRenderers[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud(ZBuffer);
TriangleRenderers[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire(ZBuffer);
TriangleRenderers[ETR_TEXTURE_GOURAUD_NOZ] = createTriangleRendererTextureGouraudNoZ();
TriangleRenderers[ETR_TEXTURE_GOURAUD_ADD] = createTriangleRendererTextureGouraudAdd(ZBuffer);
// select render target
setRenderTarget(BackBuffer);
// select the right renderer
selectRightTriangleRenderer();
}
//! destructor
CSoftwareDriver::~CSoftwareDriver()
{
// delete Backbuffer
if (BackBuffer)
BackBuffer->drop();
// delete triangle renderers
for (s32 i=0; i<ETR_COUNT; ++i)
if (TriangleRenderers[i])
TriangleRenderers[i]->drop();
// delete zbuffer
if (ZBuffer)
ZBuffer->drop();
// delete current texture
if (Texture)
Texture->drop();
if (RenderTargetTexture)
RenderTargetTexture->drop();
if (RenderTargetSurface)
RenderTargetSurface->drop();
}
//! switches to a triangle renderer
void CSoftwareDriver::switchToTriangleRenderer(ETriangleRenderer renderer)
{
video::IImage* s = 0;
if (Texture)
s = ((CSoftwareTexture*)Texture)->getTexture();
CurrentTriangleRenderer = TriangleRenderers[renderer];
CurrentTriangleRenderer->setBackfaceCulling(Material.BackfaceCulling == true);
CurrentTriangleRenderer->setTexture(s);
CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort);
}
//! void selects the right triangle renderer based on the render states.
void CSoftwareDriver::selectRightTriangleRenderer()
{
ETriangleRenderer renderer = ETR_FLAT;
if (Texture)
{
if (!Material.GouraudShading)
renderer = (!Material.Wireframe) ? ETR_TEXTURE_FLAT : ETR_TEXTURE_FLAT_WIRE;
else
{
if (Material.Wireframe)
renderer = ETR_TEXTURE_GOURAUD_WIRE;
else
{
if (Material.MaterialType == EMT_TRANSPARENT_ADD_COLOR ||
Material.MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL ||
Material.MaterialType == EMT_TRANSPARENT_VERTEX_ALPHA)
{
// simply draw all transparent stuff with the same renderer. at
// least it is transparent then.
renderer = ETR_TEXTURE_GOURAUD_ADD;
}
else
if ((Material.ZBuffer==ECFN_NEVER) && !Material.ZWriteEnable)
renderer = ETR_TEXTURE_GOURAUD_NOZ;
else
{
renderer = ETR_TEXTURE_GOURAUD;
}
}
}
}
else
{
if (!Material.GouraudShading)
renderer = (!Material.Wireframe) ? ETR_FLAT : ETR_FLAT_WIRE;
else
renderer = (!Material.Wireframe) ? ETR_GOURAUD : ETR_GOURAUD_WIRE;
}
switchToTriangleRenderer(renderer);
}
//! queries the features of the driver, returns true if feature is available
bool CSoftwareDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
{
switch (feature)
{
case EVDF_RENDER_TO_TARGET:
case EVDF_TEXTURE_NSQUARE:
return FeatureEnabled[feature];
default:
return false;
};
}
//! sets transformation
void CSoftwareDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
{
TransformationMatrix[state] = mat;
}
//! sets the current Texture
bool CSoftwareDriver::setActiveTexture(u32 stage, video::ITexture* texture)
{
if (texture && texture->getDriverType() != EDT_SOFTWARE)
{
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
return false;
}
if (Texture)
Texture->drop();
Texture = texture;
if (Texture)
Texture->grab();
selectRightTriangleRenderer();
return true;
}
//! sets a material
void CSoftwareDriver::setMaterial(const SMaterial& material)
{
Material = material;
OverrideMaterial.apply(Material);
for (u32 i = 0; i < 1; ++i)
{
setActiveTexture(i, Material.getTexture(i));
setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ),
material.getTextureMatrix(i));
}
}
//! clears the zbuffer
bool CSoftwareDriver::beginScene(bool backBuffer, bool zBuffer, SColor color,
const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
{
CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect);
WindowId=videoData.D3D9.HWnd;
SceneSourceRect = sourceRect;
if (backBuffer && BackBuffer)
BackBuffer->fill(color);
if (ZBuffer && zBuffer)
ZBuffer->clear();
return true;
}
//! presents the rendered scene on the screen, returns false if failed
bool CSoftwareDriver::endScene()
{
CNullDriver::endScene();
return Presenter->present(BackBuffer, WindowId, SceneSourceRect);
}
//! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
{
return new CSoftwareTexture(surface, name, false, mipmapData);
}
//! sets a render target
bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color)
{
if (texture && texture->getDriverType() != EDT_SOFTWARE)
{
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
return false;
}
if (RenderTargetTexture)
RenderTargetTexture->drop();
RenderTargetTexture = texture;
if (RenderTargetTexture)
{
RenderTargetTexture->grab();
setRenderTarget(((CSoftwareTexture*)RenderTargetTexture)->getTexture());
}
else
{
setRenderTarget(BackBuffer);
}
if (RenderTargetSurface && (clearBackBuffer || clearZBuffer))
{
if (clearZBuffer)
ZBuffer->clear();
if (clearBackBuffer)
RenderTargetSurface->fill(color);
}
return true;
}
//! sets a render target
void CSoftwareDriver::setRenderTarget(video::CImage* image)
{
if (RenderTargetSurface)
RenderTargetSurface->drop();
RenderTargetSurface = image;
RenderTargetSize.Width = 0;
RenderTargetSize.Height = 0;
Render2DTranslation.X = 0;
Render2DTranslation.Y = 0;
if (RenderTargetSurface)
{
RenderTargetSurface->grab();
RenderTargetSize = RenderTargetSurface->getDimension();
}
setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height));
if (ZBuffer)
ZBuffer->setSize(RenderTargetSize);
}
//! sets a viewport
void CSoftwareDriver::setViewPort(const core::rect<s32>& area)
{
ViewPort = area;
//TODO: the clipping is not correct, because the projection is affected.
// to correct this, ViewPortSize and Render2DTranslation will have to be corrected.
core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height);
ViewPort.clipAgainst(rendert);
ViewPortSize = core::dimension2du(ViewPort.getSize());
Render2DTranslation.X = (ViewPortSize.Width / 2) + ViewPort.UpperLeftCorner.X;
Render2DTranslation.Y = ViewPort.UpperLeftCorner.Y + ViewPortSize.Height - (ViewPortSize.Height / 2);// + ViewPort.UpperLeftCorner.Y;
if (CurrentTriangleRenderer)
CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort);
}
void CSoftwareDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
{
switch (iType)
{
case (EIT_16BIT):
{
drawVertexPrimitiveList16(vertices, vertexCount, (const u16*)indexList, primitiveCount, vType, pType);
break;
}
case (EIT_32BIT):
{
os::Printer::log("Software driver can not render 32bit buffers", ELL_ERROR);
break;
}
}
}
//! draws a vertex primitive list
void CSoftwareDriver::drawVertexPrimitiveList16(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType)
{
const u16* indexPointer=0;
core::array<u16> newBuffer;
switch (pType)
{
case scene::EPT_LINE_STRIP:
{
switch (vType)
{
case EVT_STANDARD:
{
for (u32 i=0; i < primitiveCount-1; ++i)
draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos,
((S3DVertex*)vertices)[indexList[i+1]].Pos,
((S3DVertex*)vertices)[indexList[i]].Color);
}
break;
case EVT_2TCOORDS:
{
for (u32 i=0; i < primitiveCount-1; ++i)
draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos,
((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos,
((S3DVertex2TCoords*)vertices)[indexList[i]].Color);
}
break;
case EVT_TANGENTS:
{
for (u32 i=0; i < primitiveCount-1; ++i)
draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos,
((S3DVertexTangents*)vertices)[indexList[i+1]].Pos,
((S3DVertexTangents*)vertices)[indexList[i]].Color);
}
break;
}
}
return;
case scene::EPT_LINE_LOOP:
drawVertexPrimitiveList16(vertices, vertexCount, indexList, primitiveCount-1, vType, scene::EPT_LINE_STRIP);
switch (vType)
{
case EVT_STANDARD:
draw3DLine(((S3DVertex*)vertices)[indexList[primitiveCount-1]].Pos,
((S3DVertex*)vertices)[indexList[0]].Pos,
((S3DVertex*)vertices)[indexList[primitiveCount-1]].Color);
break;
case EVT_2TCOORDS:
draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Pos,
((S3DVertex2TCoords*)vertices)[indexList[0]].Pos,
((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Color);
break;
case EVT_TANGENTS:
draw3DLine(((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Pos,
((S3DVertexTangents*)vertices)[indexList[0]].Pos,
((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Color);
break;
}
return;
case scene::EPT_LINES:
{
switch (vType)
{
case EVT_STANDARD:
{
for (u32 i=0; i < 2*primitiveCount; i+=2)
draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos,
((S3DVertex*)vertices)[indexList[i+1]].Pos,
((S3DVertex*)vertices)[indexList[i]].Color);
}
break;
case EVT_2TCOORDS:
{
for (u32 i=0; i < 2*primitiveCount; i+=2)
draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos,
((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos,
((S3DVertex2TCoords*)vertices)[indexList[i]].Color);
}
break;
case EVT_TANGENTS:
{
for (u32 i=0; i < 2*primitiveCount; i+=2)
draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos,
((S3DVertexTangents*)vertices)[indexList[i+1]].Pos,
((S3DVertexTangents*)vertices)[indexList[i]].Color);
}
break;
}
}
return;
case scene::EPT_TRIANGLE_FAN:
{
// TODO: don't convert fan to list
newBuffer.reallocate(primitiveCount*3);
for( u32 t=0; t<primitiveCount; ++t )
{
newBuffer.push_back(indexList[0]);
newBuffer.push_back(indexList[t+1]);
newBuffer.push_back(indexList[t+2]);
}
indexPointer = newBuffer.pointer();
}
break;
case scene::EPT_TRIANGLES:
indexPointer=indexList;
break;
default:
return;
}
switch (vType)
{
case EVT_STANDARD:
drawClippedIndexedTriangleListT((S3DVertex*)vertices, vertexCount, indexPointer, primitiveCount);
break;
case EVT_2TCOORDS:
drawClippedIndexedTriangleListT((S3DVertex2TCoords*)vertices, vertexCount, indexPointer, primitiveCount);
break;
case EVT_TANGENTS:
drawClippedIndexedTriangleListT((S3DVertexTangents*)vertices, vertexCount, indexPointer, primitiveCount);
break;
}
}
template<class VERTEXTYPE>
void CSoftwareDriver::drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices,
s32 vertexCount, const u16* indexList, s32 triangleCount)
{
if (!RenderTargetSurface || !ZBuffer || !triangleCount)
return;
if (!checkPrimitiveCount(triangleCount))
return;
// arrays for storing clipped vertices
core::array<VERTEXTYPE> clippedVertices;
core::array<u16> clippedIndices;
// calculate inverse world transformation
core::matrix4 worldinv(TransformationMatrix[ETS_WORLD]);
worldinv.makeInverse();
// calculate view frustum planes
scene::SViewFrustum frustum(TransformationMatrix[ETS_PROJECTION] * TransformationMatrix[ETS_VIEW]);
// copy and transform clipping planes ignoring far plane
core::plane3df planes[5]; // ordered by near, left, right, bottom, top
for (int p=0; p<5; ++p)
worldinv.transformPlane(frustum.planes[p+1], planes[p]);
core::EIntersectionRelation3D inout[3]; // is point in front or back of plane?
// temporary buffer for vertices to be clipped by all planes
core::array<VERTEXTYPE> tClpBuf;
int t;
int i;
for (i=0; i<triangleCount; ++i) // for all input triangles
{
// add next triangle to tempClipBuffer
for (t=0; t<3; ++t)
tClpBuf.push_back(vertices[indexList[(i*3)+t]]);
for (int p=0; p<5; ++p) // for all clip planes
for (int v=0; v<(int)tClpBuf.size(); v+=3) // for all vertices in temp clip buffer
{
int inside = 0;
int outside = 0;
// test intersection relation of the current vertices
for (t=0; t<3; ++t)
{
inout[t] = planes[p].classifyPointRelation(tClpBuf[v+t].Pos);
if (inout[t] != core::ISREL3D_FRONT)
++inside;
else
if (inout[t] == core::ISREL3D_FRONT)
++outside;
}
if (!outside)
{
// add all vertices to new buffer, this triangle needs no clipping.
// so simply don't change this part of the temporary triangle buffer
continue;
}
if (!inside)
{
// all vertices are outside, don't add this triangle, so erase this
// triangle from the tClpBuf
tClpBuf.erase(v,3);
v -= 3;
continue;
}
// this vertex has to be clipped by this clipping plane.
// The following lines represent my try to implement some real clipping.
// There is a bug somewhere, and after some time I've given up.
// So now it is commented out, resulting that triangles which would need clipping
// are simply taken out (in the next two lines).
#ifndef __SOFTWARE_CLIPPING_PROBLEM__
tClpBuf.erase(v,3);
v -= 3;
#endif
/*
// my idea is the following:
// current vertex to next vertex relation:
// out - out : add nothing
// out - in : add middle point
// in - out : add first and middle point
// in - in : add both
// now based on the number of intersections, create new vertices
// into tClpBuf (at the front for not letting them be clipped again)
int added = 0;
int prev = v+2;
for (int index=v; index<v+3; ++index)
{
if (inout[prev] == core::ISREL3D_BACK)
{
if (inout[index] != core::ISREL3D_BACK)
{
VERTEXTYPE& vt1 = tClpBuf[prev];
VERTEXTYPE& vt2 = tClpBuf[index];
f32 fact = planes[p].getKnownIntersectionWithLine(vt1.Pos, vt2.Pos);
VERTEXTYPE nvt;
nvt.Pos = vt1.Pos.getInterpolated(vt2.Pos, fact);
nvt.Color = vt1.Color.getInterpolated(vt2.Color, fact);
nvt.TCoords = vt1.TCoords.getInterpolated(vt2.TCoords, fact);
tClpBuf.push_front(nvt); ++index; ++prev; ++v;
++added;
}
}
else
{
if (inout[index] != core::ISREL3D_BACK)
{
VERTEXTYPE vt1 = tClpBuf[index];
VERTEXTYPE vt2 = tClpBuf[prev];
tClpBuf.push_front(vt1); ++index; ++prev; ++v;
tClpBuf.push_front(vt2); ++index; ++prev; ++v;
added+= 2;
}
else
{
// same as above, but other way round.
VERTEXTYPE vt1 = tClpBuf[index];
VERTEXTYPE vt2 = tClpBuf[prev];
f32 fact = planes[p].getKnownIntersectionWithLine(vt1.Pos, vt2.Pos);
VERTEXTYPE nvt;
nvt.Pos = vt1.Pos.getInterpolated(vt2.Pos, fact);
nvt.Color = vt1.Color.getInterpolated(vt2.Color, fact);
nvt.TCoords = vt1.TCoords.getInterpolated(vt2.TCoords, fact);
tClpBuf.push_front(vt2); ++index; ++prev; ++v;
tClpBuf.push_front(nvt); ++index; ++prev; ++v;
added += 2;
}
}
prev = index;
}
// erase original vertices
tClpBuf.erase(v,3);
v -= 3;
*/
} // end for all clip planes
// now add all remaining triangles in tempClipBuffer to clippedIndices
// and clippedVertices array.
if (clippedIndices.size() + tClpBuf.size() < 65535)
for (t=0; t<(int)tClpBuf.size(); ++t)
{
clippedIndices.push_back(clippedVertices.size());
clippedVertices.push_back(tClpBuf[t]);
}
tClpBuf.clear();
} // end for all input triangles
// draw newly created triangles.
// -----------------------------------------------------------
// here all triangles are being drawn. I put this in a separate
// method, but the visual studio 6 compiler has great problems
// with templates and didn't accept two template methods in this
// class.
// draw triangles
CNullDriver::drawVertexPrimitiveList(clippedVertices.pointer(), clippedVertices.size(),
clippedIndices.pointer(), clippedIndices.size()/3, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);
if (TransformedPoints.size() < clippedVertices.size())
TransformedPoints.set_used(clippedVertices.size());
if (TransformedPoints.empty())
return;
const VERTEXTYPE* currentVertex = clippedVertices.pointer();
S2DVertex* tp = &TransformedPoints[0];
core::dimension2d<u32> textureSize(0,0);
f32 zDiv;
if (Texture)
textureSize = ((CSoftwareTexture*)Texture)->getTexture()->getDimension();
f32 transformedPos[4]; // transform all points in the list
core::matrix4 matrix(TransformationMatrix[ETS_PROJECTION]);
matrix *= TransformationMatrix[ETS_VIEW];
matrix *= TransformationMatrix[ETS_WORLD];
s32 ViewTransformWidth = (ViewPortSize.Width>>1);
s32 ViewTransformHeight = (ViewPortSize.Height>>1);
for (i=0; i<(int)clippedVertices.size(); ++i)
{
transformedPos[0] = currentVertex->Pos.X;
transformedPos[1] = currentVertex->Pos.Y;
transformedPos[2] = currentVertex->Pos.Z;
transformedPos[3] = 1.0f;
matrix.multiplyWith1x4Matrix(transformedPos);
zDiv = transformedPos[3] == 0.0f ? 1.0f : (1.0f / transformedPos[3]);
tp->Pos.X = (s32)(ViewTransformWidth * (transformedPos[0] * zDiv) + (Render2DTranslation.X));
tp->Pos.Y = (Render2DTranslation.Y - (s32)(ViewTransformHeight * (transformedPos[1] * zDiv)));
tp->Color = currentVertex->Color.toA1R5G5B5();
tp->ZValue = (TZBufferType)(32767.0f * zDiv);
tp->TCoords.X = (s32)(currentVertex->TCoords.X * textureSize.Width);
tp->TCoords.X <<= 8;
tp->TCoords.Y = (s32)(currentVertex->TCoords.Y * textureSize.Height);
tp->TCoords.Y <<= 8;
++currentVertex;
++tp;
}
// draw all transformed points from the index list
CurrentTriangleRenderer->drawIndexedTriangleList(&TransformedPoints[0],
clippedVertices.size(), clippedIndices.pointer(), clippedIndices.size()/3);
}
//! Draws a 3d line.
void CSoftwareDriver::draw3DLine(const core::vector3df& start,
const core::vector3df& end, SColor color)
{
core::vector3df vect = start.crossProduct(end);
vect.normalize();
vect *= Material.Thickness*0.3f;
S3DVertex vtx[4];
vtx[0].Color = color;
vtx[1].Color = color;
vtx[2].Color = color;
vtx[3].Color = color;
vtx[0].Pos = start;
vtx[1].Pos = end;
vtx[2].Pos = start + vect;
vtx[3].Pos = end + vect;
u16 idx[12] = {0,1,2, 0,2,1, 0,1,3, 0,3,1};
drawIndexedTriangleList(vtx, 4, idx, 4);
}
//! clips a triangle against the viewing frustum
void CSoftwareDriver::clipTriangle(f32* transformedPos)
{
}
//! Only used by the internal engine. Used to notify the driver that
//! the window was resized.
void CSoftwareDriver::OnResize(const core::dimension2d<u32>& size)
{
// make sure width and height are multiples of 2
core::dimension2d<u32> realSize(size);
if (realSize.Width % 2)
realSize.Width += 1;
if (realSize.Height % 2)
realSize.Height += 1;
if (ScreenSize != realSize)
{
if (ViewPort.getWidth() == (s32)ScreenSize.Width &&
ViewPort.getHeight() == (s32)ScreenSize.Height)
{
ViewPort = core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(realSize));
}
ScreenSize = realSize;
bool resetRT = (RenderTargetSurface == BackBuffer);
if (BackBuffer)
BackBuffer->drop();
BackBuffer = new CImage(ECF_A1R5G5B5, realSize);
if (resetRT)
setRenderTarget(BackBuffer);
}
}
//! returns the current render target size
const core::dimension2d<u32>& CSoftwareDriver::getCurrentRenderTargetSize() const
{
return RenderTargetSize;
}
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
void CSoftwareDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect,
const core::rect<s32>* clipRect, SColor color,
bool useAlphaChannelOfTexture)
{
if (texture)
{
if (texture->getDriverType() != EDT_SOFTWARE)
{
os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);
return;
}
if (useAlphaChannelOfTexture)
((CSoftwareTexture*)texture)->getImage()->copyToWithAlpha(
RenderTargetSurface, destPos, sourceRect, color, clipRect);
else
((CSoftwareTexture*)texture)->getImage()->copyTo(
RenderTargetSurface, destPos, sourceRect, clipRect);
}
}
//! Draws a 2d line.
void CSoftwareDriver::draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color)
{
drawLine(RenderTargetSurface, start, end, color );
}
//! Draws a pixel
void CSoftwareDriver::drawPixel(u32 x, u32 y, const SColor & color)
{
BackBuffer->setPixel(x, y, color, true);
}
//! draw a 2d rectangle
void CSoftwareDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos,
const core::rect<s32>* clip)
{
if (clip)
{
core::rect<s32> p(pos);
p.clipAgainst(*clip);
if(!p.isValid())
return;
drawRectangle(RenderTargetSurface, p, color);
}
else
{
if(!pos.isValid())
return;
drawRectangle(RenderTargetSurface, pos, color);
}
}
//!Draws an 2d rectangle with a gradient.
void CSoftwareDriver::draw2DRectangle(const core::rect<s32>& pos,
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
const core::rect<s32>* clip)
{
// TODO: implement
draw2DRectangle(colorLeftUp, pos, clip);
}
//! \return Returns the name of the video driver. Example: In case of the Direct3D8
//! driver, it would return "Direct3D8.1".
const wchar_t* CSoftwareDriver::getName() const
{
return L"Irrlicht Software Driver 1.0";
}
//! Returns type of video driver
E_DRIVER_TYPE CSoftwareDriver::getDriverType() const
{
return EDT_SOFTWARE;
}
//! returns color format
ECOLOR_FORMAT CSoftwareDriver::getColorFormat() const
{
if (BackBuffer)
return BackBuffer->getColorFormat();
else
return CNullDriver::getColorFormat();
}
//! Returns the transformation set by setTransform
const core::matrix4& CSoftwareDriver::getTransform(E_TRANSFORMATION_STATE state) const
{
return TransformationMatrix[state];
}
//! Creates a render target texture.
ITexture* CSoftwareDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name,
const ECOLOR_FORMAT format)
{
IImage* img = createImage(video::ECF_A1R5G5B5, size);
ITexture* tex = new CSoftwareTexture(img, name, true);
img->drop();
addTexture(tex);
tex->drop();
return tex;
}
//! Clears the ZBuffer.
void CSoftwareDriver::clearZBuffer()
{
if (ZBuffer)
ZBuffer->clear();
}
//! Returns an image created from the last rendered frame.
IImage* CSoftwareDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
{
if (target != video::ERT_FRAME_BUFFER)
return 0;
if (BackBuffer)
{
IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension());
BackBuffer->copyTo(tmp);
return tmp;
}
else
return 0;
}
//! Returns the maximum amount of primitives (mostly vertices) which
//! the device is able to render with one drawIndexedTriangleList
//! call.
u32 CSoftwareDriver::getMaximalPrimitiveCount() const
{
return 0x00800000;
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a video driver
IVideoDriver* createSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CSoftwareDriver(windowSize, fullscreen, io, presenter);
#else
return 0;
#endif
}
} // end namespace video
} // end namespace irr

View File

@@ -1,180 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_VIDEO_SOFTWARE_H_INCLUDED__
#define __C_VIDEO_SOFTWARE_H_INCLUDED__
#include "ITriangleRenderer.h"
#include "CNullDriver.h"
#include "SViewFrustum.h"
#include "CImage.h"
namespace irr
{
namespace video
{
class CSoftwareDriver : public CNullDriver
{
public:
//! constructor
CSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter);
//! destructor
virtual ~CSoftwareDriver();
//! queries the features of the driver, returns true if feature is available
virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const;
//! sets transformation
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat);
//! sets a material
virtual void setMaterial(const SMaterial& material);
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color);
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area);
//! clears the zbuffer
virtual bool beginScene(bool backBuffer=true, bool zBuffer=true,
SColor color=SColor(255,0,0,0),
const SExposedVideoData& videoData=SExposedVideoData(),
core::rect<s32>* sourceRect=0);
//! presents the rendered scene on the screen, returns false if failed
virtual bool endScene();
//! Only used by the internal engine. Used to notify the driver that
//! the window was resized.
virtual void OnResize(const core::dimension2d<u32>& size);
//! returns size of the current render target
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const;
//! draws a vertex primitive list
void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType);
//! Draws a 3d line.
virtual void draw3DLine(const core::vector3df& start,
const core::vector3df& end, SColor color = SColor(255,255,255,255));
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false);
//! draw an 2d rectangle
virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
const core::rect<s32>* clip = 0);
//!Draws an 2d rectangle with a gradient.
virtual void draw2DRectangle(const core::rect<s32>& pos,
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
const core::rect<s32>* clip = 0);
//! Draws a 2d line.
virtual void draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color=SColor(255,255,255,255));
//! Draws a single pixel
virtual void drawPixel(u32 x, u32 y, const SColor & color);
//! \return Returns the name of the video driver. Example: In case of the Direct3D8
//! driver, it would return "Direct3D8.1".
virtual const wchar_t* getName() const;
//! Returns type of video driver
virtual E_DRIVER_TYPE getDriverType() const;
//! get color format of the current color buffer
virtual ECOLOR_FORMAT getColorFormat() const;
//! Returns the transformation set by setTransform
virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const;
//! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
//! Creates a render target texture.
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN);
//! Clears the ZBuffer.
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER);
//! Returns the maximum amount of primitives (mostly vertices) which
//! the device is able to render with one drawIndexedTriangleList
//! call.
virtual u32 getMaximalPrimitiveCount() const;
protected:
//! sets a render target
void setRenderTarget(video::CImage* image);
//! sets the current Texture
bool setActiveTexture(u32 stage, video::ITexture* texture);
//! switches to a triangle renderer
void switchToTriangleRenderer(ETriangleRenderer renderer);
//! void selects the right triangle renderer based on the render states.
void selectRightTriangleRenderer();
//! clips a triangle agains the viewing frustum
void clipTriangle(f32* transformedPos);
//! draws a vertex primitive list
void drawVertexPrimitiveList16(const void* vertices, u32 vertexCount,
const u16* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType);
template<class VERTEXTYPE>
void drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices,
s32 vertexCount, const u16* indexList, s32 triangleCount);
video::CImage* BackBuffer;
video::IImagePresenter* Presenter;
void* WindowId;
core::rect<s32>* SceneSourceRect;
core::array<S2DVertex> TransformedPoints;
video::ITexture* RenderTargetTexture;
video::CImage* RenderTargetSurface;
core::position2d<s32> Render2DTranslation;
core::dimension2d<u32> RenderTargetSize;
core::dimension2d<u32> ViewPortSize;
core::matrix4 TransformationMatrix[ETS_COUNT];
ITriangleRenderer* CurrentTriangleRenderer;
ITriangleRenderer* TriangleRenderers[ETR_COUNT];
ETriangleRenderer CurrentRenderer;
IZBuffer* ZBuffer;
video::ITexture* Texture;
SMaterial Material;
};
} // end namespace video
} // end namespace irr
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,290 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_VIDEO_2_SOFTWARE_H_INCLUDED__
#define __C_VIDEO_2_SOFTWARE_H_INCLUDED__
#include "SoftwareDriver2_compile_config.h"
#include "IBurningShader.h"
#include "CNullDriver.h"
#include "CImage.h"
#include "os.h"
#include "irrString.h"
#include "SIrrCreationParameters.h"
namespace irr
{
namespace video
{
class CBurningVideoDriver : public CNullDriver
{
public:
//! constructor
CBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter);
//! destructor
virtual ~CBurningVideoDriver();
//! queries the features of the driver, returns true if feature is available
virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const;
//! sets transformation
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat);
//! sets a material
virtual void setMaterial(const SMaterial& material);
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color);
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area);
//! clears the zbuffer
virtual bool beginScene(bool backBuffer=true, bool zBuffer=true,
SColor color=SColor(255,0,0,0),
const SExposedVideoData& videoData=SExposedVideoData(),
core::rect<s32>* sourceRect=0);
//! presents the rendered scene on the screen, returns false if failed
virtual bool endScene();
//! Only used by the internal engine. Used to notify the driver that
//! the window was resized.
virtual void OnResize(const core::dimension2d<u32>& size);
//! returns size of the current render target
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const;
//! deletes all dynamic lights there are
virtual void deleteAllDynamicLights();
//! adds a dynamic light, returning an index to the light
//! \param light: the light data to use to create the light
//! \return An index to the light, or -1 if an error occurs
virtual s32 addDynamicLight(const SLight& light);
//! Turns a dynamic light on or off
//! \param lightIndex: the index returned by addDynamicLight
//! \param turnOn: true to turn the light on, false to turn it off
virtual void turnLightOn(s32 lightIndex, bool turnOn);
//! returns the maximal amount of dynamic lights the device can handle
virtual u32 getMaximalDynamicLightAmount() const;
//! Sets the dynamic ambient light color. The default color is
//! (0,0,0,0) which means it is dark.
//! \param color: New color of the ambient light.
virtual void setAmbientLight(const SColorf& color);
//! draws a vertex primitive list
void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType);
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false);
//! Draws a part of the texture into the rectangle.
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false);
//! Draws a 3d line.
virtual void draw3DLine(const core::vector3df& start,
const core::vector3df& end, SColor color = SColor(255,255,255,255));
//! draw an 2d rectangle
virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
const core::rect<s32>* clip = 0);
//!Draws an 2d rectangle with a gradient.
virtual void draw2DRectangle(const core::rect<s32>& pos,
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
const core::rect<s32>* clip = 0);
//! Draws a 2d line.
virtual void draw2DLine(const core::position2d<s32>& start,
const core::position2d<s32>& end,
SColor color=SColor(255,255,255,255));
//! Draws a single pixel
virtual void drawPixel(u32 x, u32 y, const SColor & color);
//! \return Returns the name of the video driver. Example: In case of the DirectX8
//! driver, it would return "Direct3D8.1".
virtual const wchar_t* getName() const;
//! Returns type of video driver
virtual E_DRIVER_TYPE getDriverType() const;
//! get color format of the current color buffer
virtual ECOLOR_FORMAT getColorFormat() const;
//! Returns the transformation set by setTransform
virtual const core::matrix4& getTransform(E_TRANSFORMATION_STATE state) const;
//! Creates a render target texture.
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN);
//! Clears the DepthBuffer.
virtual void clearZBuffer();
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER);
//! Returns the maximum amount of primitives (mostly vertices) which
//! the device is able to render with one drawIndexedTriangleList
//! call.
virtual u32 getMaximalPrimitiveCount() const;
//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
//! this: First, draw all geometry. Then use this method, to draw the shadow
//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
virtual void drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail=true, u32 debugDataVisible=0);
//! Fills the stencil shadow with color. After the shadow volume has been drawn
//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
//! to draw the color of the shadow.
virtual void drawStencilShadow(bool clearStencilBuffer=false,
video::SColor leftUpEdge = video::SColor(0,0,0,0),
video::SColor rightUpEdge = video::SColor(0,0,0,0),
video::SColor leftDownEdge = video::SColor(0,0,0,0),
video::SColor rightDownEdge = video::SColor(0,0,0,0));
//! Returns the graphics card vendor name.
virtual core::stringc getVendorInfo();
//! Returns the maximum texture size supported.
virtual core::dimension2du getMaxTextureSize() const;
virtual IDepthBuffer * getDepthBuffer () { return DepthBuffer; }
virtual IStencilBuffer * getStencilBuffer () { return StencilBuffer; }
protected:
//! sets a render target
void setRenderTarget(video::CImage* image);
//! sets the current Texture
//bool setTexture(u32 stage, video::ITexture* texture);
//! returns a device dependent texture from a software surface (IImage)
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData=0);
video::CImage* BackBuffer;
video::IImagePresenter* Presenter;
void* WindowId;
core::rect<s32>* SceneSourceRect;
video::ITexture* RenderTargetTexture;
video::IImage* RenderTargetSurface;
core::dimension2d<u32> RenderTargetSize;
//! selects the right triangle renderer based on the render states.
void setCurrentShader();
IBurningShader* CurrentShader;
IBurningShader* BurningShader[ETR2_COUNT];
IDepthBuffer* DepthBuffer;
IStencilBuffer* StencilBuffer;
/*
extend Matrix Stack
-> combined CameraProjection
-> combined CameraProjectionWorld
-> ClipScale from NDC to DC Space
*/
enum E_TRANSFORMATION_STATE_BURNING_VIDEO
{
ETS_VIEW_PROJECTION = ETS_COUNT,
ETS_CURRENT,
ETS_CLIPSCALE,
ETS_VIEW_INVERSE,
ETS_WORLD_INVERSE,
ETS_COUNT_BURNING
};
enum E_TRANSFORMATION_FLAG
{
ETF_IDENTITY = 1,
ETF_TEXGEN_CAMERA_NORMAL = 2,
ETF_TEXGEN_CAMERA_REFLECTION = 4,
};
u32 TransformationFlag[ETS_COUNT_BURNING];
core::matrix4 Transformation[ETS_COUNT_BURNING];
void getCameraPosWorldSpace ();
void getLightPosObjectSpace ();
// Vertex Cache
static const SVSize vSize[];
SVertexCache VertexCache;
void VertexCache_reset (const void* vertices, u32 vertexCount,
const void* indices, u32 indexCount,
E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType);
void VertexCache_get ( const s4DVertex ** face );
void VertexCache_getbypass ( s4DVertex ** face );
void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex );
s4DVertex * VertexCache_getVertex ( const u32 sourceIndex );
// culling & clipping
u32 clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane );
u32 clipToFrustumTest ( const s4DVertex * v ) const;
u32 clipToFrustum ( s4DVertex *source, s4DVertex * temp, const u32 vIn );
#ifdef SOFTWARE_DRIVER_2_LIGHTING
void lightVertex ( s4DVertex *dest, u32 vertexargb );
//! Sets the fog mode.
virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start,
f32 end, f32 density, bool pixelFog, bool rangeFog);
#endif
// holds transformed, clipped vertices
SAlignedVertex CurrentOut;
SAlignedVertex Temp;
void ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const;
f32 screenarea ( const s4DVertex *v0 ) const;
void select_polygon_mipmap ( s4DVertex *source, u32 vIn, u32 tex, const core::dimension2du& texSize ) const;
f32 texelarea ( const s4DVertex *v0, int tex ) const;
void ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const;
f32 screenarea2 ( const s4DVertex **v ) const;
f32 texelarea2 ( const s4DVertex **v, int tex ) const;
void select_polygon_mipmap2 ( s4DVertex **source, u32 tex, const core::dimension2du& texSize ) const;
SBurningShaderLightSpace LightSpace;
SBurningShaderMaterial Material;
static const sVec4 NDCPlane[6];
};
} // end namespace video
} // end namespace irr
#endif

View File

@@ -1,151 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
#include "CSoftwareTexture.h"
#include "os.h"
namespace irr
{
namespace video
{
//! constructor
CSoftwareTexture::CSoftwareTexture(IImage* image, const io::path& name,
bool renderTarget, void* mipmapData)
: ITexture(name), Texture(0), IsRenderTarget(renderTarget)
{
#ifdef _DEBUG
setDebugName("CSoftwareTexture");
#endif
if (image)
{
OrigSize = image->getDimension();
core::dimension2d<u32> optSize=OrigSize.getOptimalSize();
Image = new CImage(ECF_A1R5G5B5, OrigSize);
image->copyTo(Image);
if (optSize == OrigSize)
{
Texture = Image;
Texture->grab();
}
else
{
Texture = new CImage(ECF_A1R5G5B5, optSize);
Image->copyToScaling(Texture);
}
}
}
//! destructor
CSoftwareTexture::~CSoftwareTexture()
{
if (Image)
Image->drop();
if (Texture)
Texture->drop();
}
//! lock function
void* CSoftwareTexture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
{
return Image->lock();
}
//! unlock function
void CSoftwareTexture::unlock()
{
if (Image != Texture)
{
os::Printer::log("Performance warning, slow unlock of non power of 2 texture.", ELL_WARNING);
Image->copyToScaling(Texture);
}
Image->unlock();
}
//! Returns original size of the texture.
const core::dimension2d<u32>& CSoftwareTexture::getOriginalSize() const
{
return OrigSize;
}
//! Returns (=size) of the texture.
const core::dimension2d<u32>& CSoftwareTexture::getSize() const
{
return Image->getDimension();
}
//! returns unoptimized surface
CImage* CSoftwareTexture::getImage()
{
return Image;
}
//! returns texture surface
CImage* CSoftwareTexture::getTexture()
{
return Texture;
}
//! returns driver type of texture (=the driver, who created the texture)
E_DRIVER_TYPE CSoftwareTexture::getDriverType() const
{
return EDT_SOFTWARE;
}
//! returns color format of texture
ECOLOR_FORMAT CSoftwareTexture::getColorFormat() const
{
return ECF_A1R5G5B5;
}
//! returns pitch of texture (in bytes)
u32 CSoftwareTexture::getPitch() const
{
return Image->getDimension().Width * 2;
}
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
void CSoftwareTexture::regenerateMipMapLevels(void* mipmapData)
{
// our software textures don't have mip maps
}
bool CSoftwareTexture::isRenderTarget() const
{
return IsRenderTarget;
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_

View File

@@ -1,76 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_SOFTWARE_TEXTURE_H_INCLUDED__
#define __C_SOFTWARE_TEXTURE_H_INCLUDED__
#include "ITexture.h"
#include "CImage.h"
namespace irr
{
namespace video
{
/*!
interface for a Video Driver dependent Texture.
*/
class CSoftwareTexture : public ITexture
{
public:
//! constructor
CSoftwareTexture(IImage* surface, const io::path& name,
bool renderTarget=false, void* mipmapData=0);
//! destructor
virtual ~CSoftwareTexture();
//! lock function
virtual void* lock(E_TEXTURE_LOCK_MODE mode=ETLM_READ_WRITE, u32 mipmapLevel=0);
//! unlock function
virtual void unlock();
//! Returns original size of the texture.
virtual const core::dimension2d<u32>& getOriginalSize() const;
//! Returns (=size) of the texture.
virtual const core::dimension2d<u32>& getSize() const;
//! returns unoptimized surface
virtual CImage* getImage();
//! returns texture surface
virtual CImage* getTexture();
//! returns driver type of texture (=the driver, who created the texture)
virtual E_DRIVER_TYPE getDriverType() const;
//! returns color format of texture
virtual ECOLOR_FORMAT getColorFormat() const;
//! returns pitch of texture (in bytes)
virtual u32 getPitch() const;
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
virtual void regenerateMipMapLevels(void* mipmapData=0);
//! is it a render target?
virtual bool isRenderTarget() const;
private:
CImage* Image;
CImage* Texture;
core::dimension2d<u32> OrigSize;
bool IsRenderTarget;
};
} // end namespace video
} // end namespace irr
#endif

View File

@@ -1,156 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
#include "SoftwareDriver2_compile_config.h"
#include "SoftwareDriver2_helper.h"
#include "CSoftwareTexture2.h"
#include "os.h"
namespace irr
{
namespace video
{
//! constructor
CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name,
u32 flags, void* mipmapData)
: ITexture(name), MipMapLOD(0), Flags ( flags ), OriginalFormat(video::ECF_UNKNOWN)
{
#ifdef _DEBUG
setDebugName("CSoftwareTexture2");
#endif
#ifndef SOFTWARE_DRIVER_2_MIPMAPPING
Flags &= ~GEN_MIPMAP;
#endif
memset32 ( MipMap, 0, sizeof ( MipMap ) );
if (image)
{
OrigSize = image->getDimension();
OriginalFormat = image->getColorFormat();
core::setbit_cond(Flags,
image->getColorFormat () == video::ECF_A8R8G8B8 ||
image->getColorFormat () == video::ECF_A1R5G5B5,
HAS_ALPHA);
core::dimension2d<u32> optSize(
OrigSize.getOptimalSize( 0 != ( Flags & NP2_SIZE ),
false, false,
( Flags & NP2_SIZE ) ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 0)
);
if ( OrigSize == optSize )
{
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());
image->copyTo(MipMap[0]);
}
else
{
char buf[256];
core::stringw showName ( name );
snprintf ( buf, 256, "Burningvideo: Warning Texture %ls reformat %dx%d -> %dx%d,%d",
showName.c_str(),
OrigSize.Width, OrigSize.Height, optSize.Width, optSize.Height,
BURNINGSHADER_COLOR_FORMAT
);
OrigSize = optSize;
os::Printer::log ( buf, ELL_WARNING );
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);
image->copyToScalingBoxFilter ( MipMap[0],0, false );
}
OrigImageDataSizeInPixels = (f32) 0.3f * MipMap[0]->getImageDataSizeInPixels();
}
regenerateMipMapLevels(mipmapData);
}
//! destructor
CSoftwareTexture2::~CSoftwareTexture2()
{
for ( s32 i = 0; i!= SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
{
if ( MipMap[i] )
MipMap[i]->drop();
}
}
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
void CSoftwareTexture2::regenerateMipMapLevels(void* mipmapData)
{
if ( !hasMipMaps () )
return;
s32 i;
// release
for ( i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
{
if ( MipMap[i] )
MipMap[i]->drop();
}
core::dimension2d<u32> newSize;
core::dimension2d<u32> origSize=OrigSize;
for (i=1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
{
newSize = MipMap[i-1]->getDimension();
newSize.Width = core::s32_max ( 1, newSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
newSize.Height = core::s32_max ( 1, newSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
origSize.Width = core::s32_max(1, origSize.Width >> 1);
origSize.Height = core::s32_max(1, origSize.Height >> 1);
if (mipmapData)
{
if (OriginalFormat != BURNINGSHADER_COLOR_FORMAT)
{
IImage* tmpImage = new CImage(OriginalFormat, origSize, mipmapData, true, false);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
if (origSize==newSize)
tmpImage->copyTo(MipMap[i]);
else
tmpImage->copyToScalingBoxFilter(MipMap[i]);
tmpImage->drop();
}
else
{
if (origSize==newSize)
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mipmapData, false);
else
{
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mipmapData, true, false);
tmpImage->copyToScalingBoxFilter(MipMap[i]);
tmpImage->drop();
}
}
mipmapData = (u8*)mipmapData+origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8;
}
else
{
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
//static u32 color[] = { 0, 0xFFFF0000, 0xFF00FF00,0xFF0000FF,0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0xFF0F0F0F };
MipMap[i]->fill ( 0 );
MipMap[0]->copyToScalingBoxFilter( MipMap[i], 0, false );
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_

View File

@@ -1,300 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRFlat : public CTRTextureGouraud
{
public:
CTRFlat(IZBuffer* zbuffer)
: CTRTextureGouraud(zbuffer)
{
#ifdef _DEBUG
setDebugName("CTRFlat");
#endif
}
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
u16 color;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
s32 spanZValue, spanZStep; // ZValues when drawing a span
TZBufferType* zTarget, *spanZTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
color = v1->Color;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
// TODO: clipping is not correct when leftx is clipped.
if (leftx<ViewPortRect.UpperLeftCorner.X)
leftx = ViewPortRect.UpperLeftCorner.X;
else
if (leftx>ViewPortRect.LowerRightCorner.X)
leftx = ViewPortRect.LowerRightCorner.X;
if (rightx<ViewPortRect.UpperLeftCorner.X)
rightx = ViewPortRect.UpperLeftCorner.X;
else
if (rightx>ViewPortRect.LowerRightCorner.X)
rightx = ViewPortRect.LowerRightCorner.X;
// draw the span
if (rightx - leftx != 0)
{
tmpDiv = 1.0f / (rightx - leftx);
spanZValue = leftZValue;
spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv);
hSpanBegin = targetSurface + leftx;
spanZTarget = zTarget + leftx;
hSpanEnd = targetSurface + rightx;
while (hSpanBegin < hSpanEnd)
{
if (spanZValue > *spanZTarget)
{
*spanZTarget = spanZValue;
*hSpanBegin = color;
}
spanZValue += spanZStep;
++hSpanBegin;
++spanZTarget;
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
}
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererFlat(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRFlat(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,281 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRFlatWire : public CTRTextureGouraud
{
public:
CTRFlatWire(IZBuffer* zbuffer)
: CTRTextureGouraud(zbuffer)
{
#ifdef _DEBUG
setDebugName("CTRWire");
#endif
}
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
u16 color;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
TZBufferType* zTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
color = v1->Color;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
if (leftx>=ViewPortRect.UpperLeftCorner.X &&
leftx<=ViewPortRect.LowerRightCorner.X)
{
if (leftZValue > *(zTarget + leftx))
{
*(zTarget + leftx) = leftZValue;
*(targetSurface + leftx) = color;
}
}
if (rightx>=ViewPortRect.UpperLeftCorner.X &&
rightx<=ViewPortRect.LowerRightCorner.X)
{
if (rightZValue > *(zTarget + rightx))
{
*(zTarget + rightx) = rightZValue;
*(targetSurface + rightx) = color;
}
}
// draw the span
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
}
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererFlatWire(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRFlatWire(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,358 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRGouraud : public CTRTextureGouraud
{
public:
CTRGouraud(IZBuffer* zbuffer)
: CTRTextureGouraud(zbuffer)
{
#ifdef _DEBUG
setDebugName("CTRGouraud");
#endif
}
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels
s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values
s32 leftStepR, leftStepG, leftStepB,
rightStepR, rightStepG, rightStepB; // color steps
s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span.
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
s32 spanZValue, spanZStep; // ZValues when drawing a span
TZBufferType* zTarget, *spanZTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
leftR = rightR = video::getRed(v1->Color)<<11;
leftG = rightG = video::getGreen(v1->Color)<<11;
leftB = rightB = video::getBlue(v1->Color)<<11;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<11) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<11) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<11) - rightB) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - leftB) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - rightB) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<11) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<11) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<11) - leftB) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
leftR += leftStepR*leftx;
leftG += leftStepG*leftx;
leftB += leftStepB*leftx;
rightR += rightStepR*leftx;
rightG += rightStepG*leftx;
rightB += rightStepB*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
// TODO: clipping is not correct when leftx is clipped.
if (leftx<ViewPortRect.UpperLeftCorner.X)
leftx = ViewPortRect.UpperLeftCorner.X;
else
if (leftx>ViewPortRect.LowerRightCorner.X)
leftx = ViewPortRect.LowerRightCorner.X;
if (rightx<ViewPortRect.UpperLeftCorner.X)
rightx = ViewPortRect.UpperLeftCorner.X;
else
if (rightx>ViewPortRect.LowerRightCorner.X)
rightx = ViewPortRect.LowerRightCorner.X;
// draw the span
if (rightx - leftx != 0)
{
tmpDiv = 1.0f / (rightx - leftx);
spanZValue = leftZValue;
spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv);
hSpanBegin = targetSurface + leftx;
spanZTarget = zTarget + leftx;
hSpanEnd = targetSurface + rightx;
spanR = leftR;
spanG = leftG;
spanB = leftB;
spanStepR = (s32)((rightR - leftR) * tmpDiv);
spanStepG = (s32)((rightG - leftG) * tmpDiv);
spanStepB = (s32)((rightB - leftB) * tmpDiv);
while (hSpanBegin < hSpanEnd)
{
if (spanZValue > *spanZTarget)
{
*spanZTarget = spanZValue;
*hSpanBegin = video::RGB16(spanR>>8, spanG>>8, spanB>>8);
}
spanR += spanStepR;
spanG += spanStepG;
spanB += spanStepB;
spanZValue += spanZStep;
++hSpanBegin;
++spanZTarget;
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
leftR += leftStepR;
leftG += leftStepG;
leftB += leftStepB;
rightR += rightStepR;
rightG += rightStepG;
rightB += rightStepB;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
rightR = video::getRed(v2->Color)<<11;
rightG = video::getGreen(v2->Color)<<11;
rightB = video::getBlue(v2->Color)<<11;
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - rightB) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
leftR = video::getRed(v2->Color)<<11;
leftG = video::getGreen(v2->Color)<<11;
leftB = video::getBlue(v2->Color)<<11;
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - leftB) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
}
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererGouraud(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRGouraud(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,645 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
#define IPOL_C0
//#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRGouraud2 : public IBurningShader
{
public:
//! constructor
CTRGouraud2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRGouraud2::CTRGouraud2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRGouraud2");
#endif
}
/*!
*/
void CTRGouraud2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef IPOL_C0
tFixPoint r0, g0, b0;
#ifdef INVERSE_W
f32 inversew;
#endif
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef IPOL_C0
#ifdef INVERSE_W
inversew = core::reciprocal ( line.w[0] );
getSample_color ( r0, g0, b0, line.c[0][0] * inversew );
#else
getSample_color ( r0, g0, b0, line.c[0][0] );
#endif
dst[i] = fix_to_color ( r0, g0, b0 );
#else
dst[i] = COLOR_BRIGHT_WHITE;
#endif
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
if ( a->Pos.y > c->Pos.y ) swapVertexPointer(&a, &c);
if ( b->Pos.y > c->Pos.y ) swapVertexPointer(&b, &c);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraud2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,657 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
#define IPOL_C0
//#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRGouraudAlpha2 : public IBurningShader
{
public:
//! constructor
CTRGouraudAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRGouraudAlpha2::CTRGouraudAlpha2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRGouraudAlpha2");
#endif
}
/*!
*/
void CTRGouraudAlpha2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[0];
#endif
#ifdef IPOL_T1
sVec2 slopeT[1];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef IPOL_C0
#ifdef INVERSE_W
f32 inversew;
#endif
tFixPoint a0;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef IPOL_C0
#ifdef INVERSE_W
inversew = core::reciprocal ( line.w[0] );
getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );
#else
getSample_color ( a0, r0, g0, b0, line.c[0][0] );
#endif
color_to_fix ( r1, g1, b1, dst[i] );
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix_to_color ( r2, g2, b2 );
#else
dst[i] = COLOR_BRIGHT_WHITE;
#endif
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudAlpha2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,654 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
//#define INVERSE_W
//#define USE_ZBUFFER
//#define IPOL_W
//#define CMP_W
//#define WRITE_W
#define IPOL_C0
//#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
//#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRGouraudAlphaNoZ2 : public IBurningShader
{
public:
//! constructor
CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRGouraudAlphaNoZ2::CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRGouraudAlphaNoZ2");
#endif
}
/*!
*/
void CTRGouraudAlphaNoZ2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef IPOL_C0
#ifdef INVERSE_W
f32 inversew;
#endif
tFixPoint a0;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
#ifdef IPOL_C0
#ifdef IPOL_W
inversew = core::reciprocal ( line.w[0] );
getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );
#else
getSample_color ( a0, r0, g0, b0, line.c[0][0] );
#endif
color_to_fix ( r1, g1, b1, dst[i] );
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix_to_color ( r2, g2, b2 );
#else
dst[i] = COLOR_BRIGHT_WHITE;
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudAlphaNoZ2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,326 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRGouraudWire : public CTRTextureGouraud
{
public:
CTRGouraudWire(IZBuffer* zbuffer)
: CTRTextureGouraud(zbuffer)
{
#ifdef _DEBUG
setDebugName("CTRGouraudWire");
#endif
}
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values
s32 leftStepR, leftStepG, leftStepB,
rightStepR, rightStepG, rightStepB; // color steps
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
TZBufferType* zTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
leftR = rightR = video::getRed(v1->Color)<<11;
leftG = rightG = video::getGreen(v1->Color)<<11;
leftB = rightB = video::getBlue(v1->Color)<<11;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<11) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<11) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<11) - rightB) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - leftB) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - rightB) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<11) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<11) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<11) - leftB) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
leftR += leftStepR*leftx;
leftG += leftStepG*leftx;
leftB += leftStepB*leftx;
rightR += rightStepR*leftx;
rightG += rightStepG*leftx;
rightB += rightStepB*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
if (leftx>=ViewPortRect.UpperLeftCorner.X &&
leftx<=ViewPortRect.LowerRightCorner.X)
{
if (leftZValue > *(zTarget + leftx))
{
*(zTarget + leftx) = leftZValue;
*(targetSurface + leftx) = video::RGB16(leftR>>8, leftG>>8, leftB>>8);
}
}
if (rightx>=ViewPortRect.UpperLeftCorner.X &&
rightx<=ViewPortRect.LowerRightCorner.X)
{
if (rightZValue > *(zTarget + rightx))
{
*(zTarget + rightx) = rightZValue;
*(targetSurface + rightx) = video::RGB16(rightR, rightG, rightB);
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
leftR += leftStepR;
leftG += leftStepG;
leftB += leftStepB;
rightR += rightStepR;
rightG += rightStepG;
rightB += rightStepB;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
rightR = video::getRed(v2->Color)<<11;
rightG = video::getGreen(v2->Color)<<11;
rightB = video::getBlue(v2->Color)<<11;
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - rightB) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
leftR = video::getRed(v2->Color)<<11;
leftG = video::getGreen(v2->Color)<<11;
leftB = video::getBlue(v2->Color)<<11;
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<11) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<11) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<11) - leftB) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
}
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererGouraudWire(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRGouraudWire(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,848 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
#undef IPOL_T2
#undef IPOL_L0
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
#define IPOL_C0
#define IPOL_T0
#define IPOL_T1
#define IPOL_L0
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRNormalMap : public IBurningShader
{
public:
//! constructor
CTRNormalMap(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRNormalMap");
#endif
}
/*!
*/
void CTRNormalMap::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#ifdef IPOL_L0
sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T2
slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;
#endif
#ifdef IPOL_L0
slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2] * subPixel;
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
tFixPoint tx0, tx1;
tFixPoint ty0, ty1;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
tFixPoint lx, ly, lz;
tFixPoint ndotl;
sVec3 light;
#ifdef IPOL_C0
tFixPoint r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
tx1 = tofix ( line.t[1][0].x,inversew);
ty1 = tofix ( line.t[1][0].y,inversew);
#ifdef IPOL_C0
r3 = tofix ( line.c[0][0].y ,inversew );
g3 = tofix ( line.c[0][0].z ,inversew );
b3 = tofix ( line.c[0][0].w ,inversew );
#endif
#else
tx0 = tofix ( line.t[0][0].x );
ty0 = tofix ( line.t[0][0].y );
tx1 = tofix ( line.t[1][0].x );
ty1 = tofix ( line.t[1][0].y );
#ifdef IPOL_C0
r3 = tofix ( line.c[0][0].y );
g3 = tofix ( line.c[0][0].z );
b3 = tofix ( line.c[0][0].w );
#endif
#endif
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
// normal map
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );
r1 = ( r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
g1 = ( g1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
b1 = ( b1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
/*
sVec3 l = line.l[0][0] * inversew;
l.setLength( 2.f );
lx = tofix ( l.x - 0.5f );
ly = tofix ( l.y - 0.5f );
lz = tofix ( l.z - 0.5f );
*/
lx = tofix ( line.l[0][0].x, inversew );
ly = tofix ( line.l[0][0].y, inversew );
lz = tofix ( line.l[0][0].z, inversew );
// DOT 3 Normal Map light in tangent space
ndotl = saturateFix ( FIX_POINT_HALF_COLOR + (( imulFix ( r1, lx ) + imulFix ( g1, ly ) + imulFix ( b1, lz ) ) << (COLOR_MAX_LOG2-1)) );
#ifdef IPOL_C0
// N . L
r2 = imulFix ( imulFix_tex1 ( r0, ndotl ), r3 );
g2 = imulFix ( imulFix_tex1 ( g0, ndotl ), g3 );
b2 = imulFix ( imulFix_tex1 ( b0, ndotl ), b3 );
/*
// heightmap: (1 - neu ) + alt - 0.5, on_minus_srcalpha + add signed
// emboss bump map
a4 -= a1;
r2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( r0 + a4, r3 ) ) );
g2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( g0 + a4, g3 ) ) );
b2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( b0 + a4, b3 ) ) );
*/
/*
r2 = clampfix_maxcolor ( imulFix_tex1 ( r2, r1 ) );
g2 = clampfix_maxcolor ( imulFix_tex1 ( g2, g1 ) );
b2 = clampfix_maxcolor ( imulFix_tex1 ( b2, b1 ) );
*/
#else
r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );
g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );
b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );
#endif
dst[i] = fix_to_color ( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2];
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0];
#endif
}
}
void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][0] = (c->Tex[2] - a->Tex[2]) * scan.invDeltaY[0];
scan.t[2][0] = a->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0];
scan.l[0][0] = a->LightTangent[0];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][1] = (b->Tex[2] - a->Tex[2]) * scan.invDeltaY[1];
scan.t[2][1] = a->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1];
scan.l[0][1] = a->LightTangent[0];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0] * subPixel;
scan.t[2][1] += scan.slopeT[2][1] * subPixel;
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0] * subPixel;
scan.l[0][1] += scan.slopeL[0][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
#ifdef IPOL_T2
line.t[2][scan.left] = scan.t[2][0];
line.t[2][scan.right] = scan.t[2][1];
#endif
#ifdef IPOL_L0
line.l[0][scan.left] = scan.l[0][0];
line.l[0][scan.right] = scan.l[0][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0];
scan.t[2][1] += scan.slopeT[2][1];
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0];
scan.l[0][1] += scan.slopeL[0][1];
#endif
}
}
// rasterize lower sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
//if( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
#ifdef IPOL_T2
scan.t[2][0] = a->Tex[2] + scan.slopeT[2][0] * temp[0];
#endif
#ifdef IPOL_L0
scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][1] = (c->Tex[2] - b->Tex[2]) * scan.invDeltaY[2];
scan.t[2][1] = b->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2];
scan.l[0][1] = b->LightTangent[0];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0] * subPixel;
scan.t[2][1] += scan.slopeT[2][1] * subPixel;
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0] * subPixel;
scan.l[0][1] += scan.slopeL[0][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
#ifdef IPOL_T2
line.t[2][scan.left] = scan.t[2][0];
line.t[2][scan.right] = scan.t[2][1];
#endif
#ifdef IPOL_L0
line.l[0][scan.left] = scan.l[0][0];
line.l[0][scan.right] = scan.l[0][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0];
scan.t[2][1] += scan.slopeT[2][1];
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0];
scan.l[0][1] += scan.slopeL[0][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a triangle renderer
IBurningShader* createTRNormalMap(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRNormalMap(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,930 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef USE_SBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
#undef IPOL_T2
#undef IPOL_L0
// define render case
#define SUBTEXEL
//#define INVERSE_W
#define USE_ZBUFFER
#define USE_SBUFFER
#define IPOL_W
#define CMP_W
//#define WRITE_W
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRStencilShadow : public IBurningShader
{
public:
//! constructor
CTRStencilShadow(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
virtual void setParam ( u32 index, f32 value);
private:
// fragment shader
typedef void (CTRStencilShadow::*tFragmentShader) ();
void fragment_zfail_decr ();
void fragment_zfail_incr ();
tFragmentShader fragmentShader;
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRStencilShadow::CTRStencilShadow(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRStencilShadow");
#endif
}
/*!
*/
void CTRStencilShadow::setParam ( u32 index, f32 value)
{
u32 val = (u32) value;
// glStencilOp (fail,zfail,zpass
if ( index == 1 && val == 1 )
{
fragmentShader = &CTRStencilShadow::fragment_zfail_incr;
}
else
if ( index == 1 && val == 2 )
{
fragmentShader = &CTRStencilShadow::fragment_zfail_decr;
}
}
/*!
*/
void CTRStencilShadow::fragment_zfail_decr ()
{
if (!Stencil)
return;
//tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
#ifdef USE_SBUFFER
u32 *stencil;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#ifdef IPOL_L0
sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T2
slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;
#endif
#ifdef IPOL_L0
slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2] * subPixel;
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0] * subPixel;
#endif
#endif
//dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef USE_SBUFFER
stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
#ifdef IPOL_C0
tFixPoint r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] < z[i] )
#endif
{
// zfail
stencil[i] -= 1;
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2];
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0];
#endif
}
}
/*!
*/
void CTRStencilShadow::fragment_zfail_incr()
{
if (!Stencil)
return;
//tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
#ifdef USE_SBUFFER
u32 *stencil;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#ifdef IPOL_L0
sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T2
slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;
#endif
#ifdef IPOL_L0
slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2] * subPixel;
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0] * subPixel;
#endif
#endif
//dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef USE_SBUFFER
stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
#ifdef IPOL_C0
tFixPoint r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] < z[i] )
#endif
{
// zfail
stencil[i] += 1;
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2];
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0];
#endif
}
}
void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][0] = (c->Tex[2] - a->Tex[2]) * scan.invDeltaY[0];
scan.t[2][0] = a->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0];
scan.l[0][0] = a->LightTangent[0];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][1] = (b->Tex[2] - a->Tex[2]) * scan.invDeltaY[1];
scan.t[2][1] = a->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1];
scan.l[0][1] = a->LightTangent[0];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0] * subPixel;
scan.t[2][1] += scan.slopeT[2][1] * subPixel;
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0] * subPixel;
scan.l[0][1] += scan.slopeL[0][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
#ifdef IPOL_T2
line.t[2][scan.left] = scan.t[2][0];
line.t[2][scan.right] = scan.t[2][1];
#endif
#ifdef IPOL_L0
line.l[0][scan.left] = scan.l[0][0];
line.l[0][scan.right] = scan.l[0][1];
#endif
// render a scanline
(this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0];
scan.t[2][1] += scan.slopeT[2][1];
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0];
scan.l[0][1] += scan.slopeL[0][1];
#endif
}
}
// rasterize lower sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
//if( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
#ifdef IPOL_T2
scan.t[2][0] = a->Tex[2] + scan.slopeT[2][0] * temp[0];
#endif
#ifdef IPOL_L0
scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
#ifdef IPOL_T2
scan.slopeT[2][1] = (c->Tex[2] - b->Tex[2]) * scan.invDeltaY[2];
scan.t[2][1] = b->Tex[2];
#endif
#ifdef IPOL_L0
scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2];
scan.l[0][1] = b->LightTangent[0];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0] * subPixel;
scan.t[2][1] += scan.slopeT[2][1] * subPixel;
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0] * subPixel;
scan.l[0][1] += scan.slopeL[0][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
#ifdef IPOL_T2
line.t[2][scan.left] = scan.t[2][0];
line.t[2][scan.right] = scan.t[2][1];
#endif
#ifdef IPOL_L0
line.l[0][scan.left] = scan.l[0][0];
line.l[0][scan.right] = scan.l[0][1];
#endif
// render a scanline
(this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
#ifdef IPOL_T2
scan.t[2][0] += scan.slopeT[2][0];
scan.t[2][1] += scan.slopeT[2][1];
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0];
scan.l[0][1] += scan.slopeL[0][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a triangle renderer
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRStencilShadow(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@@ -1,659 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
#define IPOL_C0
#define IPOL_T0
#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureDetailMap2 : public IBurningShader
{
public:
//! constructor
CTRTextureDetailMap2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRTextureDetailMap2::CTRTextureDetailMap2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureDetailMap2");
#endif
}
/*!
*/
void CTRTextureDetailMap2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
tFixPoint tx0, tx1;
tFixPoint ty0, ty1;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
tx1 = tofix ( line.t[1][0].x,inversew);
ty1 = tofix ( line.t[1][0].y,inversew);
#else
tx0 = tofix ( line.t[0][0].x );
ty0 = tofix ( line.t[0][0].y );
tx1 = tofix ( line.t[1][0].x );
ty1 = tofix ( line.t[1][0].y );
#endif
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
getSample_texture ( r1, g1, b1, &IT[1], tx1,ty1 );
// bias half color
r1 += -FIX_POINT_HALF_COLOR;
g1 += -FIX_POINT_HALF_COLOR;
b1 += -FIX_POINT_HALF_COLOR;
r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 ) );
g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 ) );
b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 ) );
dst[i] = fix_to_color ( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureDetailMap2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureDetailMap2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,339 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRTextureFlat : public CTRTextureGouraud
{
public:
CTRTextureFlat(IZBuffer* zbuffer)
: CTRTextureGouraud(zbuffer)
{
#ifdef _DEBUG
setDebugName("CTRTextureFlat");
#endif
}
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels
s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values
s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values
s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
s32 spanZValue, spanZStep; // ZValues when drawing a span
TZBufferType* zTarget, *spanZTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
lockedTexture = (u16*)Texture->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
leftTx = rightTx = v1->TCoords.X;
leftTy = rightTy = v1->TCoords.Y;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
leftTx += leftTxStep*leftx;
leftTy += leftTyStep*leftx;
rightTx += rightTxStep*leftx;
rightTy += rightTyStep*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
// TODO: clipping is not correct when leftx is clipped.
if (leftx<ViewPortRect.UpperLeftCorner.X)
leftx = ViewPortRect.UpperLeftCorner.X;
else
if (leftx>ViewPortRect.LowerRightCorner.X)
leftx = ViewPortRect.LowerRightCorner.X;
if (rightx<ViewPortRect.UpperLeftCorner.X)
rightx = ViewPortRect.UpperLeftCorner.X;
else
if (rightx>ViewPortRect.LowerRightCorner.X)
rightx = ViewPortRect.LowerRightCorner.X;
// draw the span
if (rightx - leftx != 0)
{
tmpDiv = 1.0f / (rightx - leftx);
spanZValue = leftZValue;
spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv);
hSpanBegin = targetSurface + leftx;
spanZTarget = zTarget + leftx;
hSpanEnd = targetSurface + rightx;
spanTx = leftTx;
spanTy = leftTy;
spanTxStep = (s32)((rightTx - leftTx) * tmpDiv);
spanTyStep = (s32)((rightTy - leftTy) * tmpDiv);
while (hSpanBegin < hSpanEnd)
{
if (spanZValue > *spanZTarget)
{
*spanZTarget = spanZValue;
*hSpanBegin = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)];
}
spanTx += spanTxStep;
spanTy += spanTyStep;
spanZValue += spanZStep;
++hSpanBegin;
++spanZTarget;
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
leftTx += leftTxStep;
leftTy += leftTyStep;
rightTx += rightTxStep;
rightTy += rightTyStep;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
rightTx = v2->TCoords.X;
rightTy = v2->TCoords.Y;
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
leftTx = v2->TCoords.X;
leftTy = v2->TCoords.Y;
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
Texture->unlock();
}
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererTextureFlat(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRTextureFlat(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,313 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRTextureFlatWire : public CTRTextureGouraud
{
public:
CTRTextureFlatWire(IZBuffer* zbuffer)
: CTRTextureGouraud(zbuffer)
{
#ifdef _DEBUG
setDebugName("CTRTextureFlatWire");
#endif
}
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values
s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
TZBufferType* zTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
lockedTexture = (u16*)Texture->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
leftTx = rightTx = v1->TCoords.X;
leftTy = rightTy = v1->TCoords.Y;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
leftTx += leftTxStep*leftx;
leftTy += leftTyStep*leftx;
rightTx += rightTxStep*leftx;
rightTy += rightTyStep*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
if (leftx>=ViewPortRect.UpperLeftCorner.X &&
leftx<=ViewPortRect.LowerRightCorner.X)
{
if (leftZValue > *(zTarget + leftx))
{
*(zTarget + leftx) = leftZValue;
*(targetSurface + leftx) = lockedTexture[((leftTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)];
}
}
if (rightx>=ViewPortRect.UpperLeftCorner.X &&
rightx<=ViewPortRect.LowerRightCorner.X)
{
if (rightZValue > *(zTarget + rightx))
{
*(zTarget + rightx) = rightZValue;
*(targetSurface + rightx) = lockedTexture[((rightTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)];
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
leftTx += leftTxStep;
leftTy += leftTyStep;
rightTx += rightTxStep;
rightTy += rightTyStep;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
rightTx = v2->TCoords.X;
rightTy = v2->TCoords.Y;
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
leftTx = v2->TCoords.X;
leftTy = v2->TCoords.Y;
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
Texture->unlock();
}
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererTextureFlatWire(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRTextureFlatWire(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,468 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! constructor
CTRTextureGouraud::CTRTextureGouraud(IZBuffer* zbuffer)
: RenderTarget(0), ZBuffer(zbuffer), SurfaceWidth(0), SurfaceHeight(0),
BackFaceCullingEnabled(true), lockedZBuffer(0),
lockedSurface(0), lockedTexture(0), lockedTextureWidth(0),
textureXMask(0), textureYMask(0), Texture(0)
{
#ifdef _DEBUG
setDebugName("CTRTextureGouraud");
#endif
if (ZBuffer)
zbuffer->grab();
}
//! destructor
CTRTextureGouraud::~CTRTextureGouraud()
{
if (RenderTarget)
RenderTarget->drop();
if (ZBuffer)
ZBuffer->drop();
if (Texture)
Texture->drop();
}
//! sets the Texture
void CTRTextureGouraud::setTexture(video::IImage* texture)
{
if (Texture)
Texture->drop();
Texture = texture;
if (Texture)
{
Texture->grab();
lockedTextureWidth = Texture->getDimension().Width;
textureXMask = lockedTextureWidth-1;
textureYMask = Texture->getDimension().Height-1;
}
}
//! en or disables the backface culling
void CTRTextureGouraud::setBackfaceCulling(bool enabled)
{
BackFaceCullingEnabled = enabled;
}
//! sets a render target
void CTRTextureGouraud::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)
{
if (RenderTarget)
RenderTarget->drop();
RenderTarget = surface;
if (RenderTarget)
{
SurfaceWidth = RenderTarget->getDimension().Width;
SurfaceHeight = RenderTarget->getDimension().Height;
RenderTarget->grab();
ViewPortRect = viewPort;
}
}
//! draws an indexed triangle list
void CTRTextureGouraud::drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels
s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values
s32 leftStepR, leftStepG, leftStepB,
rightStepR, rightStepG, rightStepB; // color steps
s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span.
s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values
s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values
s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
s32 spanZValue, spanZStep; // ZValues when drawing a span
TZBufferType* zTarget, *spanZTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
lockedTexture = (u16*)Texture->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
leftR = rightR = video::getRed(v1->Color)<<8;
leftG = rightG = video::getGreen(v1->Color)<<8;
leftB = rightB = video::getBlue(v1->Color)<<8;
leftTx = rightTx = v1->TCoords.X;
leftTy = rightTy = v1->TCoords.Y;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv);
rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv);
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv);
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv);
leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
leftR += leftStepR*leftx;
leftG += leftStepG*leftx;
leftB += leftStepB*leftx;
rightR += rightStepR*leftx;
rightG += rightStepG*leftx;
rightB += rightStepB*leftx;
leftTx += leftTxStep*leftx;
leftTy += leftTyStep*leftx;
rightTx += rightTxStep*leftx;
rightTy += rightTyStep*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
// thanks to a correction by hybrid
// calculations delayed to correctly propagate to textures etc.
s32 tDiffLeft=0, tDiffRight=0;
if (leftx<ViewPortRect.UpperLeftCorner.X)
tDiffLeft=ViewPortRect.UpperLeftCorner.X-leftx;
else
if (leftx>ViewPortRect.LowerRightCorner.X)
tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx;
if (rightx<ViewPortRect.UpperLeftCorner.X)
tDiffRight=ViewPortRect.UpperLeftCorner.X-rightx;
else
if (rightx>ViewPortRect.LowerRightCorner.X)
tDiffRight=ViewPortRect.LowerRightCorner.X-rightx;
// draw the span
if (rightx + tDiffRight - leftx - tDiffLeft)
{
tmpDiv = 1.0f / (f32)(rightx - leftx);
spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv);
spanZValue = leftZValue+tDiffLeft*spanZStep;
spanStepR = (s32)((rightR - leftR) * tmpDiv);
spanR = leftR+tDiffLeft*spanStepR;
spanStepG = (s32)((rightG - leftG) * tmpDiv);
spanG = leftG+tDiffLeft*spanStepG;
spanStepB = (s32)((rightB - leftB) * tmpDiv);
spanB = leftB+tDiffLeft*spanStepB;
spanTxStep = (s32)((rightTx - leftTx) * tmpDiv);
spanTx = leftTx + tDiffLeft*spanTxStep;
spanTyStep = (s32)((rightTy - leftTy) * tmpDiv);
spanTy = leftTy+tDiffLeft*spanTyStep;
hSpanBegin = targetSurface + leftx+tDiffLeft;
spanZTarget = zTarget + leftx+tDiffLeft;
hSpanEnd = targetSurface + rightx+tDiffRight;
while (hSpanBegin < hSpanEnd)
{
if (spanZValue > *spanZTarget)
{
*spanZTarget = spanZValue;
u16 color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)];
*hSpanBegin = video::RGB16(video::getRed(color) * (spanR>>8) >>2,
video::getGreen(color) * (spanG>>8) >>2,
video::getBlue(color) * (spanB>>8) >>2);
}
spanR += spanStepR;
spanG += spanStepG;
spanB += spanStepB;
spanTx += spanTxStep;
spanTy += spanTyStep;
spanZValue += spanZStep;
++hSpanBegin;
++spanZTarget;
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
leftR += leftStepR;
leftG += leftStepG;
leftB += leftStepB;
rightR += rightStepR;
rightG += rightStepG;
rightB += rightStepB;
leftTx += leftTxStep;
leftTy += leftTyStep;
rightTx += rightTxStep;
rightTy += rightTyStep;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
rightR = video::getRed(v2->Color)<<8;
rightG = video::getGreen(v2->Color)<<8;
rightB = video::getBlue(v2->Color)<<8;
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv);
rightTx = v2->TCoords.X;
rightTy = v2->TCoords.Y;
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
leftR = video::getRed(v2->Color)<<8;
leftG = video::getGreen(v2->Color)<<8;
leftB = video::getBlue(v2->Color)<<8;
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv);
leftTx = v2->TCoords.X;
leftTy = v2->TCoords.Y;
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
Texture->unlock();
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererTextureGouraud(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRTextureGouraud(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,85 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_TRIANGLE_RENDERER_TEXTURE_GOURAUD_H_INCLUDED__
#define __C_TRIANGLE_RENDERER_TEXTURE_GOURAUD_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifndef _IRR_COMPILE_WITH_SOFTWARE_
// forward declarations for create methods
namespace irr
{
namespace video
{
class ITriangleRenderer;
class IZBuffer;
} // end namespace video
} // end namespace irr
#else
#include "ITriangleRenderer.h"
#include "IImage.h"
namespace irr
{
namespace video
{
//! CTRTextureGouraud class
class CTRTextureGouraud : public ITriangleRenderer
{
public:
//! constructor
CTRTextureGouraud(IZBuffer* zbuffer);
//! destructor
virtual ~CTRTextureGouraud();
//! sets a render target
virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort);
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount);
//! en or disables the backface culling
virtual void setBackfaceCulling(bool enabled = true);
//! sets the Texture
virtual void setTexture(video::IImage* texture);
protected:
//! vertauscht zwei vertizen
inline void swapVertices(const S2DVertex** v1, const S2DVertex** v2)
{
const S2DVertex* b = *v1;
*v1 = *v2;
*v2 = b;
}
video::IImage* RenderTarget;
core::rect<s32> ViewPortRect;
IZBuffer* ZBuffer;
s32 SurfaceWidth;
s32 SurfaceHeight;
bool BackFaceCullingEnabled;
TZBufferType* lockedZBuffer;
u16* lockedSurface;
u16* lockedTexture;
s32 lockedTextureWidth;
s32 textureXMask, textureYMask;
video::IImage* Texture;
};
} // end namespace video
} // end namespace irr
#endif
#endif

View File

@@ -1,674 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureGouraud2 : public IBurningShader
{
public:
//! constructor
CTRTextureGouraud2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRTextureGouraud2::CTRTextureGouraud2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureGouraud2");
#endif
}
/*!
*/
void CTRTextureGouraud2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
tFixPoint tx0;
tFixPoint ty0;
tFixPoint r0, g0, b0;
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
u32 dIndex = ( line.y & 3 ) << 2;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x, inversew);
ty0 = tofix ( line.t[0][0].y, inversew);
#ifdef IPOL_C0
r1 = tofix ( line.c[0][0].y ,inversew );
g1 = tofix ( line.c[0][0].z ,inversew );
b1 = tofix ( line.c[0][0].w ,inversew );
#endif
#else
tx0 = tofix ( line.t[0][0].x );
ty0 = tofix ( line.t[0][0].y );
#ifdef IPOL_C0
getTexel_plain2 ( r1, g1, b1, line.c[0][0] );
#endif
#endif
#ifdef IPOL_C0
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
dst[i] = fix_to_color ( imulFix ( r0, r1 ),
imulFix ( g0, g1 ),
imulFix ( b0, b1 )
);
#else
#ifdef BURNINGVIDEO_RENDERER_FAST
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
dst[i] = getTexel_plain ( &IT[0], d + tx0, d + ty0 );
#else
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
dst[i] = fix_to_color ( r0, g0, b0 );
#endif
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraud2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,419 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRTextureGouraudAdd : public CTRTextureGouraud
{
public:
//! constructor
CTRTextureGouraudAdd(IZBuffer* zbuffer);
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount);
protected:
};
//! constructor
CTRTextureGouraudAdd::CTRTextureGouraudAdd(IZBuffer* zbuffer)
: CTRTextureGouraud(zbuffer)
{
#ifdef _DEBUG
setDebugName("CTRTextureGouraudAdd");
#endif
}
//! draws an indexed triangle list
void CTRTextureGouraudAdd::drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
u16 color;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels
s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values
s32 leftStepR, leftStepG, leftStepB,
rightStepR, rightStepG, rightStepB; // color steps
s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span.
s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values
s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values
s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
s32 spanZValue, spanZStep; // ZValues when drawing a span
TZBufferType* zTarget, *spanZTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
lockedTexture = (u16*)Texture->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
leftR = rightR = video::getRed(v1->Color)<<8;
leftG = rightG = video::getGreen(v1->Color)<<8;
leftB = rightB = video::getBlue(v1->Color)<<8;
leftTx = rightTx = v1->TCoords.X;
leftTy = rightTy = v1->TCoords.Y;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv);
rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv);
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv);
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv);
leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
leftR += leftStepR*leftx;
leftG += leftStepG*leftx;
leftB += leftStepB*leftx;
rightR += rightStepR*leftx;
rightG += rightStepG*leftx;
rightB += rightStepB*leftx;
leftTx += leftTxStep*leftx;
leftTy += leftTyStep*leftx;
rightTx += rightTxStep*leftx;
rightTy += rightTyStep*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
// thanks to a correction by hybrid
// calculations delayed to correctly propagate to textures etc.
s32 tDiffLeft=0, tDiffRight=0;
if (leftx<ViewPortRect.UpperLeftCorner.X)
tDiffLeft=ViewPortRect.UpperLeftCorner.X-leftx;
else
if (leftx>ViewPortRect.LowerRightCorner.X)
tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx;
if (rightx<ViewPortRect.UpperLeftCorner.X)
tDiffRight=ViewPortRect.UpperLeftCorner.X-rightx;
else
if (rightx>ViewPortRect.LowerRightCorner.X)
tDiffRight=ViewPortRect.LowerRightCorner.X-rightx;
// draw the span
if (rightx + tDiffRight - leftx - tDiffLeft)
{
tmpDiv = 1.0f / (f32)(rightx - leftx);
spanZStep = (s32)((rightZValue - leftZValue) * tmpDiv);
spanZValue = leftZValue+tDiffLeft*spanZStep;
spanStepR = (s32)((rightR - leftR) * tmpDiv);
spanR = leftR+tDiffLeft*spanStepR;
spanStepG = (s32)((rightG - leftG) * tmpDiv);
spanG = leftG+tDiffLeft*spanStepG;
spanStepB = (s32)((rightB - leftB) * tmpDiv);
spanB = leftB+tDiffLeft*spanStepB;
spanTxStep = (s32)((rightTx - leftTx) * tmpDiv);
spanTx = leftTx + tDiffLeft*spanTxStep;
spanTyStep = (s32)((rightTy - leftTy) * tmpDiv);
spanTy = leftTy+tDiffLeft*spanTyStep;
hSpanBegin = targetSurface + leftx+tDiffLeft;
spanZTarget = zTarget + leftx+tDiffLeft;
hSpanEnd = targetSurface + rightx+tDiffRight;
while (hSpanBegin < hSpanEnd)
{
if (spanZValue > *spanZTarget)
{
//*spanZTarget = spanZValue;
color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)];
s32 basis = *hSpanBegin;
s32 r = (video::getRed(basis)<<3) + (video::getRed(color)<<3);
if (r > 255) r = 255;
s32 g = (video::getGreen(basis)<<3) + (video::getGreen(color)<<3);
if (g > 255) g = 255;
s32 b = (video::getBlue(basis)<<3) + (video::getBlue(color)<<3);
if (b > 255) b = 255;
*hSpanBegin = video::RGB16(r, g, b);
}
spanR += spanStepR;
spanG += spanStepG;
spanB += spanStepB;
spanTx += spanTxStep;
spanTy += spanTyStep;
spanZValue += spanZStep;
++hSpanBegin;
++spanZTarget;
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
leftR += leftStepR;
leftG += leftStepG;
leftB += leftStepB;
rightR += rightStepR;
rightG += rightStepG;
rightB += rightStepB;
leftTx += leftTxStep;
leftTy += leftTyStep;
rightTx += rightTxStep;
rightTy += rightTyStep;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
rightR = video::getRed(v2->Color)<<8;
rightG = video::getGreen(v2->Color)<<8;
rightB = video::getBlue(v2->Color)<<8;
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv);
rightTx = v2->TCoords.X;
rightTy = v2->TCoords.Y;
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
leftR = video::getRed(v2->Color)<<8;
leftG = video::getGreen(v2->Color)<<8;
leftB = video::getBlue(v2->Color)<<8;
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv);
leftTx = v2->TCoords.X;
leftTy = v2->TCoords.Y;
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
Texture->unlock();
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
ITriangleRenderer* createTriangleRendererTextureGouraudAdd(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRTextureGouraudAdd(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,680 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
//#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureGouraudAdd2 : public IBurningShader
{
public:
//! constructor
CTRTextureGouraudAdd2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanLineData line;
};
//! constructor
CTRTextureGouraudAdd2::CTRTextureGouraudAdd2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureGouraudAdd2");
#endif
}
/*!
*/
void CTRTextureGouraudAdd2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[1] - line.c[0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
u32 dIndex = ( line.y & 3 ) << 2;
#else
tFixPoint tx0;
tFixPoint ty0;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef BURNINGVIDEO_RENDERER_FAST
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
dst[i] = PixelAdd32 (
dst[i],
getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
d + tofix ( line.t[0][0].y,inversew) )
);
#else
dst[i] = PixelAdd32 (
dst[i],
getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x),
d + tofix ( line.t[0][0].y) )
);
#endif
#else
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
#else
tx0 = tofix ( line.t[0][0].x );
ty0 = tofix ( line.t[0][0].y );
#endif
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
color_to_fix ( r1, g1, b1, dst[i] );
dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + r0 ),
clampfix_maxcolor ( g1 + g0 ),
clampfix_maxcolor ( b1 + b0 )
);
#endif
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
sScanConvertData scan;
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAdd2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,645 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
//#define WRITE_W
//#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureGouraudAddNoZ2 : public IBurningShader
{
public:
//! constructor
CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRTextureGouraudAddNoZ2::CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureGouraudAddNoZ2");
#endif
}
/*!
*/
void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[1] - line.c[0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef IPOL_W
f32 inversew;
#endif
tFixPoint tx0;
tFixPoint ty0;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef IPOL_W
inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
#else
tx0 = tofix ( line.t[0][0].x );
ty0 = tofix ( line.t[0][0].y );
#endif
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
color_to_fix ( r1, g1, b1, dst[i] );
dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + (r0 >> 1 ) ),
clampfix_maxcolor ( g1 + (g0 >> 1 ) ),
clampfix_maxcolor ( b1 + (b0 >> 1) )
);
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAddNoZ2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,744 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureGouraudAlpha2 : public IBurningShader
{
public:
//! constructor
CTRTextureGouraudAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
virtual void setParam ( u32 index, f32 value);
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
u32 AlphaRef;
};
//! constructor
CTRTextureGouraudAlpha2::CTRTextureGouraudAlpha2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureGouraudAlpha2");
#endif
AlphaRef = 0;
}
/*!
*/
void CTRTextureGouraudAlpha2::setParam ( u32 index, f32 value)
{
#ifdef BURNINGVIDEO_RENDERER_FAST
AlphaRef = core::floor32 ( value * 256.f );
#else
AlphaRef = u32_to_fixPoint ( core::floor32 ( value * 256.f ) );
#endif
}
/*!
*/
void CTRTextureGouraudAlpha2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
u32 dIndex = ( line.y & 3 ) << 2;
#else
tFixPoint a0;
tFixPoint r0, g0, b0;
#endif
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef BURNINGVIDEO_RENDERER_FAST
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
u32 argb = getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
d + tofix ( line.t[0][0].y,inversew)
);
#else
u32 argb = getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x),
d + tofix ( line.t[0][0].y)
);
#endif
const u32 alpha = ( argb >> 24 );
if ( alpha > AlphaRef )
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
dst[i] = PixelBlend32 ( dst[i], argb, alpha );
}
#else
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
getSample_texture ( a0,r0,g0,b0,
&IT[0],
tofix ( line.t[0][0].x,inversew),
tofix ( line.t[0][0].y,inversew)
);
#else
getSample_texture ( a0,r0,g0,b0,
&IT[0],
tofix ( line.t[0][0].x),
tofix ( line.t[0][0].y)
);
#endif
if ( (tFixPointu) a0 > AlphaRef )
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
#ifdef INVERSE_W
getSample_color ( r2, g2, b2, line.c[0][0], inversew );
#else
getSample_color ( r2, g2, b2, line.c[0][0] );
#endif
r0 = imulFix ( r0, r2 );
g0 = imulFix ( g0, g2 );
b0 = imulFix ( b0, b2 );
color_to_fix ( r1, g1, b1, dst[i] );
a0 >>= 8;
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix4_to_color ( a0, r2, g2, b2 );
/*
dst[i] = PixelBlend32 ( dst[i],
fix_to_color ( r0,g0, b0 ),
fixPointu_to_u32 ( a0 )
);
*/
/*
getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );
color_to_fix ( r1, g1, b1, dst[i] );
r2 = r0 + imulFix ( a0, r1 - r0 );
g2 = g0 + imulFix ( a0, g1 - g0 );
b2 = b0 + imulFix ( a0, b1 - b0 );
dst[i] = fix_to_color ( r2, g2, b2 );
*/
}
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAlpha2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,745 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
//#define WRITE_W
#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureGouraudAlphaNoZ : public IBurningShader
{
public:
//! constructor
CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
virtual void setParam ( u32 index, f32 value);
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
u32 AlphaRef;
};
//! constructor
CTRTextureGouraudAlphaNoZ::CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureGouraudAlphaNoZ");
#endif
AlphaRef = 0;
}
/*!
*/
void CTRTextureGouraudAlphaNoZ::setParam ( u32 index, f32 value)
{
#ifdef BURNINGVIDEO_RENDERER_FAST
AlphaRef = core::floor32 ( value * 256.f );
#else
AlphaRef = u32_to_fixPoint ( core::floor32 ( value * 256.f ) );
#endif
}
/*!
*/
void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
u32 dIndex = ( line.y & 3 ) << 2;
#else
tFixPoint a0;
tFixPoint r0, g0, b0;
#endif
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef BURNINGVIDEO_RENDERER_FAST
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
u32 argb = getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
d + tofix ( line.t[0][0].y,inversew)
);
#else
u32 argb = getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x),
d + tofix ( line.t[0][0].y)
);
#endif
const u32 alpha = ( argb >> 24 );
if ( alpha > AlphaRef )
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
dst[i] = PixelBlend32 ( dst[i], argb, alpha );
}
#else
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
getSample_texture ( a0, r0, g0, b0,
&IT[0],
tofix ( line.t[0][0].x,inversew),
tofix ( line.t[0][0].y,inversew)
);
#else
getSample_texture ( a0, r0, g0,b0,
&IT[0],
tofix ( line.t[0][0].x),
tofix ( line.t[0][0].y)
);
#endif
if ( (tFixPointu) a0 > AlphaRef )
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
#ifdef INVERSE_W
getSample_color ( r2, g2, b2, line.c[0][0], inversew );
#else
getSample_color ( r2, g2, b2, line.c[0][0] );
#endif
r0 = imulFix ( r0, r2 );
g0 = imulFix ( g0, g2 );
b0 = imulFix ( b0, b2 );
color_to_fix ( r1, g1, b1, dst[i] );
a0 >>= 8;
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix4_to_color ( a0, r2, g2, b2 );
/*
dst[i] = PixelBlend32 ( dst[i],
fix_to_color ( r0,g0, b0 ),
fixPointu_to_u32 ( a0 )
);
*/
/*
getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );
color_to_fix ( r1, g1, b1, dst[i] );
r2 = r0 + imulFix ( a0, r1 - r0 );
g2 = g0 + imulFix ( a0, g1 - g0 );
b2 = b0 + imulFix ( a0, b1 - b0 );
dst[i] = fix_to_color ( r2, g2, b2 );
*/
}
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAlphaNoZ(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,367 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#include "SColor.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRTextureGouraudNoZ : public CTRTextureGouraud
{
public:
CTRTextureGouraudNoZ()
: CTRTextureGouraud(0)
{
#ifdef _DEBUG
setDebugName("CTRGouraudWireNoZ");
#endif
}
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
u16 color;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
u16 *hSpanBegin, *hSpanEnd; // pointer used when plotting pixels
s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values
s32 leftStepR, leftStepG, leftStepB,
rightStepR, rightStepG, rightStepB; // color steps
s32 spanR, spanG, spanB, spanStepR, spanStepG, spanStepB; // color interpolating values while drawing a span.
s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values
s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values
s32 spanTx, spanTy, spanTxStep, spanTyStep; // values of Texturecoords when drawing a span
core::rect<s32> TriangleRect;
lockedSurface = (u16*)RenderTarget->lock();
lockedTexture = (u16*)Texture->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftR = rightR = video::getRed(v1->Color)<<8;
leftG = rightG = video::getGreen(v1->Color)<<8;
leftB = rightB = video::getBlue(v1->Color)<<8;
leftTx = rightTx = v1->TCoords.X;
leftTy = rightTy = v1->TCoords.Y;
targetSurface = lockedSurface + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv);
rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv);
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv);
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv);
leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
leftR += leftStepR*leftx;
leftG += leftStepG*leftx;
leftB += leftStepB*leftx;
rightR += rightStepR*leftx;
rightG += rightStepG*leftx;
rightB += rightStepB*leftx;
leftTx += leftTxStep*leftx;
leftTy += leftTyStep*leftx;
rightTx += rightTxStep*leftx;
rightTy += rightTyStep*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
// thanks to a correction by hybrid
// calculations delayed to correctly propagate to textures etc.
s32 tDiffLeft=0, tDiffRight=0;
if (leftx<ViewPortRect.UpperLeftCorner.X)
tDiffLeft=ViewPortRect.UpperLeftCorner.X-leftx;
else
if (leftx>ViewPortRect.LowerRightCorner.X)
tDiffLeft=ViewPortRect.LowerRightCorner.X-leftx;
if (rightx<ViewPortRect.UpperLeftCorner.X)
tDiffRight=ViewPortRect.UpperLeftCorner.X-rightx;
else
if (rightx>ViewPortRect.LowerRightCorner.X)
tDiffRight=ViewPortRect.LowerRightCorner.X-rightx;
// draw the span
if (rightx + tDiffRight - leftx - tDiffLeft)
{
tmpDiv = 1.0f / (f32)(rightx - leftx);
spanStepR = (s32)((rightR - leftR) * tmpDiv);
spanR = leftR+tDiffLeft*spanStepR;
spanStepG = (s32)((rightG - leftG) * tmpDiv);
spanG = leftG+tDiffLeft*spanStepG;
spanStepB = (s32)((rightB - leftB) * tmpDiv);
spanB = leftB+tDiffLeft*spanStepB;
spanTxStep = (s32)((rightTx - leftTx) * tmpDiv);
spanTx = leftTx + tDiffLeft*spanTxStep;
spanTyStep = (s32)((rightTy - leftTy) * tmpDiv);
spanTy = leftTy+tDiffLeft*spanTyStep;
hSpanBegin = targetSurface + leftx+tDiffLeft;
hSpanEnd = targetSurface + rightx+tDiffRight;
while (hSpanBegin < hSpanEnd)
{
color = lockedTexture[((spanTy>>8)&textureYMask) * lockedTextureWidth + ((spanTx>>8)&textureXMask)];
*hSpanBegin = video::RGB16(video::getRed(color) * (spanR>>8) >>2,
video::getGreen(color) * (spanG>>8) >>2,
video::getBlue(color) * (spanB>>8) >>2);
spanR += spanStepR;
spanG += spanStepG;
spanB += spanStepB;
spanTx += spanTxStep;
spanTy += spanTyStep;
++hSpanBegin;
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
leftR += leftStepR;
leftG += leftStepG;
leftB += leftStepB;
rightR += rightStepR;
rightG += rightStepG;
rightB += rightStepB;
leftTx += leftTxStep;
leftTy += leftTyStep;
rightTx += rightTxStep;
rightTy += rightTyStep;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightR = video::getRed(v2->Color)<<8;
rightG = video::getGreen(v2->Color)<<8;
rightB = video::getBlue(v2->Color)<<8;
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv);
rightTx = v2->TCoords.X;
rightTy = v2->TCoords.Y;
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftR = video::getRed(v2->Color)<<8;
leftG = video::getGreen(v2->Color)<<8;
leftB = video::getBlue(v2->Color)<<8;
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv);
leftTx = v2->TCoords.X;
leftTy = v2->TCoords.Y;
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
Texture->unlock();
}
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererTextureGouraudNoZ()
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRTextureGouraudNoZ();
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,647 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#ifdef BURNINGVIDEO_RENDERER_FAST
#define SUBTEXEL
#define INVERSE_W
#else
#define SUBTEXEL
#define INVERSE_W
#endif
//#define USE_ZBUFFER
#define IPOL_W
//#define CMP_W
//#define WRITE_W
//#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureGouraudNoZ2 : public IBurningShader
{
public:
//! constructor
CTRTextureGouraudNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRTextureGouraudNoZ2::CTRTextureGouraudNoZ2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureGouraudNoZ2");
#endif
}
/*!
*/
void CTRTextureGouraudNoZ2::scanline_bilinear ( )
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[1] - line.c[0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
tFixPoint tx0;
tFixPoint ty0;
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
#else
tx0 = tofix ( line.t[0][0].x );
ty0 = tofix ( line.t[0][0].y );
#endif
dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );
/*
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
dst[i] = fix_to_color ( r0, g0, b0 );
*/
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudNoZ2( driver );
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,690 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
//#define WRITE_W
#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureVertexAlpha2 : public IBurningShader
{
public:
//! constructor
CTRTextureVertexAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRTextureVertexAlpha2::CTRTextureVertexAlpha2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureVertexAlpha2");
#endif
}
/*!
*/
void CTRTextureVertexAlpha2::scanline_bilinear ( )
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
//#define __TEST_THIS
#ifdef __TEST_THIS
#else
tFixPoint tx0;
tFixPoint ty0;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#endif
#ifdef IPOL_C0
tFixPoint a3;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef __TEST_THIS
inversew = fix_inverse32 ( line.w[0] );
dst[i] = PixelAdd32 (
dst[i],
getTexel_plain ( &IT[0], tofix ( line.t[0][0].x,inversew),
tofix ( line.t[0][0].y,inversew) )
);
#else
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
#ifdef IPOL_C0
a3 = tofix ( line.c[0][0].y,inversew );
#endif
#else
tx0 = tofix ( line.t[0][0].x );
ty0 = tofix ( line.t[0][0].y );
#ifdef IPOL_C0
a3 = tofix ( line.c[0][0].y );
#endif
#endif
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
color_to_fix ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
r2 = clampfix_maxcolor ( r1 + imulFix ( r0, a3 ) );
g2 = clampfix_maxcolor ( g1 + imulFix ( g0, a3 ) );
b2 = clampfix_maxcolor ( b1 + imulFix ( b0, a3 ) );
#else
r2 = clampfix_maxcolor ( r1 + r0 );
g2 = clampfix_maxcolor ( g1 + g0 );
b2 = clampfix_maxcolor ( b1 + b0 );
#endif
dst[i] = fix_to_color ( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureVertexAlpha2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,364 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "CTRTextureGouraud.h"
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
class CTRTextureGouraudWire : public CTRTextureGouraud
{
public:
CTRTextureGouraudWire(IZBuffer* zbuffer)
: CTRTextureGouraud(zbuffer)
{
#ifdef _DEBUG
setDebugName("CTRGouraudWire");
#endif
}
//! draws an indexed triangle list
virtual void drawIndexedTriangleList(S2DVertex* vertices, s32 vertexCount, const u16* indexList, s32 triangleCount)
{
const S2DVertex *v1, *v2, *v3;
u16 color;
f32 tmpDiv; // temporary division factor
f32 longest; // saves the longest span
s32 height; // saves height of triangle
u16* targetSurface; // target pointer where to plot pixels
s32 spanEnd; // saves end of spans
f32 leftdeltaxf; // amount of pixels to increase on left side of triangle
f32 rightdeltaxf; // amount of pixels to increase on right side of triangle
s32 leftx, rightx; // position where we are
f32 leftxf, rightxf; // same as above, but as f32 values
s32 span; // current span
s32 leftR, leftG, leftB, rightR, rightG, rightB; // color values
s32 leftStepR, leftStepG, leftStepB,
rightStepR, rightStepG, rightStepB; // color steps
s32 leftTx, rightTx, leftTy, rightTy; // texture interpolating values
s32 leftTxStep, rightTxStep, leftTyStep, rightTyStep; // texture interpolating values
core::rect<s32> TriangleRect;
s32 leftZValue, rightZValue;
s32 leftZStep, rightZStep;
TZBufferType* zTarget;//, *spanZTarget; // target of ZBuffer;
lockedSurface = (u16*)RenderTarget->lock();
lockedZBuffer = ZBuffer->lock();
lockedTexture = (u16*)Texture->lock();
for (s32 i=0; i<triangleCount; ++i)
{
v1 = &vertices[*indexList];
++indexList;
v2 = &vertices[*indexList];
++indexList;
v3 = &vertices[*indexList];
++indexList;
// back face culling
if (BackFaceCullingEnabled)
{
s32 z = ((v3->Pos.X - v1->Pos.X) * (v3->Pos.Y - v2->Pos.Y)) -
((v3->Pos.Y - v1->Pos.Y) * (v3->Pos.X - v2->Pos.X));
if (z < 0)
continue;
}
//near plane clipping
if (v1->ZValue<0 && v2->ZValue<0 && v3->ZValue<0)
continue;
// sort for width for inscreen clipping
if (v1->Pos.X > v2->Pos.X) swapVertices(&v1, &v2);
if (v1->Pos.X > v3->Pos.X) swapVertices(&v1, &v3);
if (v2->Pos.X > v3->Pos.X) swapVertices(&v2, &v3);
if ((v1->Pos.X - v3->Pos.X) == 0)
continue;
TriangleRect.UpperLeftCorner.X = v1->Pos.X;
TriangleRect.LowerRightCorner.X = v3->Pos.X;
// sort for height for faster drawing.
if (v1->Pos.Y > v2->Pos.Y) swapVertices(&v1, &v2);
if (v1->Pos.Y > v3->Pos.Y) swapVertices(&v1, &v3);
if (v2->Pos.Y > v3->Pos.Y) swapVertices(&v2, &v3);
TriangleRect.UpperLeftCorner.Y = v1->Pos.Y;
TriangleRect.LowerRightCorner.Y = v3->Pos.Y;
if (!TriangleRect.isRectCollided(ViewPortRect))
continue;
// calculate height of triangle
height = v3->Pos.Y - v1->Pos.Y;
if (!height)
continue;
// calculate longest span
longest = (v2->Pos.Y - v1->Pos.Y) / (f32)height * (v3->Pos.X - v1->Pos.X) + (v1->Pos.X - v2->Pos.X);
spanEnd = v2->Pos.Y;
span = v1->Pos.Y;
leftxf = (f32)v1->Pos.X;
rightxf = (f32)v1->Pos.X;
leftZValue = v1->ZValue;
rightZValue = v1->ZValue;
leftR = rightR = video::getRed(v1->Color)<<8;
leftG = rightG = video::getGreen(v1->Color)<<8;
leftB = rightB = video::getBlue(v1->Color)<<8;
leftTx = rightTx = v1->TCoords.X;
leftTy = rightTy = v1->TCoords.Y;
targetSurface = lockedSurface + span * SurfaceWidth;
zTarget = lockedZBuffer + span * SurfaceWidth;
if (longest < 0.0f)
{
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
rightdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - rightB) * tmpDiv);
rightTxStep = (s32)((v2->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v2->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)height;
leftdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv);
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (f32)height;
rightdeltaxf = (v3->Pos.X - v1->Pos.X) * tmpDiv;
rightZStep = (s32)((v3->ZValue - v1->ZValue) * tmpDiv);
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv);
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
tmpDiv = 1.0f / (f32)(v2->Pos.Y - v1->Pos.Y);
leftdeltaxf = (v2->Pos.X - v1->Pos.X) * tmpDiv;
leftZStep = (s32)((v2->ZValue - v1->ZValue) * tmpDiv);
leftStepR = (s32)(((s32)(video::getRed(v2->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v2->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v2->Color)<<8) - leftB) * tmpDiv);
leftTxStep = (s32)((v2->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v2->TCoords.Y - leftTy) * tmpDiv);
}
// do it twice, once for the first half of the triangle,
// end then for the second half.
for (s32 triangleHalf=0; triangleHalf<2; ++triangleHalf)
{
if (spanEnd > ViewPortRect.LowerRightCorner.Y)
spanEnd = ViewPortRect.LowerRightCorner.Y;
// if the span <0, than we can skip these spans,
// and proceed to the next spans which are really on the screen.
if (span < ViewPortRect.UpperLeftCorner.Y)
{
// we'll use leftx as temp variable
if (spanEnd < ViewPortRect.UpperLeftCorner.Y)
{
leftx = spanEnd - span;
span = spanEnd;
}
else
{
leftx = ViewPortRect.UpperLeftCorner.Y - span;
span = ViewPortRect.UpperLeftCorner.Y;
}
leftxf += leftdeltaxf*leftx;
rightxf += rightdeltaxf*leftx;
targetSurface += SurfaceWidth*leftx;
zTarget += SurfaceWidth*leftx;
leftZValue += leftZStep*leftx;
rightZValue += rightZStep*leftx;
leftR += leftStepR*leftx;
leftG += leftStepG*leftx;
leftB += leftStepB*leftx;
rightR += rightStepR*leftx;
rightG += rightStepG*leftx;
rightB += rightStepB*leftx;
leftTx += leftTxStep*leftx;
leftTy += leftTyStep*leftx;
rightTx += rightTxStep*leftx;
rightTy += rightTyStep*leftx;
}
// the main loop. Go through every span and draw it.
while (span < spanEnd)
{
leftx = (s32)(leftxf);
rightx = (s32)(rightxf + 0.5f);
// perform some clipping
if (leftx>=ViewPortRect.UpperLeftCorner.X &&
leftx<=ViewPortRect.LowerRightCorner.X)
{
if (leftZValue > *(zTarget + leftx))
{
*(zTarget + leftx) = leftZValue;
color = lockedTexture[((leftTy>>8)&textureYMask) * lockedTextureWidth + ((leftTx>>8)&textureXMask)];
*(targetSurface + leftx) = video::RGB16(video::getRed(color) * (leftR>>8) >>2,
video::getGreen(color) * (leftG>>8) >>2,
video::getBlue(color) * (leftR>>8) >>2);
}
}
if (rightx>=ViewPortRect.UpperLeftCorner.X &&
rightx<=ViewPortRect.LowerRightCorner.X)
{
if (rightZValue > *(zTarget + rightx))
{
*(zTarget + rightx) = rightZValue;
color = lockedTexture[((rightTy>>8)&textureYMask) * lockedTextureWidth + ((rightTx>>8)&textureXMask)];
*(targetSurface + rightx) = video::RGB16(video::getRed(color) * (rightR>>8) >>2,
video::getGreen(color) * (rightG>>8) >>2,
video::getBlue(color) * (rightR>>8) >>2);
}
}
leftxf += leftdeltaxf;
rightxf += rightdeltaxf;
++span;
targetSurface += SurfaceWidth;
zTarget += SurfaceWidth;
leftZValue += leftZStep;
rightZValue += rightZStep;
leftR += leftStepR;
leftG += leftStepG;
leftB += leftStepB;
rightR += rightStepR;
rightG += rightStepG;
rightB += rightStepB;
leftTx += leftTxStep;
leftTy += leftTyStep;
rightTx += rightTxStep;
rightTy += rightTyStep;
}
if (triangleHalf>0) // break, we've gout only two halves
break;
// setup variables for second half of the triangle.
if (longest < 0.0f)
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
rightdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
rightxf = (f32)v2->Pos.X;
rightZValue = v2->ZValue;
rightZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
rightR = video::getRed(v2->Color)<<8;
rightG = video::getGreen(v2->Color)<<8;
rightB = video::getBlue(v2->Color)<<8;
rightStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - rightR) * tmpDiv);
rightStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - rightG) * tmpDiv);
rightStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - rightB) * tmpDiv);
rightTx = v2->TCoords.X;
rightTy = v2->TCoords.Y;
rightTxStep = (s32)((v3->TCoords.X - rightTx) * tmpDiv);
rightTyStep = (s32)((v3->TCoords.Y - rightTy) * tmpDiv);
}
else
{
tmpDiv = 1.0f / (v3->Pos.Y - v2->Pos.Y);
leftdeltaxf = (v3->Pos.X - v2->Pos.X) * tmpDiv;
leftxf = (f32)v2->Pos.X;
leftZValue = v2->ZValue;
leftZStep = (s32)((v3->ZValue - v2->ZValue) * tmpDiv);
leftR = video::getRed(v2->Color)<<8;
leftG = video::getGreen(v2->Color)<<8;
leftB = video::getBlue(v2->Color)<<8;
leftStepR = (s32)(((s32)(video::getRed(v3->Color)<<8) - leftR) * tmpDiv);
leftStepG = (s32)(((s32)(video::getGreen(v3->Color)<<8) - leftG) * tmpDiv);
leftStepB = (s32)(((s32)(video::getBlue(v3->Color)<<8) - leftB) * tmpDiv);
leftTx = v2->TCoords.X;
leftTy = v2->TCoords.Y;
leftTxStep = (s32)((v3->TCoords.X - leftTx) * tmpDiv);
leftTyStep = (s32)((v3->TCoords.Y - leftTy) * tmpDiv);
}
spanEnd = v3->Pos.Y;
}
}
RenderTarget->unlock();
ZBuffer->unlock();
Texture->unlock();
}
};
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_SOFTWARE_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
ITriangleRenderer* createTriangleRendererTextureGouraudWire(IZBuffer* zbuffer)
{
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
return new CTRTextureGouraudWire(zbuffer);
#else
return 0;
#endif // _IRR_COMPILE_WITH_SOFTWARE_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,672 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
//#define IPOL_C0
#define IPOL_T0
#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureLightMap2_Add : public IBurningShader
{
public:
//! constructor
CTRTextureLightMap2_Add(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRTextureLightMap2_Add::CTRTextureLightMap2_Add(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureLightMap2_Add");
#endif
}
/*!
*/
REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[1] - line.c[0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
u32 dIndex = ( line.y & 3 ) << 2;
#else
//
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#endif
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
#ifdef INVERSE_W
const f32 inversew = fix_inverse32 ( line.w[0] );
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
dst[i] = PixelAdd32 (
getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
d + tofix ( line.t[0][0].y,inversew) ),
getTexel_plain ( &IT[1], d + tofix ( line.t[1][0].x,inversew),
d + tofix ( line.t[1][0].y,inversew) )
);
#else
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
dst[i] = PixelAdd32 (
getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x),
d + tofix ( line.t[0][0].y) ),
getTexel_plain ( &IT[1], d + tofix ( line.t[1][0].x),
d + tofix ( line.t[1][0].y) )
);
#endif
#else
const f32 inversew = fix_inverse32 ( line.w[0] );
getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[0][1].x,inversew), tofix ( line.t[0][1].y,inversew) );
dst[i] = fix_to_color ( clampfix_maxcolor ( r0 + r1 ),
clampfix_maxcolor ( g0 + g1 ),
clampfix_maxcolor ( b0 + b1 )
);
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureLightMap2_Add(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureLightMap2_Add(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,644 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
//#define IPOL_C0
#define IPOL_T0
#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureLightMap2_M1 : public IBurningShader
{
public:
//! constructor
CTRTextureLightMap2_M1(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear2 ();
sScanLineData line;
};
//! constructor
CTRTextureLightMap2_M1::CTRTextureLightMap2_M1(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureLightMap2_M1");
#endif
}
/*!
*/
REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
{
tVideoSample *dst;
fp24 *z;
s32 xStart;
s32 xEnd;
s32 dx;
s32 i;
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
// subTexel
const f32 subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_W
const f32 b = (line.w[1] - line.w[0]) * invDeltaX;
f32 a = line.w[0] + ( b * subPixel );
i = 0;
while ( a <= z[i] )
{
a += b;
i += 1;
if ( i > dx )
return;
}
// lazy setup rest of scanline
line.w[0] = a;
line.w[1] = b;
#else
const f32 b = (line.z[1] - line.z[0]) * invDeltaX;
f32 a = line.z[0] + ( b * subPixel );
i = 0;
while ( a > z[i] )
{
a += b;
i += 1;
if ( i > dx )
return;
}
// lazy setup rest of scanline
line.z[0] = a;
line.z[1] = b;
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
a = (f32) i + subPixel;
line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
line.t[0][0] += line.t[0][1] * a;
line.t[1][0] += line.t[1][1] * a;
#ifdef BURNINGVIDEO_RENDERER_FAST
u32 dIndex = ( line.y & 3 ) << 2;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#else
//
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#endif
for ( ;i <= dx; i++ )
{
#ifdef IPOL_W
if ( line.w[0] >= z[i] )
{
z[i] = line.w[0];
#else
if ( line.z[0] < z[i] )
{
z[i] = line.z[0];
#endif
#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
f32 inversew = fix_inverse32 ( line.w[0] );
#else
f32 inversew = FIX_POINT_F32_MUL;
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
getSample_texture ( r0, g0, b0, &IT[0], d + tofix ( line.t[0][0].x,inversew), d + tofix ( line.t[0][0].y,inversew) );
getSample_texture ( r1, g1, b1, &IT[1], d + tofix ( line.t[1][0].x,inversew), d + tofix ( line.t[1][0].y,inversew) );
#else
getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
#endif
dst[i] = fix_to_color ( imulFix_tex1 ( r0, r1 ),
imulFix_tex1 ( g0, g1 ),
imulFix_tex1 ( b0, b1 )
);
}
#ifdef IPOL_W
line.w[0] += line.w[1];
#else
line.z[0] += line.z[1];
#endif
line.t[0][0] += line.t[0][1];
line.t[1][0] += line.t[1][1];
}
}
void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
sScanConvertData scan;
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear2 ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear2 ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureLightMap2_M1(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,644 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
//#define IPOL_C0
#define IPOL_T0
#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureLightMap2_M2 : public IBurningShader
{
public:
//! constructor
CTRTextureLightMap2_M2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear2 ();
sScanLineData line;
};
//! constructor
CTRTextureLightMap2_M2::CTRTextureLightMap2_M2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureLightMap2_M2");
#endif
}
/*!
*/
REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
{
tVideoSample *dst;
fp24 *z;
s32 xStart;
s32 xEnd;
s32 dx;
s32 i;
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
// subTexel
const f32 subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_W
const f32 b = (line.w[1] - line.w[0]) * invDeltaX;
f32 a = line.w[0] + ( b * subPixel );
i = 0;
while ( a <= z[i] )
{
a += b;
i += 1;
if ( i > dx )
return;
}
// lazy setup rest of scanline
line.w[0] = a;
line.w[1] = b;
#else
const f32 b = (line.z[1] - line.z[0]) * invDeltaX;
f32 a = line.z[0] + ( b * subPixel );
i = 0;
while ( a > z[i] )
{
a += b;
i += 1;
if ( i > dx )
return;
}
// lazy setup rest of scanline
line.z[0] = a;
line.z[1] = b;
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
a = (f32) i + subPixel;
line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
line.t[0][0] += line.t[0][1] * a;
line.t[1][0] += line.t[1][1] * a;
#ifdef BURNINGVIDEO_RENDERER_FAST
u32 dIndex = ( line.y & 3 ) << 2;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#else
//
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#endif
for ( ;i <= dx; i++ )
{
#ifdef IPOL_W
if ( line.w[0] >= z[i] )
{
z[i] = line.w[0];
#else
if ( line.z[0] < z[i] )
{
z[i] = line.z[0];
#endif
#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
f32 inversew = fix_inverse32 ( line.w[0] );
#else
f32 inversew = FIX_POINT_F32_MUL;
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
getSample_texture ( r0, g0, b0, &IT[0], d + tofix ( line.t[0][0].x,inversew), d + tofix ( line.t[0][0].y,inversew) );
getSample_texture ( r1, g1, b1, &IT[1], d + tofix ( line.t[1][0].x,inversew), d + tofix ( line.t[1][0].y,inversew) );
#else
getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
#endif
dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
}
#ifdef IPOL_W
line.w[0] += line.w[1];
#else
line.z[0] += line.z[1];
#endif
line.t[0][0] += line.t[0][1];
line.t[1][0] += line.t[1][1];
}
}
void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
sScanConvertData scan;
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear2 ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear2 ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureLightMap2_M2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureLightMap2_M2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

File diff suppressed because it is too large Load Diff

View File

@@ -1,690 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
#define IPOL_C0
#define IPOL_T0
#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRGTextureLightMap2_M4 : public IBurningShader
{
public:
//! constructor
CTRGTextureLightMap2_M4(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
CTRGTextureLightMap2_M4::CTRGTextureLightMap2_M4(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRGTextureLightMap2_M4");
#endif
}
/*!
*/
void CTRGTextureLightMap2_M4::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
#endif
tFixPoint tx0, tx1;
tFixPoint ty0, ty1;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#ifdef IPOL_C0
tFixPoint r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
#endif
{
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
tx1 = tofix ( line.t[1][0].x,inversew);
ty1 = tofix ( line.t[1][0].y,inversew);
#ifdef IPOL_C0
r3 = tofix ( line.c[0][0].y ,inversew );
g3 = tofix ( line.c[0][0].z ,inversew );
b3 = tofix ( line.c[0][0].w ,inversew );
#endif
#else
tx0 = tofix ( line.t[0][0].x );
ty0 = tofix ( line.t[0][0].y );
tx1 = tofix ( line.t[1][0].x );
ty1 = tofix ( line.t[1][0].y );
#ifdef IPOL_C0
r3 = tofix ( line.c[0][0].y );
g3 = tofix ( line.c[0][0].z );
b3 = tofix ( line.c[0][0].w );
#endif
#endif
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );
#ifdef IPOL_C0
r2 = imulFix ( r0, r3 );
g2 = imulFix ( g0, g3 );
b2 = imulFix ( b0, b3 );
r2 = clampfix_maxcolor ( imulFix_tex4 ( r2, r1 ) );
g2 = clampfix_maxcolor ( imulFix_tex4 ( g2, g1 ) );
b2 = clampfix_maxcolor ( imulFix_tex4 ( b2, b1 ) );
/*
r2 = r3 << 8;
g2 = g3 << 8;
b2 = b3 << 8;
*/
#else
r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );
g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );
b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );
#endif
dst[i] = fix_to_color ( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
//if( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererGTextureLightMap2_M4(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGTextureLightMap2_M4(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,298 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
//#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRTextureWire2 : public IBurningShader
{
public:
//! constructor
CTRTextureWire2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
virtual void drawLine ( const s4DVertex *a,const s4DVertex *b);
private:
void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const;
void renderLine ( const s4DVertex *a,const s4DVertex *b ) const;
};
//! constructor
CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRTextureWire2");
#endif
}
// swap integer with xor
static inline void swap_xor ( s32 &a, s32 &b )
{
a ^= b;
b ^= a;
a ^= b;
}
/*!
*/
void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
{
int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY;
int pitch1 = RenderTarget->getDimension().Width << 2;
int aposx = (int) a->Pos.x;
int aposy = (int) a->Pos.y;
int bposx = (int) b->Pos.x;
int bposy = (int) b->Pos.y;
int dx = bposx - aposx;
int dy = bposy - aposy;
int c;
int m;
int d = 0;
int run;
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY;
int yInc0 = pitch0;
int xInc1 = 4;
int yInc1 = pitch1;
tVideoSample color;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
tFixPoint r0, g0, b0;
getSample_color ( r0, g0, b0, a->Color[0] );
color = fix_to_color ( r0, g0, b0 );
#else
color = (tVideoSample) 0xFFFFFFFF;
#endif
if ( dx < 0 )
{
xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY);
xInc1 = -4;
dx = -dx;
}
if ( dy > dx )
{
swap_xor ( dx, dy );
swap_xor ( xInc0, yInc0 );
swap_xor ( xInc1, yInc1 );
}
if ( 0 == dx )
return;
dst = (tVideoSample*) ( (u8*) (tVideoSample*)RenderTarget->lock() + ( aposy * pitch0 ) + (aposx << VIDEO_SAMPLE_GRANULARITY ) );
#ifdef USE_ZBUFFER
z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) );
#endif
c = dx << 1;
m = dy << 1;
#ifdef IPOL_Z
f32 slopeZ = (b->Pos.z - a->Pos.z) / f32(dx);
f32 dataZ = a->Pos.z;
#endif
#ifdef IPOL_W
fp24 slopeW = (b->Pos.w - a->Pos.w) / f32( dx );
fp24 dataW = a->Pos.w;
#endif
run = dx;
while ( run )
{
#ifdef CMP_Z
if ( *z >= dataZ )
#endif
#ifdef CMP_W
if ( dataW >= *z )
#endif
{
#ifdef WRITE_Z
*z = dataZ;
#endif
#ifdef WRITE_W
*z = dataW;
#endif
*dst = color;
}
dst = (tVideoSample*) ( (u8*) dst + xInc0 ); // x += xInc
#ifdef IPOL_Z
z = (fp24*) ( (u8*) z + xInc1 );
#endif
#ifdef IPOL_W
z = (fp24*) ( (u8*) z + xInc1 );
#endif
d += m;
if ( d > dx )
{
dst = (tVideoSample*) ( (u8*) dst + yInc0 ); // y += yInc
#ifdef IPOL_Z
z = (fp24*) ( (u8*) z + yInc1 );
#endif
#ifdef IPOL_W
z = (fp24*) ( (u8*) z + yInc1 );
#endif
d -= c;
}
run -= 1;
#ifdef IPOL_Z
dataZ += slopeZ;
#endif
#ifdef IPOL_W
dataW += slopeW;
#endif
}
}
void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
sScanLineData line;
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
renderLine ( a, b );
renderLine ( b, c );
renderLine ( a, c );
}
void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b)
{
// query access to TexMaps
// sort on height, y
if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
renderLine ( a, b );
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureWire2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@@ -1,120 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
#include "SoftwareDriver2_compile_config.h"
#include "IBurningShader.h"
#include "CSoftwareDriver2.h"
namespace irr
{
namespace video
{
const tFixPointu IBurningShader::dithermask[] =
{
0x00,0x80,0x20,0xa0,
0xc0,0x40,0xe0,0x60,
0x30,0xb0,0x10,0x90,
0xf0,0x70,0xd0,0x50
};
IBurningShader::IBurningShader(CBurningVideoDriver* driver)
{
#ifdef _DEBUG
setDebugName("IBurningShader");
#endif
for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
{
IT[i].Texture = 0;
}
Driver = driver;
RenderTarget = 0;
ColorMask = COLOR_BRIGHT_WHITE;
DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();
if ( DepthBuffer )
DepthBuffer->grab();
Stencil = (CStencilBuffer*) driver->getStencilBuffer ();
if ( Stencil )
Stencil->grab();
}
//! destructor
IBurningShader::~IBurningShader()
{
if (RenderTarget)
RenderTarget->drop();
if (DepthBuffer)
DepthBuffer->drop();
if (Stencil)
Stencil->drop();
for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
{
if ( IT[i].Texture )
IT[i].Texture->drop();
}
}
//! sets a render target
void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)
{
if (RenderTarget)
RenderTarget->drop();
RenderTarget = (video::CImage* ) surface;
if (RenderTarget)
{
RenderTarget->grab();
//(tVideoSample*)RenderTarget->lock() = (tVideoSample*)RenderTarget->lock();
//(fp24*) DepthBuffer->lock() = DepthBuffer->lock();
}
}
//! sets the Texture
void IBurningShader::setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel)
{
sInternalTexture *it = &IT[stage];
if ( it->Texture)
it->Texture->drop();
it->Texture = texture;
if ( it->Texture)
{
it->Texture->grab();
// select mignify and magnify ( lodLevel )
//SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS
it->lodLevel = lodLevel;
it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY,
core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 ));
// prepare for optimal fixpoint
it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );
const core::dimension2d<u32> &dim = it->Texture->getSize();
it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;
it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_

View File

@@ -1,201 +0,0 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_BURNING_SHADER_H_INCLUDED__
#define __I_BURNING_SHADER_H_INCLUDED__
#include "SoftwareDriver2_compile_config.h"
#include "IReferenceCounted.h"
#include "irrMath.h"
#include "IImage.h"
#include "S2DVertex.h"
#include "rect.h"
#include "CDepthBuffer.h"
#include "S4DVertex.h"
#include "irrArray.h"
#include "SLight.h"
#include "SMaterial.h"
#include "os.h"
namespace irr
{
namespace video
{
struct SBurningShaderLight
{
//SLight org;
bool LightIsOn;
E_LIGHT_TYPE Type;
f32 radius;
f32 linearAttenuation;
f32 constantAttenuation;
f32 quadraticAttenuation;
sVec4 pos;
sVec3 AmbientColor;
sVec3 DiffuseColor;
sVec3 SpecularColor;
sVec4 pos_objectspace;
};
enum eLightFlags
{
ENABLED = 0x01,
POINTLIGHT = 0x02,
SPECULAR = 0x04,
FOG = 0x08,
NORMALIZE = 0x10,
VERTEXTRANSFORM = 0x20,
};
struct SBurningShaderLightSpace
{
void reset ()
{
Light.set_used ( 0 );
Global_AmbientLight.set ( 0.f, 0.f, 0.f );
Flags = 0;
}
core::array<SBurningShaderLight> Light;
sVec3 Global_AmbientLight;
sVec4 FogColor;
sVec4 campos;
sVec4 vertex;
sVec4 normal;
u32 Flags;
};
struct SBurningShaderMaterial
{
SMaterial org;
sVec3 AmbientColor;
sVec3 DiffuseColor;
sVec3 SpecularColor;
sVec3 EmissiveColor;
};
enum EBurningFFShader
{
ETR_FLAT = 0,
ETR_FLAT_WIRE,
ETR_GOURAUD,
ETR_GOURAUD_WIRE,
ETR_TEXTURE_FLAT,
ETR_TEXTURE_FLAT_WIRE,
ETR_TEXTURE_GOURAUD,
ETR_TEXTURE_GOURAUD_WIRE,
ETR_TEXTURE_GOURAUD_NOZ,
ETR_TEXTURE_GOURAUD_ADD,
ETR_TEXTURE_GOURAUD_ADD_NO_Z,
ETR_TEXTURE_GOURAUD_VERTEX_ALPHA,
ETR_TEXTURE_GOURAUD_LIGHTMAP_M1,
ETR_TEXTURE_GOURAUD_LIGHTMAP_M2,
ETR_TEXTURE_GOURAUD_LIGHTMAP_M4,
ETR_TEXTURE_LIGHTMAP_M4,
ETR_TEXTURE_GOURAUD_DETAIL_MAP,
ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD,
ETR_GOURAUD_ALPHA,
ETR_GOURAUD_ALPHA_NOZ,
ETR_TEXTURE_GOURAUD_ALPHA,
ETR_TEXTURE_GOURAUD_ALPHA_NOZ,
ETR_NORMAL_MAP_SOLID,
ETR_STENCIL_SHADOW,
ETR_TEXTURE_BLEND,
ETR_REFERENCE,
ETR_INVALID,
ETR2_COUNT
};
class CBurningVideoDriver;
class IBurningShader : public virtual IReferenceCounted
{
public:
IBurningShader(CBurningVideoDriver* driver);
//! destructor
virtual ~IBurningShader();
//! sets a render target
virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort);
//! sets the Texture
virtual void setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel);
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) = 0;
virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) {};
virtual void setParam ( u32 index, f32 value) {};
virtual void setZCompareFunc ( u32 func) {};
virtual void setMaterial ( const SBurningShaderMaterial &material ) {};
protected:
CBurningVideoDriver *Driver;
video::CImage* RenderTarget;
CDepthBuffer* DepthBuffer;
CStencilBuffer * Stencil;
tVideoSample ColorMask;
sInternalTexture IT[ BURNING_MATERIAL_MAX_TEXTURES ];
static const tFixPointu dithermask[ 4 * 4];
};
IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGTextureLightMap2_M4(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_Add(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureDetailMap2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureFlat2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureFlatWire2(CBurningVideoDriver* driver);
IBurningShader* createTRFlat2(CBurningVideoDriver* driver);
IBurningShader* createTRFlatWire2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);
IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver);
IBurningShader* createTRTextureInverseAlphaBlend(CBurningVideoDriver* driver);
IBurningShader* createTRNormalMap(CBurningVideoDriver* driver);
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver);
} // end namespace video
} // end namespace irr
#endif