Remove software renderer
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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_
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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_
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user