Remove more unused code (#87)
This commit is contained in:
		@@ -1,133 +0,0 @@
 | 
			
		||||
// Copyright (C) 2008-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_DYNAMIC_MESHBUFFER_H_INCLUDED__
 | 
			
		||||
#define __C_DYNAMIC_MESHBUFFER_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "IDynamicMeshBuffer.h"
 | 
			
		||||
 | 
			
		||||
#include "CVertexBuffer.h"
 | 
			
		||||
#include "CIndexBuffer.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace scene
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	class CDynamicMeshBuffer: public IDynamicMeshBuffer
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		//! constructor
 | 
			
		||||
		CDynamicMeshBuffer(video::E_VERTEX_TYPE vertexType, video::E_INDEX_TYPE indexType)
 | 
			
		||||
		: PrimitiveType(EPT_TRIANGLES)
 | 
			
		||||
		{
 | 
			
		||||
			VertexBuffer=new CVertexBuffer(vertexType);
 | 
			
		||||
			IndexBuffer=new CIndexBuffer(indexType);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! destructor
 | 
			
		||||
		virtual ~CDynamicMeshBuffer()
 | 
			
		||||
		{
 | 
			
		||||
			if (VertexBuffer)
 | 
			
		||||
				VertexBuffer->drop();
 | 
			
		||||
			if (IndexBuffer)
 | 
			
		||||
				IndexBuffer->drop();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual IVertexBuffer& getVertexBuffer() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return *VertexBuffer;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual IIndexBuffer& getIndexBuffer() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return *IndexBuffer;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void setVertexBuffer(IVertexBuffer *newVertexBuffer) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (newVertexBuffer)
 | 
			
		||||
				newVertexBuffer->grab();
 | 
			
		||||
			if (VertexBuffer)
 | 
			
		||||
				VertexBuffer->drop();
 | 
			
		||||
 | 
			
		||||
			VertexBuffer=newVertexBuffer;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual void setIndexBuffer(IIndexBuffer *newIndexBuffer) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (newIndexBuffer)
 | 
			
		||||
				newIndexBuffer->grab();
 | 
			
		||||
			if (IndexBuffer)
 | 
			
		||||
				IndexBuffer->drop();
 | 
			
		||||
 | 
			
		||||
			IndexBuffer=newIndexBuffer;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get Material of this buffer.
 | 
			
		||||
		virtual const video::SMaterial& getMaterial() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return Material;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get Material of this buffer.
 | 
			
		||||
		virtual video::SMaterial& getMaterial() _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return Material;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get bounding box
 | 
			
		||||
		virtual const core::aabbox3d<f32>& getBoundingBox() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return BoundingBox;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Set bounding box
 | 
			
		||||
		virtual void setBoundingBox( const core::aabbox3df& box) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			BoundingBox = box;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Recalculate bounding box
 | 
			
		||||
		virtual void recalculateBoundingBox() _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (!getVertexBuffer().size())
 | 
			
		||||
				BoundingBox.reset(0,0,0);
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				BoundingBox.reset(getVertexBuffer()[0].Pos);
 | 
			
		||||
				for (u32 i=1; i<getVertexBuffer().size(); ++i)
 | 
			
		||||
					BoundingBox.addInternalPoint(getVertexBuffer()[i].Pos);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Describe what kind of primitive geometry is used by the meshbuffer
 | 
			
		||||
		virtual void setPrimitiveType(E_PRIMITIVE_TYPE type) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			PrimitiveType = type;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get the kind of primitive geometry which is used by the meshbuffer
 | 
			
		||||
		virtual E_PRIMITIVE_TYPE getPrimitiveType() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return PrimitiveType;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		video::SMaterial Material;
 | 
			
		||||
		core::aabbox3d<f32> BoundingBox;
 | 
			
		||||
		//! Primitive type used for rendering (triangles, lines, ...)
 | 
			
		||||
		E_PRIMITIVE_TYPE PrimitiveType;
 | 
			
		||||
	private:
 | 
			
		||||
		CDynamicMeshBuffer(const CDynamicMeshBuffer&); // = delete in c++11, prevent copying
 | 
			
		||||
 | 
			
		||||
		IVertexBuffer *VertexBuffer;
 | 
			
		||||
		IIndexBuffer *IndexBuffer;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace scene
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -121,71 +121,6 @@ namespace video
 | 
			
		||||
		texture which will not reflect can be set as second texture.*/
 | 
			
		||||
		EMT_TRANSPARENT_REFLECTION_2_LAYER,
 | 
			
		||||
 | 
			
		||||
		//! A solid normal map renderer.
 | 
			
		||||
		/** First texture is the color map, the second should be the
 | 
			
		||||
		normal map. Note that you should use this material only when
 | 
			
		||||
		drawing geometry consisting of vertices of type
 | 
			
		||||
		S3DVertexTangents (EVT_TANGENTS). You can convert any mesh into
 | 
			
		||||
		this format using IMeshManipulator::createMeshWithTangents()
 | 
			
		||||
		(See SpecialFX2 Tutorial). This shader runs on vertex shader
 | 
			
		||||
		1.1 and pixel shader 1.1 capable hardware and falls back to a
 | 
			
		||||
		fixed function lighted material if this hardware is not
 | 
			
		||||
		available. Only two lights are supported by this shader, if
 | 
			
		||||
		there are more, the nearest two are chosen. */
 | 
			
		||||
		EMT_NORMAL_MAP_SOLID,
 | 
			
		||||
 | 
			
		||||
		//! A transparent normal map renderer.
 | 
			
		||||
		/** First texture is the color map, the second should be the
 | 
			
		||||
		normal map. Note that you should use this material only when
 | 
			
		||||
		drawing geometry consisting of vertices of type
 | 
			
		||||
		S3DVertexTangents (EVT_TANGENTS). You can convert any mesh into
 | 
			
		||||
		this format using IMeshManipulator::createMeshWithTangents()
 | 
			
		||||
		(See SpecialFX2 Tutorial). This shader runs on vertex shader
 | 
			
		||||
		1.1 and pixel shader 1.1 capable hardware and falls back to a
 | 
			
		||||
		fixed function lighted material if this hardware is not
 | 
			
		||||
		available. Only two lights are supported by this shader, if
 | 
			
		||||
		there are more, the nearest two are chosen. */
 | 
			
		||||
		EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR,
 | 
			
		||||
 | 
			
		||||
		//! A transparent (based on the vertex alpha value) normal map renderer.
 | 
			
		||||
		/** First texture is the color map, the second should be the
 | 
			
		||||
		normal map. Note that you should use this material only when
 | 
			
		||||
		drawing geometry consisting of vertices of type
 | 
			
		||||
		S3DVertexTangents (EVT_TANGENTS). You can convert any mesh into
 | 
			
		||||
		this format using IMeshManipulator::createMeshWithTangents()
 | 
			
		||||
		(See SpecialFX2 Tutorial). This shader runs on vertex shader
 | 
			
		||||
		1.1 and pixel shader 1.1 capable hardware and falls back to a
 | 
			
		||||
		fixed function lighted material if this hardware is not
 | 
			
		||||
		available.  Only two lights are supported by this shader, if
 | 
			
		||||
		there are more, the nearest two are chosen. */
 | 
			
		||||
		EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA,
 | 
			
		||||
 | 
			
		||||
		//! Just like EMT_NORMAL_MAP_SOLID, but uses parallax mapping.
 | 
			
		||||
		/** Looks a lot more realistic. This only works when the
 | 
			
		||||
		hardware supports at least vertex shader 1.1 and pixel shader
 | 
			
		||||
		1.4. First texture is the color map, the second should be the
 | 
			
		||||
		normal map. The normal map texture should contain the height
 | 
			
		||||
		value in the alpha component. The
 | 
			
		||||
		IVideoDriver::makeNormalMapTexture() method writes this value
 | 
			
		||||
		automatically when creating normal maps from a heightmap when
 | 
			
		||||
		using a 32 bit texture. The height scale of the material
 | 
			
		||||
		(affecting the bumpiness) is being controlled by the
 | 
			
		||||
		SMaterial::MaterialTypeParam member. If set to zero, the
 | 
			
		||||
		default value (0.02f) will be applied. Otherwise the value set
 | 
			
		||||
		in SMaterial::MaterialTypeParam is taken. This value depends on
 | 
			
		||||
		with which scale the texture is mapped on the material. Too
 | 
			
		||||
		high or low values of MaterialTypeParam can result in strange
 | 
			
		||||
		artifacts. */
 | 
			
		||||
		EMT_PARALLAX_MAP_SOLID,
 | 
			
		||||
 | 
			
		||||
		//! A material like EMT_PARALLAX_MAP_SOLID, but transparent.
 | 
			
		||||
		/** Using EMT_TRANSPARENT_ADD_COLOR as base material. */
 | 
			
		||||
		EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR,
 | 
			
		||||
 | 
			
		||||
		//! A material like EMT_PARALLAX_MAP_SOLID, but transparent.
 | 
			
		||||
		/** Using EMT_TRANSPARENT_VERTEX_ALPHA as base material. */
 | 
			
		||||
		EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA,
 | 
			
		||||
 | 
			
		||||
		//! BlendFunc = source * sourceFactor + dest * destFactor ( E_BLEND_FUNC )
 | 
			
		||||
		/** Using only first texture. Generic blending method. 
 | 
			
		||||
		The blend function is set to SMaterial::MaterialTypeParam with 
 | 
			
		||||
@@ -216,12 +151,6 @@ namespace video
 | 
			
		||||
		"trans_alphach_ref",
 | 
			
		||||
		"trans_vertex_alpha",
 | 
			
		||||
		"trans_reflection_2layer",
 | 
			
		||||
		"normalmap_solid",
 | 
			
		||||
		"normalmap_trans_add",
 | 
			
		||||
		"normalmap_trans_vertexalpha",
 | 
			
		||||
		"parallaxmap_solid",
 | 
			
		||||
		"parallaxmap_trans_add",
 | 
			
		||||
		"parallaxmap_trans_vertexalpha",
 | 
			
		||||
		"onetexture_blend",
 | 
			
		||||
		0
 | 
			
		||||
	};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,36 +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 __E_TERRAIN_ELEMENTS_H__
 | 
			
		||||
#define __E_TERRAIN_ELEMENTS_H__
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace scene
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	//! enumeration for patch sizes specifying the size of patches in the TerrainSceneNode
 | 
			
		||||
	enum E_TERRAIN_PATCH_SIZE
 | 
			
		||||
	{
 | 
			
		||||
		//! patch size of 9, at most, use 4 levels of detail with this patch size.
 | 
			
		||||
		ETPS_9 = 9,
 | 
			
		||||
 | 
			
		||||
		//! patch size of 17, at most, use 5 levels of detail with this patch size.
 | 
			
		||||
		ETPS_17 = 17,
 | 
			
		||||
 | 
			
		||||
		//! patch size of 33, at most, use 6 levels of detail with this patch size.
 | 
			
		||||
		ETPS_33 = 33,
 | 
			
		||||
 | 
			
		||||
		//! patch size of 65, at most, use 7 levels of detail with this patch size.
 | 
			
		||||
		ETPS_65 = 65,
 | 
			
		||||
 | 
			
		||||
		//! patch size of 129, at most, use 8 levels of detail with this patch size.
 | 
			
		||||
		ETPS_129 = 129
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
} // end namespace scene
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,211 +0,0 @@
 | 
			
		||||
// Copyright (C) 2008-2012 Nikolaus Gebhardt
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
 | 
			
		||||
 | 
			
		||||
#ifndef __I_DYNAMIC_MESH_BUFFER_H_INCLUDED__
 | 
			
		||||
#define __I_DYNAMIC_MESH_BUFFER_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "IMeshBuffer.h"
 | 
			
		||||
#include "IVertexBuffer.h"
 | 
			
		||||
#include "IIndexBuffer.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace scene
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	/** a dynamic meshBuffer */
 | 
			
		||||
	class IDynamicMeshBuffer : public IMeshBuffer
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		virtual IVertexBuffer &getVertexBuffer() const =0;
 | 
			
		||||
		virtual IIndexBuffer &getIndexBuffer() const =0;
 | 
			
		||||
 | 
			
		||||
		virtual void setVertexBuffer(IVertexBuffer *vertexBuffer) =0;
 | 
			
		||||
		virtual void setIndexBuffer(IIndexBuffer *indexBuffer) =0;
 | 
			
		||||
 | 
			
		||||
		//! Get the material of this meshbuffer
 | 
			
		||||
		/** \return Material of this buffer. */
 | 
			
		||||
		virtual video::SMaterial& getMaterial() _IRR_OVERRIDE_ =0;
 | 
			
		||||
 | 
			
		||||
		//! Get the material of this meshbuffer
 | 
			
		||||
		/** \return Material of this buffer. */
 | 
			
		||||
		virtual const video::SMaterial& getMaterial() const _IRR_OVERRIDE_ =0;
 | 
			
		||||
 | 
			
		||||
		//! Get the axis aligned bounding box of this meshbuffer.
 | 
			
		||||
		/** \return Axis aligned bounding box of this buffer. */
 | 
			
		||||
		virtual const core::aabbox3df& getBoundingBox() const _IRR_OVERRIDE_ =0;
 | 
			
		||||
 | 
			
		||||
		//! Set axis aligned bounding box
 | 
			
		||||
		/** \param box User defined axis aligned bounding box to use
 | 
			
		||||
		for this buffer. */
 | 
			
		||||
		virtual void setBoundingBox(const core::aabbox3df& box) _IRR_OVERRIDE_ =0;
 | 
			
		||||
 | 
			
		||||
		//! Recalculates the bounding box. Should be called if the mesh changed.
 | 
			
		||||
		virtual void recalculateBoundingBox() _IRR_OVERRIDE_ =0;
 | 
			
		||||
 | 
			
		||||
		//! Append the vertices and indices to the current buffer
 | 
			
		||||
		/** Only works for compatible vertex types.
 | 
			
		||||
		\param vertices Pointer to a vertex array.
 | 
			
		||||
		\param numVertices Number of vertices in the array.
 | 
			
		||||
		\param indices Pointer to index array.
 | 
			
		||||
		\param numIndices Number of indices in array. */
 | 
			
		||||
		virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Append the meshbuffer to the current buffer
 | 
			
		||||
		/** Only works for compatible vertex types
 | 
			
		||||
		\param other Buffer to append to this one. */
 | 
			
		||||
		virtual void append(const IMeshBuffer* const other) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// ------------------- To be removed? -------------------  //
 | 
			
		||||
 | 
			
		||||
		//! get the current hardware mapping hint
 | 
			
		||||
		virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer().getHardwareMappingHint();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! get the current hardware mapping hint
 | 
			
		||||
		virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getIndexBuffer().getHardwareMappingHint();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! set the hardware mapping hint, for driver
 | 
			
		||||
		virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX ) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_VERTEX)
 | 
			
		||||
				getVertexBuffer().setHardwareMappingHint(NewMappingHint);
 | 
			
		||||
			if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX)
 | 
			
		||||
				getIndexBuffer().setHardwareMappingHint(NewMappingHint);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! flags the mesh as changed, reloads hardware buffers
 | 
			
		||||
		virtual void setDirty(E_BUFFER_TYPE Buffer=EBT_VERTEX_AND_INDEX) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_VERTEX)
 | 
			
		||||
				getVertexBuffer().setDirty();
 | 
			
		||||
			if (Buffer==EBT_VERTEX_AND_INDEX || Buffer==EBT_INDEX)
 | 
			
		||||
				getIndexBuffer().setDirty();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual u32 getChangedID_Vertex() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer().getChangedID();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		virtual u32 getChangedID_Index() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getIndexBuffer().getChangedID();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// ------------------- Old interface -------------------  //
 | 
			
		||||
 | 
			
		||||
		//! Get type of vertex data which is stored in this meshbuffer.
 | 
			
		||||
		/** \return Vertex type of this buffer. */
 | 
			
		||||
		virtual video::E_VERTEX_TYPE getVertexType() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer().getType();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get access to vertex data. The data is an array of vertices.
 | 
			
		||||
		/** Which vertex type is used can be determined by getVertexType().
 | 
			
		||||
		\return Pointer to array of vertices. */
 | 
			
		||||
		virtual const void* getVertices() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer().getData();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get access to vertex data. The data is an array of vertices.
 | 
			
		||||
		/** Which vertex type is used can be determined by getVertexType().
 | 
			
		||||
		\return Pointer to array of vertices. */
 | 
			
		||||
		virtual void* getVertices() _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer().getData();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get amount of vertices in meshbuffer.
 | 
			
		||||
		/** \return Number of vertices in this buffer. */
 | 
			
		||||
		virtual u32 getVertexCount() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer().size();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get type of index data which is stored in this meshbuffer.
 | 
			
		||||
		/** \return Index type of this buffer. */
 | 
			
		||||
		virtual video::E_INDEX_TYPE getIndexType() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getIndexBuffer().getType();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get access to indices.
 | 
			
		||||
		/** \return Pointer to indices array. */
 | 
			
		||||
		virtual const u16* getIndices() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return (u16*)getIndexBuffer().getData();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get access to indices.
 | 
			
		||||
		/** \return Pointer to indices array. */
 | 
			
		||||
		virtual u16* getIndices() _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return (u16*)getIndexBuffer().getData();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get amount of indices in this meshbuffer.
 | 
			
		||||
		/** \return Number of indices in this buffer. */
 | 
			
		||||
		virtual u32 getIndexCount() const _IRR_OVERRIDE_
 | 
			
		||||
		{ 
 | 
			
		||||
			return getIndexBuffer().size();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns position of vertex i
 | 
			
		||||
		virtual const core::vector3df& getPosition(u32 i) const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer()[i].Pos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns position of vertex i
 | 
			
		||||
		virtual core::vector3df& getPosition(u32 i) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer()[i].Pos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns texture coords of vertex i
 | 
			
		||||
		virtual const core::vector2df& getTCoords(u32 i) const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer()[i].TCoords;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns texture coords of vertex i
 | 
			
		||||
		virtual core::vector2df& getTCoords(u32 i) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer()[i].TCoords;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns normal of vertex i
 | 
			
		||||
		virtual const core::vector3df& getNormal(u32 i) const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer()[i].Normal;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns normal of vertex i
 | 
			
		||||
		virtual core::vector3df& getNormal(u32 i) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return getVertexBuffer()[i].Normal;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace scene
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -12,7 +12,6 @@
 | 
			
		||||
#include "vector3d.h"
 | 
			
		||||
#include "dimension2d.h"
 | 
			
		||||
#include "SColor.h"
 | 
			
		||||
#include "ETerrainElements.h"
 | 
			
		||||
#include "ESceneNodeTypes.h"
 | 
			
		||||
#include "EMeshWriterEnums.h"
 | 
			
		||||
#include "SceneParameters.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -509,20 +509,6 @@ namespace video
 | 
			
		||||
				core::position2d<s32> colorKeyPixelPos,
 | 
			
		||||
				bool zeroTexels = false) const =0;
 | 
			
		||||
 | 
			
		||||
		//! Creates a normal map from a height map texture.
 | 
			
		||||
		/** As input is considered to be a height map the texture is read like:
 | 
			
		||||
		- For a 32-bit texture only the red channel is regarded
 | 
			
		||||
		- For a 16-bit texture the rgb-values are averaged.
 | 
			
		||||
		Output channels red/green for X/Y and blue for up (Z).
 | 
			
		||||
		For a 32-bit texture we store additionally the height value in the
 | 
			
		||||
		alpha channel. This value is used by the video::EMT_PARALLAX_MAP_SOLID
 | 
			
		||||
		material and similar materials.
 | 
			
		||||
		On the borders the texture is considered to repeat.
 | 
			
		||||
		\param texture Height map texture which is converted to a normal map.
 | 
			
		||||
		\param amplitude Constant value by which the height
 | 
			
		||||
		information is multiplied.*/
 | 
			
		||||
		virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const =0;
 | 
			
		||||
 | 
			
		||||
		//! Set a render target.
 | 
			
		||||
		/** This will only work if the driver supports the
 | 
			
		||||
		EVDF_RENDER_TO_TARGET feature, which can be queried with
 | 
			
		||||
 
 | 
			
		||||
@@ -1,43 +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 __S_KEY_MAP_H_INCLUDED__
 | 
			
		||||
#define __S_KEY_MAP_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "Keycodes.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	//! enumeration for key actions. Used for example in the FPS Camera.
 | 
			
		||||
	enum EKEY_ACTION
 | 
			
		||||
	{
 | 
			
		||||
		EKA_MOVE_FORWARD = 0,
 | 
			
		||||
		EKA_MOVE_BACKWARD,
 | 
			
		||||
		EKA_STRAFE_LEFT,
 | 
			
		||||
		EKA_STRAFE_RIGHT,
 | 
			
		||||
		EKA_JUMP_UP,
 | 
			
		||||
		EKA_CROUCH,
 | 
			
		||||
		EKA_ROTATE_LEFT,
 | 
			
		||||
		EKA_ROTATE_RIGHT,
 | 
			
		||||
		EKA_COUNT,
 | 
			
		||||
 | 
			
		||||
		//! This value is not used. It only forces this enumeration to compile in 32 bit.
 | 
			
		||||
		EKA_FORCE_32BIT = 0x7fffffff
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	//! Struct storing which key belongs to which action.
 | 
			
		||||
	struct SKeyMap
 | 
			
		||||
	{
 | 
			
		||||
		SKeyMap() {}
 | 
			
		||||
		SKeyMap(EKEY_ACTION action, EKEY_CODE keyCode) : Action(action), KeyCode(keyCode) {}
 | 
			
		||||
 | 
			
		||||
		EKEY_ACTION Action;
 | 
			
		||||
		EKEY_CODE KeyCode;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -355,7 +355,7 @@ namespace video
 | 
			
		||||
		f32 Shininess;
 | 
			
		||||
 | 
			
		||||
		//! Free parameter, dependent on the material type.
 | 
			
		||||
		/** Mostly ignored, used for example in EMT_PARALLAX_MAP_SOLID,
 | 
			
		||||
		/** Mostly ignored, used for example in
 | 
			
		||||
		EMT_TRANSPARENT_ALPHA_CHANNEL and EMT_ONETEXTURE_BLEND. */
 | 
			
		||||
		f32 MaterialTypeParam;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,260 +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 __S_SHARED_MESH_BUFFER_H_INCLUDED__
 | 
			
		||||
#define __S_SHARED_MESH_BUFFER_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "irrArray.h"
 | 
			
		||||
#include "IMeshBuffer.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace scene
 | 
			
		||||
{
 | 
			
		||||
	//! Implementation of the IMeshBuffer interface with shared vertex list
 | 
			
		||||
	struct SSharedMeshBuffer : public IMeshBuffer
 | 
			
		||||
	{
 | 
			
		||||
		//! constructor
 | 
			
		||||
		SSharedMeshBuffer() 
 | 
			
		||||
			: IMeshBuffer()
 | 
			
		||||
			, Vertices(0), ChangedID_Vertex(1), ChangedID_Index(1)
 | 
			
		||||
			, MappingHintVertex(EHM_NEVER), MappingHintIndex(EHM_NEVER)
 | 
			
		||||
			, PrimitiveType(EPT_TRIANGLES)
 | 
			
		||||
		{
 | 
			
		||||
			#ifdef _DEBUG
 | 
			
		||||
			setDebugName("SSharedMeshBuffer");
 | 
			
		||||
			#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! constructor
 | 
			
		||||
		SSharedMeshBuffer(core::array<video::S3DVertex> *vertices) : IMeshBuffer(), Vertices(vertices), ChangedID_Vertex(1), ChangedID_Index(1), MappingHintVertex(EHM_NEVER), MappingHintIndex(EHM_NEVER)
 | 
			
		||||
		{
 | 
			
		||||
			#ifdef _DEBUG
 | 
			
		||||
			setDebugName("SSharedMeshBuffer");
 | 
			
		||||
			#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns the material of this meshbuffer
 | 
			
		||||
		virtual const video::SMaterial& getMaterial() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return Material;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns the material of this meshbuffer
 | 
			
		||||
		virtual video::SMaterial& getMaterial() _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return Material;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns pointer to vertices
 | 
			
		||||
		virtual const void* getVertices() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (Vertices)
 | 
			
		||||
				return Vertices->const_pointer();
 | 
			
		||||
			else
 | 
			
		||||
				return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns pointer to vertices
 | 
			
		||||
		virtual void* getVertices() _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (Vertices)
 | 
			
		||||
				return Vertices->pointer();
 | 
			
		||||
			else
 | 
			
		||||
				return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns amount of vertices
 | 
			
		||||
		virtual u32 getVertexCount() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (Vertices)
 | 
			
		||||
				return Vertices->size();
 | 
			
		||||
			else
 | 
			
		||||
				return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns pointer to indices
 | 
			
		||||
		virtual const u16* getIndices() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return Indices.const_pointer();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns pointer to indices
 | 
			
		||||
		virtual u16* getIndices() _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return Indices.pointer();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns amount of indices
 | 
			
		||||
		virtual u32 getIndexCount() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return Indices.size();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get type of index data which is stored in this meshbuffer.
 | 
			
		||||
		virtual video::E_INDEX_TYPE getIndexType() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return video::EIT_16BIT;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns an axis aligned bounding box
 | 
			
		||||
		virtual const core::aabbox3d<f32>& getBoundingBox() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return BoundingBox;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! set user axis aligned bounding box
 | 
			
		||||
		virtual void setBoundingBox( const core::aabbox3df& box) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			BoundingBox = box;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns which type of vertex data is stored.
 | 
			
		||||
		virtual video::E_VERTEX_TYPE getVertexType() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return video::EVT_STANDARD;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! recalculates the bounding box. should be called if the mesh changed.
 | 
			
		||||
		virtual void recalculateBoundingBox() _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (!Vertices || Vertices->empty() || Indices.empty())
 | 
			
		||||
				BoundingBox.reset(0,0,0);
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				BoundingBox.reset((*Vertices)[Indices[0]].Pos);
 | 
			
		||||
				for (u32 i=1; i<Indices.size(); ++i)
 | 
			
		||||
					BoundingBox.addInternalPoint((*Vertices)[Indices[i]].Pos);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns position of vertex i
 | 
			
		||||
		virtual const core::vector3df& getPosition(u32 i) const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			_IRR_DEBUG_BREAK_IF(!Vertices);
 | 
			
		||||
			return (*Vertices)[Indices[i]].Pos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns position of vertex i
 | 
			
		||||
		virtual core::vector3df& getPosition(u32 i) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			_IRR_DEBUG_BREAK_IF(!Vertices);
 | 
			
		||||
			return (*Vertices)[Indices[i]].Pos;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns normal of vertex i
 | 
			
		||||
		virtual const core::vector3df& getNormal(u32 i) const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			_IRR_DEBUG_BREAK_IF(!Vertices);
 | 
			
		||||
			return (*Vertices)[Indices[i]].Normal;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns normal of vertex i
 | 
			
		||||
		virtual core::vector3df& getNormal(u32 i) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			_IRR_DEBUG_BREAK_IF(!Vertices);
 | 
			
		||||
			return (*Vertices)[Indices[i]].Normal;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns texture coord of vertex i
 | 
			
		||||
		virtual const core::vector2df& getTCoords(u32 i) const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			_IRR_DEBUG_BREAK_IF(!Vertices);
 | 
			
		||||
			return (*Vertices)[Indices[i]].TCoords;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! returns texture coord of vertex i
 | 
			
		||||
		virtual core::vector2df& getTCoords(u32 i) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			_IRR_DEBUG_BREAK_IF(!Vertices);
 | 
			
		||||
			return (*Vertices)[Indices[i]].TCoords;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! append the vertices and indices to the current buffer
 | 
			
		||||
		virtual void append(const void* const vertices, u32 numVertices, const u16* const indices, u32 numIndices)  _IRR_OVERRIDE_ {}
 | 
			
		||||
		//! append the meshbuffer to the current buffer
 | 
			
		||||
		virtual void append(const IMeshBuffer* const other) _IRR_OVERRIDE_ {}
 | 
			
		||||
 | 
			
		||||
		//! get the current hardware mapping hint
 | 
			
		||||
		virtual E_HARDWARE_MAPPING getHardwareMappingHint_Vertex() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return MappingHintVertex;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! get the current hardware mapping hint
 | 
			
		||||
		virtual E_HARDWARE_MAPPING getHardwareMappingHint_Index() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return MappingHintIndex;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! set the hardware mapping hint, for driver
 | 
			
		||||
		virtual void setHardwareMappingHint( E_HARDWARE_MAPPING NewMappingHint, E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX ) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (buffer==EBT_VERTEX_AND_INDEX || buffer==EBT_VERTEX)
 | 
			
		||||
				MappingHintVertex=NewMappingHint;
 | 
			
		||||
			if (buffer==EBT_VERTEX_AND_INDEX || buffer==EBT_INDEX)
 | 
			
		||||
				MappingHintIndex=NewMappingHint;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Describe what kind of primitive geometry is used by the meshbuffer
 | 
			
		||||
		virtual void setPrimitiveType(E_PRIMITIVE_TYPE type) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			PrimitiveType = type;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get the kind of primitive geometry which is used by the meshbuffer
 | 
			
		||||
		virtual E_PRIMITIVE_TYPE getPrimitiveType() const _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			return PrimitiveType;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! flags the mesh as changed, reloads hardware buffers
 | 
			
		||||
		virtual void setDirty(E_BUFFER_TYPE buffer=EBT_VERTEX_AND_INDEX) _IRR_OVERRIDE_
 | 
			
		||||
		{
 | 
			
		||||
			if (buffer==EBT_VERTEX_AND_INDEX || buffer==EBT_VERTEX)
 | 
			
		||||
				++ChangedID_Vertex;
 | 
			
		||||
			if (buffer==EBT_VERTEX_AND_INDEX || buffer==EBT_INDEX)
 | 
			
		||||
				++ChangedID_Index;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! Get the currently used ID for identification of changes.
 | 
			
		||||
		/** This shouldn't be used for anything outside the VideoDriver. */
 | 
			
		||||
		virtual u32 getChangedID_Vertex() const _IRR_OVERRIDE_ {return ChangedID_Vertex;}
 | 
			
		||||
 | 
			
		||||
		//! Get the currently used ID for identification of changes.
 | 
			
		||||
		/** This shouldn't be used for anything outside the VideoDriver. */
 | 
			
		||||
		virtual u32 getChangedID_Index() const _IRR_OVERRIDE_ {return ChangedID_Index;}
 | 
			
		||||
 | 
			
		||||
		//! Material of this meshBuffer
 | 
			
		||||
		video::SMaterial Material;
 | 
			
		||||
 | 
			
		||||
		//! Shared Array of vertices
 | 
			
		||||
		core::array<video::S3DVertex> *Vertices;
 | 
			
		||||
 | 
			
		||||
		//! Array of indices
 | 
			
		||||
		core::array<u16> Indices;
 | 
			
		||||
 | 
			
		||||
		//! ID used for hardware buffer management
 | 
			
		||||
		u32 ChangedID_Vertex;
 | 
			
		||||
 | 
			
		||||
		//! ID used for hardware buffer management
 | 
			
		||||
		u32 ChangedID_Index;
 | 
			
		||||
 | 
			
		||||
		//! Bounding box
 | 
			
		||||
		core::aabbox3df BoundingBox;
 | 
			
		||||
 | 
			
		||||
		//! hardware mapping hint
 | 
			
		||||
		E_HARDWARE_MAPPING MappingHintVertex;
 | 
			
		||||
		E_HARDWARE_MAPPING MappingHintIndex;
 | 
			
		||||
 | 
			
		||||
		//! Primitive type used for rendering (triangles, lines, ...)
 | 
			
		||||
		E_PRIMITIVE_TYPE PrimitiveType;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace scene
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -31,7 +31,6 @@
 | 
			
		||||
 | 
			
		||||
#include "IrrCompileConfig.h"
 | 
			
		||||
#include "aabbox3d.h"
 | 
			
		||||
#include "CDynamicMeshBuffer.h"
 | 
			
		||||
#include "CIndexBuffer.h"
 | 
			
		||||
#include "CMeshBuffer.h"
 | 
			
		||||
#include "coreutil.h"
 | 
			
		||||
@@ -50,7 +49,6 @@
 | 
			
		||||
#include "EMeshWriterEnums.h"
 | 
			
		||||
#include "EMessageBoxFlags.h"
 | 
			
		||||
#include "ESceneNodeTypes.h"
 | 
			
		||||
#include "ETerrainElements.h"
 | 
			
		||||
#include "fast_atof.h"
 | 
			
		||||
#include "heapsort.h"
 | 
			
		||||
#include "IAnimatedMesh.h"
 | 
			
		||||
@@ -63,7 +61,6 @@
 | 
			
		||||
#include "IContextManager.h"
 | 
			
		||||
#include "ICursorControl.h"
 | 
			
		||||
#include "IDummyTransformationSceneNode.h"
 | 
			
		||||
#include "IDynamicMeshBuffer.h"
 | 
			
		||||
#include "IEventReceiver.h"
 | 
			
		||||
#include "IFileList.h"
 | 
			
		||||
#include "IFileSystem.h"
 | 
			
		||||
@@ -150,12 +147,10 @@
 | 
			
		||||
#include "SColor.h"
 | 
			
		||||
#include "SExposedVideoData.h"
 | 
			
		||||
#include "SIrrCreationParameters.h"
 | 
			
		||||
#include "SKeyMap.h"
 | 
			
		||||
#include "SLight.h"
 | 
			
		||||
#include "SMaterial.h"
 | 
			
		||||
#include "SMesh.h"
 | 
			
		||||
#include "SMeshBuffer.h"
 | 
			
		||||
#include "SSharedMeshBuffer.h"
 | 
			
		||||
#include "SSkinMeshBuffer.h"
 | 
			
		||||
#include "SVertexIndex.h"
 | 
			
		||||
#include "SViewFrustum.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,74 +0,0 @@
 | 
			
		||||
#define MAX_LIGHTS 2
 | 
			
		||||
 | 
			
		||||
precision mediump float;
 | 
			
		||||
 | 
			
		||||
/* Uniforms */
 | 
			
		||||
 | 
			
		||||
uniform sampler2D uTextureUnit0;
 | 
			
		||||
uniform sampler2D uTextureUnit1;
 | 
			
		||||
uniform int uFogEnable;
 | 
			
		||||
uniform int uFogType;
 | 
			
		||||
uniform vec4 uFogColor;
 | 
			
		||||
uniform float uFogStart;
 | 
			
		||||
uniform float uFogEnd;
 | 
			
		||||
uniform float uFogDensity;
 | 
			
		||||
 | 
			
		||||
/* Varyings */
 | 
			
		||||
 | 
			
		||||
varying vec2 vTexCoord;
 | 
			
		||||
varying vec3 vLightVector[MAX_LIGHTS];
 | 
			
		||||
varying vec4 vLightColor[MAX_LIGHTS];
 | 
			
		||||
varying float vFogCoord;
 | 
			
		||||
 | 
			
		||||
float computeFog()
 | 
			
		||||
{
 | 
			
		||||
	const float LOG2 = 1.442695;
 | 
			
		||||
	float FogFactor = 0.0;
 | 
			
		||||
 | 
			
		||||
	if (uFogType == 0) // Exp
 | 
			
		||||
	{
 | 
			
		||||
		FogFactor = exp2(-uFogDensity * vFogCoord * LOG2);
 | 
			
		||||
	}
 | 
			
		||||
	else if (uFogType == 1) // Linear
 | 
			
		||||
	{
 | 
			
		||||
		float Scale = 1.0 / (uFogEnd - uFogStart);
 | 
			
		||||
		FogFactor = (uFogEnd - vFogCoord) * Scale;
 | 
			
		||||
	}
 | 
			
		||||
	else if (uFogType == 2) // Exp2
 | 
			
		||||
	{
 | 
			
		||||
		FogFactor = exp2(-uFogDensity * uFogDensity * vFogCoord * vFogCoord * LOG2);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FogFactor = clamp(FogFactor, 0.0, 1.0);
 | 
			
		||||
 | 
			
		||||
	return FogFactor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
	vec4 Color  = texture2D(uTextureUnit0, vTexCoord);
 | 
			
		||||
	vec3 Normal = texture2D(uTextureUnit1, vTexCoord).xyz *  2.0 - 1.0;
 | 
			
		||||
 | 
			
		||||
	vec4 FinalColor = vec4(0.0, 0.0, 0.0, 0.0);
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < int(MAX_LIGHTS); i++)
 | 
			
		||||
	{
 | 
			
		||||
		vec3 LightVector = normalize(vLightVector[i]);
 | 
			
		||||
 | 
			
		||||
		float Lambert = max(dot(LightVector, Normal), 0.0);
 | 
			
		||||
		FinalColor += vec4(Lambert) * vLightColor[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FinalColor *= Color;
 | 
			
		||||
	FinalColor.w = vLightColor[0].w;
 | 
			
		||||
 | 
			
		||||
	if (bool(uFogEnable))
 | 
			
		||||
	{
 | 
			
		||||
		float FogFactor = computeFog();
 | 
			
		||||
		vec4 FogColor = uFogColor;
 | 
			
		||||
		FogColor.a = 1.0;
 | 
			
		||||
		FinalColor = mix(FogColor, FinalColor, FogFactor);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	gl_FragColor = FinalColor;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
#define MAX_LIGHTS 2
 | 
			
		||||
 | 
			
		||||
/* Attributes */
 | 
			
		||||
 | 
			
		||||
attribute vec3 inVertexPosition;
 | 
			
		||||
attribute vec3 inVertexNormal;
 | 
			
		||||
attribute vec3 inVertexTangent;
 | 
			
		||||
attribute vec3 inVertexBinormal;
 | 
			
		||||
attribute vec4 inVertexColor;
 | 
			
		||||
attribute vec2 inTexCoord0;
 | 
			
		||||
 | 
			
		||||
/* Uniforms */
 | 
			
		||||
 | 
			
		||||
uniform mat4 uWVPMatrix;
 | 
			
		||||
uniform mat4 uWVMatrix;
 | 
			
		||||
uniform vec3 uLightPosition[MAX_LIGHTS];
 | 
			
		||||
uniform vec4 uLightColor[MAX_LIGHTS];
 | 
			
		||||
 | 
			
		||||
/* Varyings */
 | 
			
		||||
 | 
			
		||||
varying vec2 vTexCoord;
 | 
			
		||||
varying vec3 vLightVector[MAX_LIGHTS];
 | 
			
		||||
varying vec4 vLightColor[MAX_LIGHTS];
 | 
			
		||||
varying float vFogCoord;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
	gl_Position = uWVPMatrix * vec4(inVertexPosition, 1.0);
 | 
			
		||||
 | 
			
		||||
	vTexCoord = inTexCoord0;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < int(MAX_LIGHTS); i++)
 | 
			
		||||
	{
 | 
			
		||||
		vec3 LightVector = uLightPosition[i] - inVertexPosition;
 | 
			
		||||
 | 
			
		||||
		vLightVector[i].x = dot(inVertexTangent, LightVector);
 | 
			
		||||
		vLightVector[i].y = dot(inVertexBinormal, LightVector);
 | 
			
		||||
		vLightVector[i].z = dot(inVertexNormal, LightVector);
 | 
			
		||||
 | 
			
		||||
		vLightColor[i].x = dot(LightVector, LightVector);
 | 
			
		||||
		vLightColor[i].x *= uLightColor[i].a;
 | 
			
		||||
		vLightColor[i] = vec4(inversesqrt(vLightColor[i].x));
 | 
			
		||||
		vLightColor[i] *= uLightColor[i];
 | 
			
		||||
		vLightColor[i].a = inVertexColor.a;
 | 
			
		||||
 | 
			
		||||
		vLightColor[i].x = clamp(vLightColor[i].x, 0.0, 1.0);
 | 
			
		||||
		vLightColor[i].y = clamp(vLightColor[i].y, 0.0, 1.0);
 | 
			
		||||
		vLightColor[i].z = clamp(vLightColor[i].z, 0.0, 1.0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vFogCoord = length((uWVMatrix * vec4(inVertexPosition, 1.0)).xyz);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,82 +0,0 @@
 | 
			
		||||
#define MAX_LIGHTS 2
 | 
			
		||||
 | 
			
		||||
precision mediump float;
 | 
			
		||||
 | 
			
		||||
/* Uniforms */
 | 
			
		||||
 | 
			
		||||
uniform float uFactor;
 | 
			
		||||
uniform sampler2D uTextureUnit0;
 | 
			
		||||
uniform sampler2D uTextureUnit1;
 | 
			
		||||
uniform int uFogEnable;
 | 
			
		||||
uniform int uFogType;
 | 
			
		||||
uniform vec4 uFogColor;
 | 
			
		||||
uniform float uFogStart;
 | 
			
		||||
uniform float uFogEnd;
 | 
			
		||||
uniform float uFogDensity;
 | 
			
		||||
 | 
			
		||||
/* Varyings */
 | 
			
		||||
 | 
			
		||||
varying vec2 vTexCoord;
 | 
			
		||||
varying vec3 vEyeVector;
 | 
			
		||||
varying vec3 vLightVector[MAX_LIGHTS];
 | 
			
		||||
varying vec4 vLightColor[MAX_LIGHTS];
 | 
			
		||||
varying float vFogCoord;
 | 
			
		||||
 | 
			
		||||
float computeFog()
 | 
			
		||||
{
 | 
			
		||||
	const float LOG2 = 1.442695;
 | 
			
		||||
	float FogFactor = 0.0;
 | 
			
		||||
 | 
			
		||||
	if (uFogType == 0) // Exp
 | 
			
		||||
	{
 | 
			
		||||
		FogFactor = exp2(-uFogDensity * vFogCoord * LOG2);
 | 
			
		||||
	}
 | 
			
		||||
	else if (uFogType == 1) // Linear
 | 
			
		||||
	{
 | 
			
		||||
		float Scale = 1.0 / (uFogEnd - uFogStart);
 | 
			
		||||
		FogFactor = (uFogEnd - vFogCoord) * Scale;
 | 
			
		||||
	}
 | 
			
		||||
	else if (uFogType == 2) // Exp2
 | 
			
		||||
	{
 | 
			
		||||
		FogFactor = exp2(-uFogDensity * uFogDensity * vFogCoord * vFogCoord * LOG2);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FogFactor = clamp(FogFactor, 0.0, 1.0);
 | 
			
		||||
 | 
			
		||||
	return FogFactor;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
	vec4 TempFetch = texture2D(uTextureUnit1, vTexCoord) *  2.0 - 1.0;
 | 
			
		||||
	TempFetch *= uFactor;
 | 
			
		||||
 | 
			
		||||
	vec3 EyeVector = normalize(vEyeVector);
 | 
			
		||||
	vec2 TexCoord = EyeVector.xy * TempFetch.w + vTexCoord;
 | 
			
		||||
 | 
			
		||||
	vec4 Color  = texture2D(uTextureUnit0, TexCoord);
 | 
			
		||||
	vec3 Normal = texture2D(uTextureUnit1, TexCoord).xyz *  2.0 - 1.0;
 | 
			
		||||
 | 
			
		||||
	vec4 FinalColor = vec4(0.0, 0.0, 0.0, 0.0);
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < int(MAX_LIGHTS); i++)
 | 
			
		||||
	{
 | 
			
		||||
		vec3 LightVector = normalize(vLightVector[i]);
 | 
			
		||||
 | 
			
		||||
		float Lambert = max(dot(LightVector, Normal), 0.0);
 | 
			
		||||
		FinalColor += vec4(Lambert) * vLightColor[i];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	FinalColor *= Color;
 | 
			
		||||
	FinalColor.w = vLightColor[0].w;
 | 
			
		||||
 | 
			
		||||
	if (bool(uFogEnable))
 | 
			
		||||
	{
 | 
			
		||||
		float FogFactor = computeFog();
 | 
			
		||||
		vec4 FogColor = uFogColor;
 | 
			
		||||
		FogColor.a = 1.0;
 | 
			
		||||
		FinalColor = mix(FogColor, FinalColor, FogFactor);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	gl_FragColor = FinalColor;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,61 +0,0 @@
 | 
			
		||||
#define MAX_LIGHTS 2
 | 
			
		||||
 | 
			
		||||
/* Attributes */
 | 
			
		||||
 | 
			
		||||
attribute vec3 inVertexPosition;
 | 
			
		||||
attribute vec3 inVertexNormal;
 | 
			
		||||
attribute vec3 inVertexTangent;
 | 
			
		||||
attribute vec3 inVertexBinormal;
 | 
			
		||||
attribute vec4 inVertexColor;
 | 
			
		||||
attribute vec2 inTexCoord0;
 | 
			
		||||
 | 
			
		||||
/* Uniforms */
 | 
			
		||||
 | 
			
		||||
uniform mat4 uWVPMatrix;
 | 
			
		||||
uniform mat4 uWVMatrix;
 | 
			
		||||
uniform vec3 uEyePosition;
 | 
			
		||||
uniform vec3 uLightPosition[MAX_LIGHTS];
 | 
			
		||||
uniform vec4 uLightColor[MAX_LIGHTS];
 | 
			
		||||
 | 
			
		||||
/* Varyings */
 | 
			
		||||
 | 
			
		||||
varying vec2 vTexCoord;
 | 
			
		||||
varying vec3 vEyeVector;
 | 
			
		||||
varying vec3 vLightVector[MAX_LIGHTS];
 | 
			
		||||
varying vec4 vLightColor[MAX_LIGHTS];
 | 
			
		||||
varying float vFogCoord;
 | 
			
		||||
 | 
			
		||||
void main()
 | 
			
		||||
{
 | 
			
		||||
	gl_Position = uWVPMatrix * vec4(inVertexPosition, 1.0);
 | 
			
		||||
 | 
			
		||||
	vTexCoord = inTexCoord0;
 | 
			
		||||
 | 
			
		||||
	vec3 EyeVector = uEyePosition - inVertexPosition;
 | 
			
		||||
 | 
			
		||||
	vEyeVector.x = dot(inVertexTangent, EyeVector);
 | 
			
		||||
	vEyeVector.y = dot(inVertexBinormal, EyeVector);
 | 
			
		||||
	vEyeVector.z = dot(inVertexNormal, EyeVector);
 | 
			
		||||
	vEyeVector *= vec3(1.0, -1.0, -1.0);
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < int(MAX_LIGHTS); i++)
 | 
			
		||||
	{
 | 
			
		||||
		vec3 LightVector = uLightPosition[i] - inVertexPosition;
 | 
			
		||||
 | 
			
		||||
		vLightVector[i].x = dot(inVertexTangent, LightVector);
 | 
			
		||||
		vLightVector[i].y = dot(inVertexBinormal, LightVector);
 | 
			
		||||
		vLightVector[i].z = dot(inVertexNormal, LightVector);
 | 
			
		||||
 | 
			
		||||
		vLightColor[i].x = dot(LightVector, LightVector);
 | 
			
		||||
		vLightColor[i].x *= uLightColor[i].a;
 | 
			
		||||
		vLightColor[i] = vec4(inversesqrt(vLightColor[i].x));
 | 
			
		||||
		vLightColor[i] *= uLightColor[i];
 | 
			
		||||
		vLightColor[i].a = inVertexColor.a;
 | 
			
		||||
 | 
			
		||||
		vLightColor[i].x = clamp(vLightColor[i].x, 0.0, 1.0);
 | 
			
		||||
		vLightColor[i].y = clamp(vLightColor[i].y, 0.0, 1.0);
 | 
			
		||||
		vLightColor[i].z = clamp(vLightColor[i].z, 0.0, 1.0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vFogCoord = length((uWVMatrix * vec4(inVertexPosition, 1.0)).xyz);
 | 
			
		||||
}
 | 
			
		||||
@@ -1057,73 +1057,6 @@ static s32 Blit(eBlitter operation,
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(SOFTWARE_DRIVER_2_2D_AS_2D)
 | 
			
		||||
static s32 StretchBlit(eBlitter operation,
 | 
			
		||||
		video::IImage* dest, const core::rect<s32>* destClipping,const core::rect<s32> *destRect,
 | 
			
		||||
		video::IImage* const source,const core::rect<s32> *srcRect, const core::dimension2d<u32>* source_org,
 | 
			
		||||
		u32 argb)
 | 
			
		||||
{
 | 
			
		||||
	tExecuteBlit blitter = getBlitter2( operation, dest, source );
 | 
			
		||||
	if ( 0 == blitter )
 | 
			
		||||
	{
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	SBlitJob job;
 | 
			
		||||
 | 
			
		||||
	AbsRectangle destClip;
 | 
			
		||||
	AbsRectangle v;
 | 
			
		||||
	setClip(destClip, destClipping, dest, 0, 0);
 | 
			
		||||
	setClip(v, destRect, 0, 1, 0);
 | 
			
		||||
	if (!intersect(job.Dest, destClip, v))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	// Clipping
 | 
			
		||||
	setClip ( job.Source, srcRect, source, 1, source_org);
 | 
			
		||||
 | 
			
		||||
	job.width = job.Dest.x1-job.Dest.x0;
 | 
			
		||||
	job.height = job.Dest.y1-job.Dest.y0;
 | 
			
		||||
 | 
			
		||||
	job.argb = argb;
 | 
			
		||||
 | 
			
		||||
	// use original dest size, despite any clipping
 | 
			
		||||
	const int dst_w = v.x1 - v.x0; // destRect->getWidth();
 | 
			
		||||
	const int dst_h = v.y1 - v.y0; // destRect->getHeight();
 | 
			
		||||
	const int src_w = job.Source.x1 - job.Source.x0;
 | 
			
		||||
	const int src_h = job.Source.y1 - job.Source.y0;
 | 
			
		||||
 | 
			
		||||
	job.stretch = dst_w != src_w || dst_h != src_h;
 | 
			
		||||
	job.x_stretch = dst_w ? (float)src_w / (float)dst_w : 1.f;
 | 
			
		||||
	job.y_stretch = dst_h ? (float)src_h / (float)dst_h : 1.f;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if ( source )
 | 
			
		||||
	{
 | 
			
		||||
		job.srcPitch = source->getPitch();
 | 
			
		||||
		job.srcPixelMul = source->getBytesPerPixel();
 | 
			
		||||
 | 
			
		||||
		//dest-clippling. advance source. loosing subpixel precision
 | 
			
		||||
		job.Source.x0 += (s32)floorf(job.x_stretch * (job.Dest.x0 - v.x0));
 | 
			
		||||
		job.Source.y0 += (s32)floorf(job.y_stretch * (job.Dest.y0 - v.y0));
 | 
			
		||||
 | 
			
		||||
		job.src = (void*) ( (u8*) source->getData() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) );
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// use srcPitch for color operation on dest
 | 
			
		||||
		job.srcPitch = job.width * dest->getBytesPerPixel();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	job.dstPitch = dest->getPitch();
 | 
			
		||||
	job.dstPixelMul = dest->getBytesPerPixel();
 | 
			
		||||
	job.dst = (void*) ( (u8*) dest->getData() + ( job.Dest.y0 * job.dstPitch ) + ( job.Dest.x0 * job.dstPixelMul ) );
 | 
			
		||||
 | 
			
		||||
	blitter( &job );
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -162,8 +162,6 @@ set(IRRDRVROBJ
 | 
			
		||||
	CNullDriver.cpp
 | 
			
		||||
	COpenGLCacheHandler.cpp
 | 
			
		||||
	COpenGLDriver.cpp
 | 
			
		||||
	COpenGLNormalMapRenderer.cpp
 | 
			
		||||
	COpenGLParallaxMapRenderer.cpp
 | 
			
		||||
	COpenGLShaderMaterialRenderer.cpp
 | 
			
		||||
	COpenGLSLMaterialRenderer.cpp
 | 
			
		||||
	COpenGLExtensionHandler.cpp
 | 
			
		||||
@@ -173,8 +171,6 @@ set(IRRDRVROBJ
 | 
			
		||||
	COGLES2ExtensionHandler.cpp
 | 
			
		||||
	COGLES2FixedPipelineRenderer.cpp
 | 
			
		||||
	COGLES2MaterialRenderer.cpp
 | 
			
		||||
	COGLES2NormalMapRenderer.cpp
 | 
			
		||||
	COGLES2ParallaxMapRenderer.cpp
 | 
			
		||||
	COGLES2Renderer2D.cpp
 | 
			
		||||
	CWebGL1Driver.cpp
 | 
			
		||||
	CGLXManager.cpp
 | 
			
		||||
 
 | 
			
		||||
@@ -1291,124 +1291,6 @@ void CNullDriver::makeColorKeyTexture(video::ITexture* texture,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Creates a normal map from a height map texture.
 | 
			
		||||
//! \param amplitude: Constant value by which the height information is multiplied.
 | 
			
		||||
void CNullDriver::makeNormalMapTexture(video::ITexture* texture, f32 amplitude) const
 | 
			
		||||
{
 | 
			
		||||
	if (!texture)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (texture->getColorFormat() != ECF_A1R5G5B5 &&
 | 
			
		||||
		texture->getColorFormat() != ECF_A8R8G8B8 )
 | 
			
		||||
	{
 | 
			
		||||
		os::Printer::log("Error: Unsupported texture color format for making normal map.", ELL_ERROR);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	core::dimension2d<u32> dim = texture->getSize();
 | 
			
		||||
	amplitude = amplitude / 255.0f;
 | 
			
		||||
	f32 vh = dim.Height / (f32)dim.Width;
 | 
			
		||||
	f32 hh = dim.Width / (f32)dim.Height;
 | 
			
		||||
 | 
			
		||||
	if (texture->getColorFormat() == ECF_A8R8G8B8)
 | 
			
		||||
	{
 | 
			
		||||
		// ECF_A8R8G8B8 version
 | 
			
		||||
 | 
			
		||||
		s32 *p = (s32*)texture->lock();
 | 
			
		||||
 | 
			
		||||
		if (!p)
 | 
			
		||||
		{
 | 
			
		||||
			os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// copy texture
 | 
			
		||||
 | 
			
		||||
		u32 pitch = texture->getPitch() / 4;
 | 
			
		||||
 | 
			
		||||
		s32* in = new s32[dim.Height * pitch];
 | 
			
		||||
		memcpy(in, p, dim.Height * pitch * 4);
 | 
			
		||||
 | 
			
		||||
		for (s32 x=0; x < s32(pitch); ++x)
 | 
			
		||||
			for (s32 y=0; y < s32(dim.Height); ++y)
 | 
			
		||||
			{
 | 
			
		||||
				// TODO: this could be optimized really a lot
 | 
			
		||||
 | 
			
		||||
				core::vector3df h1((x-1)*hh, nml32(x-1, y, pitch, dim.Height, in)*amplitude, y*vh);
 | 
			
		||||
				core::vector3df h2((x+1)*hh, nml32(x+1, y, pitch, dim.Height, in)*amplitude, y*vh);
 | 
			
		||||
				//core::vector3df v1(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh);
 | 
			
		||||
				//core::vector3df v2(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh);
 | 
			
		||||
				core::vector3df v1(x*hh, nml32(x, y+1, pitch, dim.Height, in)*amplitude, (y-1)*vh);
 | 
			
		||||
				core::vector3df v2(x*hh, nml32(x, y-1, pitch, dim.Height, in)*amplitude, (y+1)*vh);
 | 
			
		||||
 | 
			
		||||
				core::vector3df v = v1-v2;
 | 
			
		||||
				core::vector3df h = h1-h2;
 | 
			
		||||
 | 
			
		||||
				core::vector3df n = v.crossProduct(h);
 | 
			
		||||
				n.normalize();
 | 
			
		||||
				n *= 0.5f;
 | 
			
		||||
				n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1
 | 
			
		||||
				n *= 255.0f;
 | 
			
		||||
 | 
			
		||||
				s32 height = (s32)nml32(x, y, pitch, dim.Height, in);
 | 
			
		||||
				p[y*pitch + x] = video::SColor(
 | 
			
		||||
					height, // store height in alpha
 | 
			
		||||
					(s32)n.X, (s32)n.Z, (s32)n.Y).color;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		delete [] in;
 | 
			
		||||
		texture->unlock();
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// ECF_A1R5G5B5 version
 | 
			
		||||
 | 
			
		||||
		s16 *p = (s16*)texture->lock();
 | 
			
		||||
 | 
			
		||||
		if (!p)
 | 
			
		||||
		{
 | 
			
		||||
			os::Printer::log("Could not lock texture for making normal map.", ELL_ERROR);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		u32 pitch = texture->getPitch() / 2;
 | 
			
		||||
 | 
			
		||||
		// copy texture
 | 
			
		||||
 | 
			
		||||
		s16* in = new s16[dim.Height * pitch];
 | 
			
		||||
		memcpy(in, p, dim.Height * pitch * 2);
 | 
			
		||||
 | 
			
		||||
		for (s32 x=0; x < s32(pitch); ++x)
 | 
			
		||||
			for (s32 y=0; y < s32(dim.Height); ++y)
 | 
			
		||||
			{
 | 
			
		||||
				// TODO: this could be optimized really a lot
 | 
			
		||||
 | 
			
		||||
				core::vector3df h1((x-1)*hh, nml16(x-1, y, pitch, dim.Height, in)*amplitude, y*vh);
 | 
			
		||||
				core::vector3df h2((x+1)*hh, nml16(x+1, y, pitch, dim.Height, in)*amplitude, y*vh);
 | 
			
		||||
				core::vector3df v1(x*hh, nml16(x, y-1, pitch, dim.Height, in)*amplitude, (y-1)*vh);
 | 
			
		||||
				core::vector3df v2(x*hh, nml16(x, y+1, pitch, dim.Height, in)*amplitude, (y+1)*vh);
 | 
			
		||||
 | 
			
		||||
				core::vector3df v = v1-v2;
 | 
			
		||||
				core::vector3df h = h1-h2;
 | 
			
		||||
 | 
			
		||||
				core::vector3df n = v.crossProduct(h);
 | 
			
		||||
				n.normalize();
 | 
			
		||||
				n *= 0.5f;
 | 
			
		||||
				n += core::vector3df(0.5f,0.5f,0.5f); // now between 0 and 1
 | 
			
		||||
				n *= 255.0f;
 | 
			
		||||
 | 
			
		||||
				p[y*pitch + x] = video::RGBA16((u32)n.X, (u32)n.Z, (u32)n.Y);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		delete [] in;
 | 
			
		||||
		texture->unlock();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	texture->regenerateMipMapLevels();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Returns the maximum amount of primitives (mostly vertices) which
 | 
			
		||||
//! the device is able to render with one drawIndexedTriangleList
 | 
			
		||||
//! call.
 | 
			
		||||
 
 | 
			
		||||
@@ -335,10 +335,6 @@ namespace video
 | 
			
		||||
		virtual void makeColorKeyTexture(video::ITexture* texture, core::position2d<s32> colorKeyPixelPos,
 | 
			
		||||
			bool zeroTexels) const _IRR_OVERRIDE_;
 | 
			
		||||
 | 
			
		||||
		//! Creates a normal map from a height map texture.
 | 
			
		||||
		//! \param amplitude: Constant value by which the height information is multiplied.
 | 
			
		||||
		virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const _IRR_OVERRIDE_;
 | 
			
		||||
 | 
			
		||||
		//! Returns the maximum amount of primitives (mostly vertices) which
 | 
			
		||||
		//! the device is able to render with one drawIndexedTriangleList
 | 
			
		||||
		//! call.
 | 
			
		||||
@@ -720,35 +716,6 @@ namespace video
 | 
			
		||||
		// prints renderer version
 | 
			
		||||
		void printVersion();
 | 
			
		||||
 | 
			
		||||
		//! normal map lookup 32 bit version
 | 
			
		||||
		inline f32 nml32(int x, int y, int pitch, int height, s32 *p) const
 | 
			
		||||
		{
 | 
			
		||||
			if (x < 0)
 | 
			
		||||
				x = pitch-1;
 | 
			
		||||
			if (x >= pitch)
 | 
			
		||||
				x = 0;
 | 
			
		||||
			if (y < 0)
 | 
			
		||||
				y = height-1;
 | 
			
		||||
			if (y >= height)
 | 
			
		||||
				y = 0;
 | 
			
		||||
			return (f32)(((p[(y * pitch) + x])>>16) & 0xff);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		//! normal map lookup 16 bit version
 | 
			
		||||
		inline f32 nml16(int x, int y, int pitch, int height, s16 *p) const
 | 
			
		||||
		{
 | 
			
		||||
			if (x < 0)
 | 
			
		||||
				x = pitch-1;
 | 
			
		||||
			if (x >= pitch)
 | 
			
		||||
				x = 0;
 | 
			
		||||
			if (y < 0)
 | 
			
		||||
				y = height-1;
 | 
			
		||||
			if (y >= height)
 | 
			
		||||
				y = 0;
 | 
			
		||||
 | 
			
		||||
			return (f32) getAverage ( p[(y * pitch) + x] );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		inline bool getWriteZBuffer(const SMaterial& material) const
 | 
			
		||||
		{
 | 
			
		||||
			switch ( material.ZWriteEnable )
 | 
			
		||||
 
 | 
			
		||||
@@ -316,16 +316,7 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
 | 
			
		||||
			Materials[m]->Meshbuffer->recalculateBoundingBox();
 | 
			
		||||
			if (Materials[m]->RecalculateNormals)
 | 
			
		||||
				SceneManager->getMeshManipulator()->recalculateNormals(Materials[m]->Meshbuffer);
 | 
			
		||||
			if (Materials[m]->Meshbuffer->Material.MaterialType == video::EMT_PARALLAX_MAP_SOLID)
 | 
			
		||||
			{
 | 
			
		||||
				SMesh tmp;
 | 
			
		||||
				tmp.addMeshBuffer(Materials[m]->Meshbuffer);
 | 
			
		||||
				IMesh* tangentMesh = SceneManager->getMeshManipulator()->createMeshWithTangents(&tmp);
 | 
			
		||||
				mesh->addMeshBuffer(tangentMesh->getMeshBuffer(0));
 | 
			
		||||
				tangentMesh->drop();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				mesh->addMeshBuffer( Materials[m]->Meshbuffer );
 | 
			
		||||
			mesh->addMeshBuffer( Materials[m]->Meshbuffer );
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,6 @@
 | 
			
		||||
 | 
			
		||||
#include "COGLES2MaterialRenderer.h"
 | 
			
		||||
#include "COGLES2FixedPipelineRenderer.h"
 | 
			
		||||
#include "COGLES2NormalMapRenderer.h"
 | 
			
		||||
#include "COGLES2ParallaxMapRenderer.h"
 | 
			
		||||
#include "COGLES2Renderer2D.h"
 | 
			
		||||
 | 
			
		||||
#include "EVertexAttributes.h"
 | 
			
		||||
@@ -248,12 +246,6 @@ COGLES2Driver::~COGLES2Driver()
 | 
			
		||||
		COGLES2MaterialSolidCB* TransparentAlphaChannelRefCB = new COGLES2MaterialSolidCB();
 | 
			
		||||
		COGLES2MaterialSolidCB* TransparentVertexAlphaCB = new COGLES2MaterialSolidCB();
 | 
			
		||||
		COGLES2MaterialReflectionCB* TransparentReflection2LayerCB = new COGLES2MaterialReflectionCB();
 | 
			
		||||
		COGLES2MaterialNormalMapCB* NormalMapCB = new COGLES2MaterialNormalMapCB();
 | 
			
		||||
		COGLES2MaterialNormalMapCB* NormalMapAddColorCB = new COGLES2MaterialNormalMapCB();
 | 
			
		||||
		COGLES2MaterialNormalMapCB* NormalMapVertexAlphaCB = new COGLES2MaterialNormalMapCB();
 | 
			
		||||
		COGLES2MaterialParallaxMapCB* ParallaxMapCB = new COGLES2MaterialParallaxMapCB();
 | 
			
		||||
		COGLES2MaterialParallaxMapCB* ParallaxMapAddColorCB = new COGLES2MaterialParallaxMapCB();
 | 
			
		||||
		COGLES2MaterialParallaxMapCB* ParallaxMapVertexAlphaCB = new COGLES2MaterialParallaxMapCB();
 | 
			
		||||
		COGLES2MaterialOneTextureBlendCB* OneTextureBlendCB = new COGLES2MaterialOneTextureBlendCB();
 | 
			
		||||
 | 
			
		||||
		// Create built-in materials.
 | 
			
		||||
@@ -342,30 +334,6 @@ COGLES2Driver::~COGLES2Driver()
 | 
			
		||||
		addHighLevelShaderMaterialFromFiles(VertexShader, "main", EVST_VS_2_0, FragmentShader, "main", EPST_PS_2_0, "", "main",
 | 
			
		||||
			EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, TransparentReflection2LayerCB, EMT_TRANSPARENT_ALPHA_CHANNEL, 0);
 | 
			
		||||
 | 
			
		||||
		VertexShader = OGLES2ShaderPath + "COGLES2NormalMap.vsh";
 | 
			
		||||
		FragmentShader = OGLES2ShaderPath + "COGLES2NormalMap.fsh";
 | 
			
		||||
 | 
			
		||||
		addHighLevelShaderMaterialFromFiles(VertexShader, "main", EVST_VS_2_0, FragmentShader, "main", EPST_PS_2_0, "", "main",
 | 
			
		||||
			EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, NormalMapCB, EMT_SOLID, 0);
 | 
			
		||||
 | 
			
		||||
		addHighLevelShaderMaterialFromFiles(VertexShader, "main", EVST_VS_2_0, FragmentShader, "main", EPST_PS_2_0, "", "main",
 | 
			
		||||
			EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, NormalMapAddColorCB, EMT_TRANSPARENT_ADD_COLOR, 0);
 | 
			
		||||
 | 
			
		||||
		addHighLevelShaderMaterialFromFiles(VertexShader, "main", EVST_VS_2_0, FragmentShader, "main", EPST_PS_2_0, "", "main",
 | 
			
		||||
			EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, NormalMapVertexAlphaCB, EMT_TRANSPARENT_ALPHA_CHANNEL, 0);
 | 
			
		||||
 | 
			
		||||
		VertexShader = OGLES2ShaderPath + "COGLES2ParallaxMap.vsh";
 | 
			
		||||
		FragmentShader = OGLES2ShaderPath + "COGLES2ParallaxMap.fsh";
 | 
			
		||||
 | 
			
		||||
		addHighLevelShaderMaterialFromFiles(VertexShader, "main", EVST_VS_2_0, FragmentShader, "main", EPST_PS_2_0, "", "main",
 | 
			
		||||
			EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, ParallaxMapCB, EMT_SOLID, 0);
 | 
			
		||||
 | 
			
		||||
		addHighLevelShaderMaterialFromFiles(VertexShader, "main", EVST_VS_2_0, FragmentShader, "main", EPST_PS_2_0, "", "main",
 | 
			
		||||
			EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, ParallaxMapAddColorCB, EMT_TRANSPARENT_ADD_COLOR, 0);
 | 
			
		||||
 | 
			
		||||
		addHighLevelShaderMaterialFromFiles(VertexShader, "main", EVST_VS_2_0, FragmentShader, "main", EPST_PS_2_0, "", "main",
 | 
			
		||||
			EGST_GS_4_0, scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0, ParallaxMapVertexAlphaCB, EMT_TRANSPARENT_ALPHA_CHANNEL, 0);
 | 
			
		||||
 | 
			
		||||
		VertexShader = OGLES2ShaderPath + "COGLES2Solid.vsh";
 | 
			
		||||
		FragmentShader = OGLES2ShaderPath + "COGLES2OneTextureBlend.fsh";
 | 
			
		||||
 | 
			
		||||
@@ -391,12 +359,6 @@ COGLES2Driver::~COGLES2Driver()
 | 
			
		||||
		TransparentAlphaChannelRefCB->drop();
 | 
			
		||||
		TransparentVertexAlphaCB->drop();
 | 
			
		||||
		TransparentReflection2LayerCB->drop();
 | 
			
		||||
		NormalMapCB->drop();
 | 
			
		||||
		NormalMapAddColorCB->drop();
 | 
			
		||||
		NormalMapVertexAlphaCB->drop();
 | 
			
		||||
		ParallaxMapCB->drop();
 | 
			
		||||
		ParallaxMapAddColorCB->drop();
 | 
			
		||||
		ParallaxMapVertexAlphaCB->drop();
 | 
			
		||||
		OneTextureBlendCB->drop();
 | 
			
		||||
 | 
			
		||||
		// Create 2D material renderers
 | 
			
		||||
 
 | 
			
		||||
@@ -37,8 +37,6 @@ namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	class COGLES2FixedPipelineRenderer;
 | 
			
		||||
	class COGLES2NormalMapRenderer;
 | 
			
		||||
	class COGLES2ParallaxMapRenderer;
 | 
			
		||||
	class COGLES2Renderer2D;
 | 
			
		||||
 | 
			
		||||
	class COGLES2Driver : public CNullDriver, public IMaterialRendererServices, public COGLES2ExtensionHandler
 | 
			
		||||
 
 | 
			
		||||
@@ -40,13 +40,9 @@ COGLES2MaterialRenderer::COGLES2MaterialRenderer(COGLES2Driver* driver,
 | 
			
		||||
	{
 | 
			
		||||
	case EMT_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_TRANSPARENT_ALPHA_CHANNEL:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
		Alpha = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
		FixedBlending = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_ONETEXTURE_BLEND:
 | 
			
		||||
@@ -72,13 +68,9 @@ COGLES2MaterialRenderer::COGLES2MaterialRenderer(COGLES2Driver* driver,
 | 
			
		||||
	{
 | 
			
		||||
	case EMT_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_TRANSPARENT_ALPHA_CHANNEL:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
		Alpha = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
		FixedBlending = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_ONETEXTURE_BLEND:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,132 +0,0 @@
 | 
			
		||||
// Copyright (C) 2014 Patryk Nadrowski
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
 | 
			
		||||
 | 
			
		||||
#include "COGLES2NormalMapRenderer.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OGLES2_
 | 
			
		||||
 | 
			
		||||
#include "IMaterialRendererServices.h"
 | 
			
		||||
#include "IGPUProgrammingServices.h"
 | 
			
		||||
#include "IShaderConstantSetCallBack.h"
 | 
			
		||||
#include "IVideoDriver.h"
 | 
			
		||||
#include "SLight.h"
 | 
			
		||||
#include "os.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// EMT_NORMAL_MAP_SOLID + EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR + EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA
 | 
			
		||||
 | 
			
		||||
COGLES2MaterialNormalMapCB::COGLES2MaterialNormalMapCB() :
 | 
			
		||||
	FirstUpdate(true), WVPMatrixID(-1), WVMatrixID(-1), LightPositionID(-1), LightColorID(-1), TextureUnit0ID(-1), TextureUnit1ID(-1),
 | 
			
		||||
	FogEnableID(-1), FogTypeID(-1), FogColorID(-1), FogStartID(-1), FogEndID(-1), FogDensityID(-1), TextureUnit0(0), TextureUnit1(1),
 | 
			
		||||
	FogEnable(0), FogType(1), FogColor(SColorf(0.f, 0.f, 0.f, 1.f)), FogStart(0.f), FogEnd(0.f), FogDensity(0.f)
 | 
			
		||||
{
 | 
			
		||||
	for (u32 i = 0; i < 2; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		LightPosition[i] = core::vector3df(0.f, 0.f, 0.f);
 | 
			
		||||
		LightColor[i] = SColorf(0.f, 0.f, 0.f, 1.f);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void COGLES2MaterialNormalMapCB::OnSetMaterial(const SMaterial& material)
 | 
			
		||||
{
 | 
			
		||||
	if (material.FogEnable)
 | 
			
		||||
		FogEnable = 1;
 | 
			
		||||
	else
 | 
			
		||||
		FogEnable = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void COGLES2MaterialNormalMapCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
 | 
			
		||||
{
 | 
			
		||||
	IVideoDriver* driver = services->getVideoDriver();
 | 
			
		||||
 | 
			
		||||
	if (FirstUpdate)
 | 
			
		||||
	{
 | 
			
		||||
		WVPMatrixID = services->getVertexShaderConstantID("uWVPMatrix");
 | 
			
		||||
		WVMatrixID = services->getVertexShaderConstantID("uWVMatrix");
 | 
			
		||||
		LightPositionID = services->getVertexShaderConstantID("uLightPosition");
 | 
			
		||||
		LightColorID = services->getVertexShaderConstantID("uLightColor");
 | 
			
		||||
		TextureUnit0ID = services->getVertexShaderConstantID("uTextureUnit0");
 | 
			
		||||
		TextureUnit1ID = services->getVertexShaderConstantID("uTextureUnit1");
 | 
			
		||||
		FogEnableID = services->getVertexShaderConstantID("uFogEnable");
 | 
			
		||||
		FogTypeID = services->getVertexShaderConstantID("uFogType");
 | 
			
		||||
		FogColorID = services->getVertexShaderConstantID("uFogColor");
 | 
			
		||||
		FogStartID = services->getVertexShaderConstantID("uFogStart");
 | 
			
		||||
		FogEndID = services->getVertexShaderConstantID("uFogEnd");
 | 
			
		||||
		FogDensityID = services->getVertexShaderConstantID("uFogDensity");
 | 
			
		||||
 | 
			
		||||
		FirstUpdate = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const core::matrix4 W = driver->getTransform(ETS_WORLD);
 | 
			
		||||
	const core::matrix4 V = driver->getTransform(ETS_VIEW);
 | 
			
		||||
	const core::matrix4 P = driver->getTransform(ETS_PROJECTION);
 | 
			
		||||
 | 
			
		||||
	core::matrix4 Matrix = P * V * W;
 | 
			
		||||
	services->setPixelShaderConstant(WVPMatrixID, Matrix.pointer(), 16);
 | 
			
		||||
 | 
			
		||||
	Matrix = V * W;
 | 
			
		||||
	services->setPixelShaderConstant(WVMatrixID, Matrix.pointer(), 16);
 | 
			
		||||
 | 
			
		||||
	Matrix = W;
 | 
			
		||||
	Matrix.makeInverse();
 | 
			
		||||
 | 
			
		||||
	const u32 LightCount = driver->getDynamicLightCount();
 | 
			
		||||
 | 
			
		||||
	for (u32 i = 0; i < 2; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		SLight CurrentLight;
 | 
			
		||||
 | 
			
		||||
		if (i < LightCount)
 | 
			
		||||
			CurrentLight = driver->getDynamicLight(i);
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			CurrentLight.DiffuseColor.set(0.f, 0.f, 0.f);
 | 
			
		||||
			CurrentLight.Radius = 1.f;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		CurrentLight.DiffuseColor.a = 1.f / (CurrentLight.Radius*CurrentLight.Radius);
 | 
			
		||||
 | 
			
		||||
		Matrix.transformVect(CurrentLight.Position);
 | 
			
		||||
 | 
			
		||||
		LightPosition[i] = CurrentLight.Position;
 | 
			
		||||
		LightColor[i] = CurrentLight.DiffuseColor;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	services->setPixelShaderConstant(LightPositionID, reinterpret_cast<f32*>(LightPosition), 6);
 | 
			
		||||
	services->setPixelShaderConstant(LightColorID, reinterpret_cast<f32*>(LightColor), 8);
 | 
			
		||||
 | 
			
		||||
	services->setPixelShaderConstant(TextureUnit0ID, &TextureUnit0, 1);
 | 
			
		||||
	services->setPixelShaderConstant(TextureUnit1ID, &TextureUnit1, 1);
 | 
			
		||||
 | 
			
		||||
	services->setPixelShaderConstant(FogEnableID, &FogEnable, 1);
 | 
			
		||||
 | 
			
		||||
	if (FogEnable)
 | 
			
		||||
	{
 | 
			
		||||
		SColor TempColor(0);
 | 
			
		||||
		E_FOG_TYPE TempType = EFT_FOG_LINEAR;
 | 
			
		||||
		bool TempPerFragment = false;
 | 
			
		||||
		bool TempRange = false;
 | 
			
		||||
 | 
			
		||||
		driver->getFog(TempColor, TempType, FogStart, FogEnd, FogDensity, TempPerFragment, TempRange);
 | 
			
		||||
 | 
			
		||||
		FogType = (s32)TempType;
 | 
			
		||||
		FogColor = SColorf(TempColor);
 | 
			
		||||
 | 
			
		||||
		services->setPixelShaderConstant(FogTypeID, &FogType, 1);
 | 
			
		||||
		services->setPixelShaderConstant(FogColorID, reinterpret_cast<f32*>(&FogColor), 4);
 | 
			
		||||
		services->setPixelShaderConstant(FogStartID, &FogStart, 1);
 | 
			
		||||
		services->setPixelShaderConstant(FogEndID, &FogEnd, 1);
 | 
			
		||||
		services->setPixelShaderConstant(FogDensityID, &FogDensity, 1);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,62 +0,0 @@
 | 
			
		||||
// Copyright (C) 2014 Patryk Nadrowski
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
 | 
			
		||||
 | 
			
		||||
#ifndef __C_OGLES2_NORMAL_MAP_RENDERER_H_INCLUDED__
 | 
			
		||||
#define __C_OGLES2_NORMAL_MAP_RENDERER_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "IrrCompileConfig.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OGLES2_
 | 
			
		||||
 | 
			
		||||
#include "IMaterialRenderer.h"
 | 
			
		||||
#include "IShaderConstantSetCallBack.h"
 | 
			
		||||
 | 
			
		||||
#include "COGLES2Common.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class COGLES2MaterialNormalMapCB : public IShaderConstantSetCallBack
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	COGLES2MaterialNormalMapCB();
 | 
			
		||||
 | 
			
		||||
	virtual void OnSetMaterial(const SMaterial& material);
 | 
			
		||||
	virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	bool FirstUpdate;
 | 
			
		||||
	s32 WVPMatrixID;
 | 
			
		||||
	s32 WVMatrixID;
 | 
			
		||||
	s32 LightPositionID;
 | 
			
		||||
	s32 LightColorID;
 | 
			
		||||
	s32 TextureUnit0ID;
 | 
			
		||||
	s32 TextureUnit1ID;
 | 
			
		||||
	s32 FogEnableID;
 | 
			
		||||
	s32 FogTypeID;
 | 
			
		||||
	s32 FogColorID;
 | 
			
		||||
	s32 FogStartID;
 | 
			
		||||
	s32 FogEndID;
 | 
			
		||||
	s32 FogDensityID;
 | 
			
		||||
 | 
			
		||||
	core::vector3df LightPosition[2];
 | 
			
		||||
	SColorf LightColor[2];
 | 
			
		||||
	s32 TextureUnit0;
 | 
			
		||||
	s32 TextureUnit1;
 | 
			
		||||
	s32 FogEnable;
 | 
			
		||||
	s32 FogType;
 | 
			
		||||
	SColorf FogColor;
 | 
			
		||||
	f32 FogStart;
 | 
			
		||||
	f32 FogEnd;
 | 
			
		||||
	f32 FogDensity;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,146 +0,0 @@
 | 
			
		||||
// Copyright (C) 2014 Patryk Nadrowski
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
 | 
			
		||||
 | 
			
		||||
#include "COGLES2ParallaxMapRenderer.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OGLES2_
 | 
			
		||||
 | 
			
		||||
#include "IMaterialRendererServices.h"
 | 
			
		||||
#include "IGPUProgrammingServices.h"
 | 
			
		||||
#include "IShaderConstantSetCallBack.h"
 | 
			
		||||
#include "IVideoDriver.h"
 | 
			
		||||
#include "SLight.h"
 | 
			
		||||
#include "os.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// EMT_PARALLAX_MAP_SOLID + EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR + EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA
 | 
			
		||||
 | 
			
		||||
COGLES2MaterialParallaxMapCB::COGLES2MaterialParallaxMapCB() :
 | 
			
		||||
	FirstUpdate(true), WVPMatrixID(-1), WVMatrixID(-1), EyePositionID(-1), LightPositionID(-1), LightColorID(-1), FactorID(-1), TextureUnit0ID(-1), TextureUnit1ID(-1),
 | 
			
		||||
	FogEnableID(-1), FogTypeID(-1), FogColorID(-1), FogStartID(-1), FogEndID(-1), FogDensityID(-1), Factor(0.02f), TextureUnit0(0), TextureUnit1(1),
 | 
			
		||||
	FogEnable(0), FogType(1), FogColor(SColorf(0.f, 0.f, 0.f, 1.f)), FogStart(0.f), FogEnd(0.f), FogDensity(0.f)
 | 
			
		||||
{
 | 
			
		||||
	for (u32 i = 0; i < 2; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		LightPosition[i] = core::vector3df(0.f, 0.f, 0.f);
 | 
			
		||||
		LightColor[i] = SColorf(0.f, 0.f, 0.f, 1.f);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void COGLES2MaterialParallaxMapCB::OnSetMaterial(const SMaterial& material)
 | 
			
		||||
{
 | 
			
		||||
	if (!core::equals(material.MaterialTypeParam, 0.f))
 | 
			
		||||
		Factor = material.MaterialTypeParam;
 | 
			
		||||
	else
 | 
			
		||||
		Factor = 0.02f;
 | 
			
		||||
 | 
			
		||||
	if (material.FogEnable)
 | 
			
		||||
		FogEnable = 1;
 | 
			
		||||
	else
 | 
			
		||||
		FogEnable = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void COGLES2MaterialParallaxMapCB::OnSetConstants(IMaterialRendererServices* services, s32 userData)
 | 
			
		||||
{
 | 
			
		||||
	IVideoDriver* driver = services->getVideoDriver();
 | 
			
		||||
 | 
			
		||||
	if (FirstUpdate)
 | 
			
		||||
	{
 | 
			
		||||
		WVPMatrixID = services->getVertexShaderConstantID("uWVPMatrix");
 | 
			
		||||
		WVMatrixID = services->getVertexShaderConstantID("uWVMatrix");
 | 
			
		||||
		EyePositionID = services->getVertexShaderConstantID("uEyePosition");
 | 
			
		||||
		LightPositionID = services->getVertexShaderConstantID("uLightPosition");
 | 
			
		||||
		LightColorID = services->getVertexShaderConstantID("uLightColor");
 | 
			
		||||
		FactorID = services->getVertexShaderConstantID("uFactor");
 | 
			
		||||
		TextureUnit0ID = services->getVertexShaderConstantID("uTextureUnit0");
 | 
			
		||||
		TextureUnit1ID = services->getVertexShaderConstantID("uTextureUnit1");
 | 
			
		||||
		FogEnableID = services->getVertexShaderConstantID("uFogEnable");
 | 
			
		||||
		FogTypeID = services->getVertexShaderConstantID("uFogType");
 | 
			
		||||
		FogColorID = services->getVertexShaderConstantID("uFogColor");
 | 
			
		||||
		FogStartID = services->getVertexShaderConstantID("uFogStart");
 | 
			
		||||
		FogEndID = services->getVertexShaderConstantID("uFogEnd");
 | 
			
		||||
		FogDensityID = services->getVertexShaderConstantID("uFogDensity");
 | 
			
		||||
 | 
			
		||||
		FirstUpdate = false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const core::matrix4 W = driver->getTransform(ETS_WORLD);
 | 
			
		||||
	const core::matrix4 V = driver->getTransform(ETS_VIEW);
 | 
			
		||||
	const core::matrix4 P = driver->getTransform(ETS_PROJECTION);
 | 
			
		||||
 | 
			
		||||
	core::matrix4 Matrix = P * V * W;
 | 
			
		||||
	services->setPixelShaderConstant(WVPMatrixID, Matrix.pointer(), 16);
 | 
			
		||||
 | 
			
		||||
	Matrix = V * W;
 | 
			
		||||
	services->setPixelShaderConstant(WVMatrixID, Matrix.pointer(), 16);
 | 
			
		||||
 | 
			
		||||
	core::vector3df EyePosition(0.0f, 0.0f, 0.0f);
 | 
			
		||||
 | 
			
		||||
	Matrix.makeInverse();
 | 
			
		||||
	Matrix.transformVect(EyePosition);
 | 
			
		||||
	services->setPixelShaderConstant(EyePositionID, reinterpret_cast<f32*>(&EyePosition), 3);
 | 
			
		||||
 | 
			
		||||
	Matrix = W;
 | 
			
		||||
	Matrix.makeInverse();
 | 
			
		||||
 | 
			
		||||
	const u32 LightCount = driver->getDynamicLightCount();
 | 
			
		||||
 | 
			
		||||
	for (u32 i = 0; i < 2; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		SLight CurrentLight;
 | 
			
		||||
 | 
			
		||||
		if (i < LightCount)
 | 
			
		||||
			CurrentLight = driver->getDynamicLight(i);
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			CurrentLight.DiffuseColor.set(0.f, 0.f, 0.f);
 | 
			
		||||
			CurrentLight.Radius = 1.f;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		CurrentLight.DiffuseColor.a = 1.f / (CurrentLight.Radius*CurrentLight.Radius);
 | 
			
		||||
 | 
			
		||||
		Matrix.transformVect(CurrentLight.Position);
 | 
			
		||||
 | 
			
		||||
		LightPosition[i] = CurrentLight.Position;
 | 
			
		||||
		LightColor[i] = CurrentLight.DiffuseColor;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	services->setPixelShaderConstant(LightPositionID, reinterpret_cast<f32*>(LightPosition), 6);
 | 
			
		||||
	services->setPixelShaderConstant(LightColorID, reinterpret_cast<f32*>(LightColor), 8);
 | 
			
		||||
 | 
			
		||||
	services->setPixelShaderConstant(FactorID, &Factor, 1);
 | 
			
		||||
	services->setPixelShaderConstant(TextureUnit0ID, &TextureUnit0, 1);
 | 
			
		||||
	services->setPixelShaderConstant(TextureUnit1ID, &TextureUnit1, 1);
 | 
			
		||||
 | 
			
		||||
	services->setPixelShaderConstant(FogEnableID, &FogEnable, 1);
 | 
			
		||||
 | 
			
		||||
	if (FogEnable)
 | 
			
		||||
	{
 | 
			
		||||
		SColor TempColor(0);
 | 
			
		||||
		E_FOG_TYPE TempType = EFT_FOG_LINEAR;
 | 
			
		||||
		bool TempPerFragment = false;
 | 
			
		||||
		bool TempRange = false;
 | 
			
		||||
 | 
			
		||||
		driver->getFog(TempColor, TempType, FogStart, FogEnd, FogDensity, TempPerFragment, TempRange);
 | 
			
		||||
 | 
			
		||||
		FogType = (s32)TempType;
 | 
			
		||||
		FogColor = SColorf(TempColor);
 | 
			
		||||
 | 
			
		||||
		services->setPixelShaderConstant(FogTypeID, &FogType, 1);
 | 
			
		||||
		services->setPixelShaderConstant(FogColorID, reinterpret_cast<f32*>(&FogColor), 4);
 | 
			
		||||
		services->setPixelShaderConstant(FogStartID, &FogStart, 1);
 | 
			
		||||
		services->setPixelShaderConstant(FogEndID, &FogEnd, 1);
 | 
			
		||||
		services->setPixelShaderConstant(FogDensityID, &FogDensity, 1);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
// Copyright (C) 2014 Patryk Nadrowski
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
 | 
			
		||||
 | 
			
		||||
#ifndef __C_OGLES2_PARALLAX_MAP_RENDERER_H_INCLUDED__
 | 
			
		||||
#define __C_OGLES2_PARALLAX_MAP_RENDERER_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "IrrCompileConfig.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OGLES2_
 | 
			
		||||
 | 
			
		||||
#include "IMaterialRenderer.h"
 | 
			
		||||
#include "IShaderConstantSetCallBack.h"
 | 
			
		||||
 | 
			
		||||
#include "COGLES2Common.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class COGLES2MaterialParallaxMapCB : public IShaderConstantSetCallBack
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	COGLES2MaterialParallaxMapCB();
 | 
			
		||||
 | 
			
		||||
	virtual void OnSetMaterial(const SMaterial& material);
 | 
			
		||||
	virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	bool FirstUpdate;
 | 
			
		||||
	s32 WVPMatrixID;
 | 
			
		||||
	s32 WVMatrixID;
 | 
			
		||||
	s32 EyePositionID;
 | 
			
		||||
	s32 LightPositionID;
 | 
			
		||||
	s32 LightColorID;
 | 
			
		||||
	s32 FactorID;
 | 
			
		||||
	s32 TextureUnit0ID;
 | 
			
		||||
	s32 TextureUnit1ID;
 | 
			
		||||
	s32 FogEnableID;
 | 
			
		||||
	s32 FogTypeID;
 | 
			
		||||
	s32 FogColorID;
 | 
			
		||||
	s32 FogStartID;
 | 
			
		||||
	s32 FogEndID;
 | 
			
		||||
	s32 FogDensityID;
 | 
			
		||||
 | 
			
		||||
	core::vector3df LightPosition[2];
 | 
			
		||||
	SColorf LightColor[2];
 | 
			
		||||
	f32 Factor;
 | 
			
		||||
	s32 TextureUnit0;
 | 
			
		||||
	s32 TextureUnit1;
 | 
			
		||||
	s32 FogEnable;
 | 
			
		||||
	s32 FogType;
 | 
			
		||||
	SColorf FogColor;
 | 
			
		||||
	f32 FogStart;
 | 
			
		||||
	f32 FogEnd;
 | 
			
		||||
	f32 FogDensity;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -184,17 +184,6 @@ void COGLES1Driver::createMaterialRenderers()
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(this));
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(this));
 | 
			
		||||
 | 
			
		||||
	// add normal map renderers
 | 
			
		||||
// TODO ogl-es
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_SOLID(this));
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_SOLID(this));
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_SOLID(this));
 | 
			
		||||
 | 
			
		||||
	// add parallax map renderers
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_SOLID(this));
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_SOLID(this));
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_SOLID(this));
 | 
			
		||||
 | 
			
		||||
	// add basic 1 texture blending
 | 
			
		||||
	addAndDropMaterialRenderer(new COGLES1MaterialRenderer_ONETEXTURE_BLEND(this));
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,6 @@
 | 
			
		||||
#include "COpenGLMaterialRenderer.h"
 | 
			
		||||
#include "COpenGLShaderMaterialRenderer.h"
 | 
			
		||||
#include "COpenGLSLMaterialRenderer.h"
 | 
			
		||||
#include "COpenGLNormalMapRenderer.h"
 | 
			
		||||
#include "COpenGLParallaxMapRenderer.h"
 | 
			
		||||
 | 
			
		||||
#include "COpenGLCoreTexture.h"
 | 
			
		||||
#include "COpenGLCoreRenderTarget.h"
 | 
			
		||||
@@ -258,24 +256,6 @@ void COpenGLDriver::createMaterialRenderers()
 | 
			
		||||
	addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_VERTEX_ALPHA(this));
 | 
			
		||||
	addAndDropMaterialRenderer(new COpenGLMaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(this));
 | 
			
		||||
 | 
			
		||||
	// add normal map renderers
 | 
			
		||||
	s32 tmp = 0;
 | 
			
		||||
	video::IMaterialRenderer* renderer = 0;
 | 
			
		||||
	renderer = new COpenGLNormalMapRenderer(this, tmp, EMT_SOLID);
 | 
			
		||||
	renderer->drop();
 | 
			
		||||
	renderer = new COpenGLNormalMapRenderer(this, tmp, EMT_TRANSPARENT_ADD_COLOR);
 | 
			
		||||
	renderer->drop();
 | 
			
		||||
	renderer = new COpenGLNormalMapRenderer(this, tmp, EMT_TRANSPARENT_VERTEX_ALPHA);
 | 
			
		||||
	renderer->drop();
 | 
			
		||||
 | 
			
		||||
	// add parallax map renderers
 | 
			
		||||
	renderer = new COpenGLParallaxMapRenderer(this, tmp, EMT_SOLID);
 | 
			
		||||
	renderer->drop();
 | 
			
		||||
	renderer = new COpenGLParallaxMapRenderer(this, tmp, EMT_TRANSPARENT_ADD_COLOR);
 | 
			
		||||
	renderer->drop();
 | 
			
		||||
	renderer = new COpenGLParallaxMapRenderer(this, tmp, EMT_TRANSPARENT_VERTEX_ALPHA);
 | 
			
		||||
	renderer->drop();
 | 
			
		||||
 | 
			
		||||
	// add basic 1 texture blending
 | 
			
		||||
	addAndDropMaterialRenderer(new COpenGLMaterialRenderer_ONETEXTURE_BLEND(this));
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,292 +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 "COpenGLNormalMapRenderer.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
 | 
			
		||||
 | 
			
		||||
#include "IGPUProgrammingServices.h"
 | 
			
		||||
#include "IShaderConstantSetCallBack.h"
 | 
			
		||||
#include "IVideoDriver.h"
 | 
			
		||||
#include "os.h"
 | 
			
		||||
 | 
			
		||||
#include "COpenGLDriver.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// Irrlicht Engine OpenGL render path normal map vertex shader
 | 
			
		||||
// I guess it could be optimized a lot, because I wrote it in D3D ASM and
 | 
			
		||||
// transferred it 1:1 to OpenGL
 | 
			
		||||
const char OPENGL_NORMAL_MAP_VSH[] =
 | 
			
		||||
	"!!ARBvp1.0\n"\
 | 
			
		||||
	"#input\n"\
 | 
			
		||||
	"# 0-3: transposed world matrix;\n"\
 | 
			
		||||
	"#;12: Light01 position \n"\
 | 
			
		||||
	"#;13: x,y,z: Light01 color; .w: 1/LightRadius^2 \n"\
 | 
			
		||||
	"#;14: Light02 position \n"\
 | 
			
		||||
	"#;15: x,y,z: Light02 color; .w: 1/LightRadius^2 \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"ATTRIB InPos = vertex.position;\n"\
 | 
			
		||||
	"ATTRIB InColor = vertex.color;\n"\
 | 
			
		||||
	"ATTRIB InNormal = vertex.normal;\n"\
 | 
			
		||||
	"ATTRIB InTexCoord = vertex.texcoord[0];\n"\
 | 
			
		||||
	"ATTRIB InTangent = vertex.texcoord[1];\n"\
 | 
			
		||||
	"ATTRIB InBinormal = vertex.texcoord[2];\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"#output\n"\
 | 
			
		||||
	"OUTPUT OutPos = result.position;\n"\
 | 
			
		||||
	"OUTPUT OutLightColor1 = result.color.primary;\n"\
 | 
			
		||||
	"OUTPUT OutLightColor2 = result.color.secondary;\n"\
 | 
			
		||||
	"OUTPUT OutTexCoord = result.texcoord[0];\n"\
 | 
			
		||||
	"OUTPUT OutLightVector1 = result.texcoord[1];\n"\
 | 
			
		||||
	"OUTPUT OutLightVector2 = result.texcoord[2];\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.\n"\
 | 
			
		||||
	"TEMP Temp;\n"\
 | 
			
		||||
	"TEMP TempColor;\n"\
 | 
			
		||||
	"TEMP TempLightVector1;\n"\
 | 
			
		||||
	"TEMP TempLightVector2;\n"\
 | 
			
		||||
	"TEMP TempTransLightV1;\n"\
 | 
			
		||||
	"TEMP TempTransLightV2;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# transform position to clip space \n"\
 | 
			
		||||
	"DP4 OutPos.x, MVP[0], InPos;\n"\
 | 
			
		||||
	"DP4 OutPos.y, MVP[1], InPos;\n"\
 | 
			
		||||
	"DP4 Temp.z, MVP[2], InPos;\n"\
 | 
			
		||||
	"DP4 OutPos.w, MVP[3], InPos;\n"\
 | 
			
		||||
	"MOV OutPos.z, Temp.z;\n"\
 | 
			
		||||
	"MOV result.fogcoord.x, Temp.z;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# vertex - lightpositions \n"\
 | 
			
		||||
	"SUB TempLightVector1, program.local[12], InPos; \n"\
 | 
			
		||||
	"SUB TempLightVector2, program.local[14], InPos; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# transform the light vector 1 with U, V, W \n"\
 | 
			
		||||
	"DP3 TempTransLightV1.x, InTangent, TempLightVector1; \n"\
 | 
			
		||||
	"DP3 TempTransLightV1.y, InBinormal, TempLightVector1; \n"\
 | 
			
		||||
	"DP3 TempTransLightV1.z, InNormal, TempLightVector1; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# transform the light vector 2 with U, V, W \n"\
 | 
			
		||||
	"DP3 TempTransLightV2.x, InTangent, TempLightVector2; \n"\
 | 
			
		||||
	"DP3 TempTransLightV2.y, InBinormal, TempLightVector2; \n"\
 | 
			
		||||
	"DP3 TempTransLightV2.z, InNormal, TempLightVector2; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# normalize light vector 1 \n"\
 | 
			
		||||
	"DP3 TempTransLightV1.w, TempTransLightV1, TempTransLightV1; \n"\
 | 
			
		||||
	"RSQ TempTransLightV1.w, TempTransLightV1.w; \n"\
 | 
			
		||||
	"MUL TempTransLightV1, TempTransLightV1, TempTransLightV1.w;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# normalize light vector 2 \n"\
 | 
			
		||||
	"DP3 TempTransLightV2.w, TempTransLightV2, TempTransLightV2; \n"\
 | 
			
		||||
	"RSQ TempTransLightV2.w, TempTransLightV2.w; \n"\
 | 
			
		||||
	"MUL TempTransLightV2, TempTransLightV2, TempTransLightV2.w;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# move light vectors out\n"\
 | 
			
		||||
	"MAD OutLightVector1, TempTransLightV1, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\
 | 
			
		||||
	"MAD OutLightVector2, TempTransLightV2, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate attenuation of light 1\n"\
 | 
			
		||||
	"MOV TempLightVector1.w, {0,0,0,0}; \n"\
 | 
			
		||||
	"DP3 TempLightVector1.x, TempLightVector1, TempLightVector1; \n"\
 | 
			
		||||
	"MUL TempLightVector1.x, TempLightVector1.x, program.local[13].w;  \n"\
 | 
			
		||||
	"RSQ TempLightVector1, TempLightVector1.x; \n"\
 | 
			
		||||
	"MUL OutLightColor1, TempLightVector1, program.local[13]; # resulting light color = lightcolor * attenuation \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate attenuation of light 2\n"\
 | 
			
		||||
	"MOV TempLightVector2.w, {0,0,0,0}; \n"\
 | 
			
		||||
	"DP3 TempLightVector2.x, TempLightVector2, TempLightVector2; \n"\
 | 
			
		||||
	"MUL TempLightVector2.x, TempLightVector2.x, program.local[15].w;  \n"\
 | 
			
		||||
	"RSQ TempLightVector2, TempLightVector2.x; \n"\
 | 
			
		||||
	"MUL OutLightColor2, TempLightVector2, program.local[15]; # resulting light color = lightcolor * attenuation \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# move out texture coordinates and original alpha value\n"\
 | 
			
		||||
	"MOV OutTexCoord, InTexCoord; \n"\
 | 
			
		||||
	"MOV OutLightColor1.w, InColor.w; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"END\n";
 | 
			
		||||
 | 
			
		||||
// Irrlicht Engine OpenGL render path normal map pixel shader
 | 
			
		||||
// I guess it could be optimized a bit, because I wrote it in D3D ASM and
 | 
			
		||||
// transfered it 1:1 to OpenGL
 | 
			
		||||
const char OPENGL_NORMAL_MAP_PSH[] =
 | 
			
		||||
	"!!ARBfp1.0\n"\
 | 
			
		||||
	"#_IRR_FOG_MODE_\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"#Input\n"\
 | 
			
		||||
	"ATTRIB inTexCoord = fragment.texcoord[0];   \n"\
 | 
			
		||||
	"ATTRIB light1Vector = fragment.texcoord[1]; \n"\
 | 
			
		||||
	"ATTRIB light2Vector = fragment.texcoord[2];    \n"\
 | 
			
		||||
	"ATTRIB light1Color = fragment.color.primary;   \n"\
 | 
			
		||||
	"ATTRIB light2Color = fragment.color.secondary; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"#Output\n"\
 | 
			
		||||
	"OUTPUT outColor = result.color;\n"\
 | 
			
		||||
	"TEMP temp;\n"\
 | 
			
		||||
	"TEMP temp2;\n"\
 | 
			
		||||
	"TEMP colorMapColor;\n"\
 | 
			
		||||
	"TEMP normalMapColor;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# fetch color and normal map; \n"\
 | 
			
		||||
	"TXP colorMapColor, inTexCoord, texture[0], 2D; \n"\
 | 
			
		||||
	"TXP normalMapColor, inTexCoord, texture[1], 2D; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate color of light1; \n"\
 | 
			
		||||
	"MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
 | 
			
		||||
	"MAD temp, light1Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
 | 
			
		||||
	"DP3_SAT temp, normalMapColor, temp; \n"\
 | 
			
		||||
	"MUL temp, light1Color, temp; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate color of light2; \n"\
 | 
			
		||||
	"MAD temp2, light2Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
 | 
			
		||||
	"DP3_SAT temp2, normalMapColor, temp2; \n"\
 | 
			
		||||
	"MAD temp, light2Color, temp2, temp; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# luminance * base color; \n"\
 | 
			
		||||
	"MUL outColor, temp, colorMapColor; \n"\
 | 
			
		||||
	"MOV outColor.a, light1Color.a; #write interpolated vertex alpha value\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"END\n";
 | 
			
		||||
 | 
			
		||||
//! Constructor
 | 
			
		||||
COpenGLNormalMapRenderer::COpenGLNormalMapRenderer(video::COpenGLDriver* driver,
 | 
			
		||||
	s32& outMaterialTypeNr, E_MATERIAL_TYPE baseMaterial)
 | 
			
		||||
	: COpenGLShaderMaterialRenderer(driver, 0, baseMaterial), CompiledShaders(true)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	#ifdef _DEBUG
 | 
			
		||||
	setDebugName("COpenGLNormalMapRenderer");
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	// set this as callback. We could have done this in
 | 
			
		||||
	// the initialization list, but some compilers don't like it.
 | 
			
		||||
 | 
			
		||||
	CallBack = this;
 | 
			
		||||
 | 
			
		||||
	// basically, this thing simply compiles the hardcoded shaders if the
 | 
			
		||||
	// hardware is able to do them, otherwise it maps to the base material
 | 
			
		||||
 | 
			
		||||
	if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) ||
 | 
			
		||||
		!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
 | 
			
		||||
	{
 | 
			
		||||
		// this hardware is not able to do shaders. Fall back to
 | 
			
		||||
		// base material.
 | 
			
		||||
		outMaterialTypeNr = driver->addMaterialRenderer(this);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check if already compiled normal map shaders are there.
 | 
			
		||||
 | 
			
		||||
	video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_NORMAL_MAP_SOLID);
 | 
			
		||||
 | 
			
		||||
	if (renderer)
 | 
			
		||||
	{
 | 
			
		||||
		// use the already compiled shaders
 | 
			
		||||
		video::COpenGLNormalMapRenderer* nmr = reinterpret_cast<video::COpenGLNormalMapRenderer*>(renderer);
 | 
			
		||||
		CompiledShaders = false;
 | 
			
		||||
 | 
			
		||||
		VertexShader = nmr->VertexShader;
 | 
			
		||||
		PixelShader = nmr->PixelShader;
 | 
			
		||||
 | 
			
		||||
		outMaterialTypeNr = driver->addMaterialRenderer(this);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// compile shaders on our own
 | 
			
		||||
		init(outMaterialTypeNr, OPENGL_NORMAL_MAP_VSH, OPENGL_NORMAL_MAP_PSH, EVT_TANGENTS);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// fallback if compilation has failed
 | 
			
		||||
	if (-1==outMaterialTypeNr)
 | 
			
		||||
		outMaterialTypeNr = driver->addMaterialRenderer(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Destructor
 | 
			
		||||
COpenGLNormalMapRenderer::~COpenGLNormalMapRenderer()
 | 
			
		||||
{
 | 
			
		||||
	if (CallBack == this)
 | 
			
		||||
		CallBack = 0;
 | 
			
		||||
 | 
			
		||||
	if (!CompiledShaders)
 | 
			
		||||
	{
 | 
			
		||||
		// prevent this from deleting shaders we did not create
 | 
			
		||||
		VertexShader = 0;
 | 
			
		||||
		PixelShader.clear();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Returns the render capability of the material.
 | 
			
		||||
s32 COpenGLNormalMapRenderer::getRenderCapability() const
 | 
			
		||||
{
 | 
			
		||||
	if (Driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) &&
 | 
			
		||||
		Driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Called by the engine when the vertex and/or pixel shader constants for an
 | 
			
		||||
//! material renderer should be set.
 | 
			
		||||
void COpenGLNormalMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData)
 | 
			
		||||
{
 | 
			
		||||
	video::IVideoDriver* driver = services->getVideoDriver();
 | 
			
		||||
 | 
			
		||||
	// set transposed world matrix
 | 
			
		||||
	const core::matrix4& tWorld = driver->getTransform(video::ETS_WORLD).getTransposed();
 | 
			
		||||
	services->setVertexShaderConstant(tWorld.pointer(), 0, 4);
 | 
			
		||||
 | 
			
		||||
	// set transposed worldViewProj matrix
 | 
			
		||||
	core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
 | 
			
		||||
	worldViewProj *= driver->getTransform(video::ETS_VIEW);
 | 
			
		||||
	worldViewProj *= driver->getTransform(video::ETS_WORLD);
 | 
			
		||||
	core::matrix4 tr(worldViewProj.getTransposed());
 | 
			
		||||
	services->setVertexShaderConstant(tr.pointer(), 8, 4);
 | 
			
		||||
 | 
			
		||||
	// here we fetch the fixed function lights from the driver
 | 
			
		||||
	// and set them as constants
 | 
			
		||||
 | 
			
		||||
	u32 cnt = driver->getDynamicLightCount();
 | 
			
		||||
 | 
			
		||||
	// Load the inverse world matrix.
 | 
			
		||||
	core::matrix4 invWorldMat;
 | 
			
		||||
	driver->getTransform(video::ETS_WORLD).getInverse(invWorldMat);
 | 
			
		||||
 | 
			
		||||
	for (u32 i=0; i<2; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		video::SLight light;
 | 
			
		||||
 | 
			
		||||
		if (i<cnt)
 | 
			
		||||
			light = driver->getDynamicLight(i);
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			light.DiffuseColor.set(0,0,0); // make light dark
 | 
			
		||||
			light.Radius = 1.0f;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation
 | 
			
		||||
 | 
			
		||||
		// Transform the light by the inverse world matrix to get it into object space.
 | 
			
		||||
		invWorldMat.transformVect(light.Position);
 | 
			
		||||
 | 
			
		||||
		services->setVertexShaderConstant(
 | 
			
		||||
			reinterpret_cast<const f32*>(&light.Position), 12+(i*2), 1);
 | 
			
		||||
 | 
			
		||||
		services->setVertexShaderConstant(
 | 
			
		||||
			reinterpret_cast<const f32*>(&light.DiffuseColor), 13+(i*2), 1);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace video
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,51 +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_OPENGL_NORMAL_MAP_RENDERER_H_INCLUDED__
 | 
			
		||||
#define __C_OPENGL_NORMAL_MAP_RENDERER_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "IrrCompileConfig.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
 | 
			
		||||
 | 
			
		||||
#include "IShaderConstantSetCallBack.h"
 | 
			
		||||
 | 
			
		||||
#include "COpenGLShaderMaterialRenderer.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//! Class for rendering normal maps with OpenGL
 | 
			
		||||
class COpenGLNormalMapRenderer : public COpenGLShaderMaterialRenderer, public IShaderConstantSetCallBack
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	//! Constructor
 | 
			
		||||
	COpenGLNormalMapRenderer(video::COpenGLDriver* driver,
 | 
			
		||||
		s32& outMaterialTypeNr, E_MATERIAL_TYPE baseMaterial);
 | 
			
		||||
 | 
			
		||||
	//! Destructor
 | 
			
		||||
	~COpenGLNormalMapRenderer();
 | 
			
		||||
 | 
			
		||||
	//! Called by the engine when the vertex and/or pixel shader constants for an
 | 
			
		||||
	//! material renderer should be set.
 | 
			
		||||
	virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData) _IRR_OVERRIDE_;
 | 
			
		||||
 | 
			
		||||
	//! Returns the render capability of the material.
 | 
			
		||||
	virtual s32 getRenderCapability() const _IRR_OVERRIDE_;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
	bool CompiledShaders;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace video
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,355 +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 "COpenGLParallaxMapRenderer.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
 | 
			
		||||
 | 
			
		||||
#include "IGPUProgrammingServices.h"
 | 
			
		||||
#include "IShaderConstantSetCallBack.h"
 | 
			
		||||
#include "IVideoDriver.h"
 | 
			
		||||
#include "os.h"
 | 
			
		||||
 | 
			
		||||
#include "COpenGLDriver.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// Irrlicht Engine OpenGL render path parallax map vertex shader
 | 
			
		||||
// I guess it could be optimized a lot, because I wrote it in D3D ASM and
 | 
			
		||||
// transferred it 1:1 to OpenGL
 | 
			
		||||
const char OPENGL_PARALLAX_MAP_VSH[] =
 | 
			
		||||
	"!!ARBvp1.0\n"\
 | 
			
		||||
	"#input\n"\
 | 
			
		||||
	"# 0-3: transposed world matrix;\n"\
 | 
			
		||||
	"#;12: Light01 position \n"\
 | 
			
		||||
	"#;13: x,y,z: Light01 color; .w: 1/LightRadius^2 \n"\
 | 
			
		||||
	"#;14: Light02 position \n"\
 | 
			
		||||
	"#;15: x,y,z: Light02 color; .w: 1/LightRadius^2 \n"\
 | 
			
		||||
	"#;16: Eye position \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"ATTRIB InPos = vertex.position;\n"\
 | 
			
		||||
	"ATTRIB InColor = vertex.color;\n"\
 | 
			
		||||
	"ATTRIB InNormal = vertex.normal;\n"\
 | 
			
		||||
	"ATTRIB InTexCoord = vertex.texcoord[0];\n"\
 | 
			
		||||
	"ATTRIB InTangent = vertex.texcoord[1];\n"\
 | 
			
		||||
	"ATTRIB InBinormal = vertex.texcoord[2];\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"#output\n"\
 | 
			
		||||
	"OUTPUT OutPos = result.position;\n"\
 | 
			
		||||
	"OUTPUT OutLightColor1 = result.color.primary;\n"\
 | 
			
		||||
	"OUTPUT OutLightColor2 = result.color.secondary;\n"\
 | 
			
		||||
	"OUTPUT OutTexCoord = result.texcoord[0];\n"\
 | 
			
		||||
	"OUTPUT OutLightVector1 = result.texcoord[1];\n"\
 | 
			
		||||
	"OUTPUT OutLightVector2 = result.texcoord[2];\n"\
 | 
			
		||||
	"OUTPUT OutEyeVector = result.texcoord[3];\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"PARAM MVP[4] = { state.matrix.mvp }; # modelViewProjection matrix.\n"\
 | 
			
		||||
	"TEMP Temp;\n"\
 | 
			
		||||
	"TEMP TempColor;\n"\
 | 
			
		||||
	"TEMP TempLightVector1;\n"\
 | 
			
		||||
	"TEMP TempLightVector2;\n"\
 | 
			
		||||
	"TEMP TempEyeVector;\n"\
 | 
			
		||||
	"TEMP TempTransLightV1;\n"\
 | 
			
		||||
	"TEMP TempTransLightV2;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# transform position to clip space \n"\
 | 
			
		||||
	"DP4 OutPos.x, MVP[0], InPos;\n"\
 | 
			
		||||
	"DP4 OutPos.y, MVP[1], InPos;\n"\
 | 
			
		||||
	"DP4 Temp.z, MVP[2], InPos;\n"\
 | 
			
		||||
	"DP4 OutPos.w, MVP[3], InPos;\n"\
 | 
			
		||||
	"MOV OutPos.z, Temp.z;\n"\
 | 
			
		||||
	"MOV result.fogcoord.x, Temp.z;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# vertex - lightpositions \n"\
 | 
			
		||||
	"SUB TempLightVector1, program.local[12], InPos; \n"\
 | 
			
		||||
	"SUB TempLightVector2, program.local[14], InPos; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# eye vector \n"\
 | 
			
		||||
	"SUB Temp, program.local[16], InPos; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# transform the light vector 1 with U, V, W \n"\
 | 
			
		||||
	"DP3 TempTransLightV1.x, InTangent, TempLightVector1; \n"\
 | 
			
		||||
	"DP3 TempTransLightV1.y, InBinormal, TempLightVector1; \n"\
 | 
			
		||||
	"DP3 TempTransLightV1.z, InNormal, TempLightVector1; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# transform the light vector 2 with U, V, W \n"\
 | 
			
		||||
	"DP3 TempTransLightV2.x, InTangent, TempLightVector2; \n"\
 | 
			
		||||
	"DP3 TempTransLightV2.y, InBinormal, TempLightVector2; \n"\
 | 
			
		||||
	"DP3 TempTransLightV2.z, InNormal, TempLightVector2; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# transform the eye vector with U, V, W \n"\
 | 
			
		||||
	"DP3 TempEyeVector.x, InTangent, Temp; \n"\
 | 
			
		||||
	"DP3 TempEyeVector.y, InBinormal, Temp; \n"\
 | 
			
		||||
	"DP3 TempEyeVector.z, InNormal, Temp; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# normalize light vector 1 \n"\
 | 
			
		||||
	"DP3 TempTransLightV1.w, TempTransLightV1, TempTransLightV1; \n"\
 | 
			
		||||
	"RSQ TempTransLightV1.w, TempTransLightV1.w; \n"\
 | 
			
		||||
	"MUL TempTransLightV1, TempTransLightV1, TempTransLightV1.w;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# normalize light vector 2 \n"\
 | 
			
		||||
	"DP3 TempTransLightV2.w, TempTransLightV2, TempTransLightV2; \n"\
 | 
			
		||||
	"RSQ TempTransLightV2.w, TempTransLightV2.w; \n"\
 | 
			
		||||
	"MUL TempTransLightV2, TempTransLightV2, TempTransLightV2.w;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# normalize eye vector \n"\
 | 
			
		||||
	"DP3 TempEyeVector.w, TempEyeVector, TempEyeVector; \n"\
 | 
			
		||||
	"RSQ TempEyeVector.w, TempEyeVector.w; \n"\
 | 
			
		||||
	"MUL TempEyeVector, TempEyeVector, TempEyeVector.w;\n"\
 | 
			
		||||
	"MUL TempEyeVector, TempEyeVector, {1,-1,-1,1}; # flip x \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# move light and eye vectors out\n"\
 | 
			
		||||
	"MAD OutLightVector1, TempTransLightV1, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\
 | 
			
		||||
	"MAD OutLightVector2, TempTransLightV2, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\
 | 
			
		||||
	"MAD OutEyeVector, TempEyeVector, {0.5,0.5,0.5,0.5}, {0.5,0.5,0.5,0.5}; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate attenuation of light 1\n"\
 | 
			
		||||
	"MOV TempLightVector1.w, {0,0,0,0}; \n"\
 | 
			
		||||
	"DP3 TempLightVector1.x, TempLightVector1, TempLightVector1; \n"\
 | 
			
		||||
	"MUL TempLightVector1.x, TempLightVector1.x, program.local[13].w;  \n"\
 | 
			
		||||
	"RSQ TempLightVector1, TempLightVector1.x; \n"\
 | 
			
		||||
	"MUL OutLightColor1, TempLightVector1, program.local[13]; # resulting light color = lightcolor * attenuation \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate attenuation of light 2\n"\
 | 
			
		||||
	"MOV TempLightVector2.w, {0,0,0,0}; \n"\
 | 
			
		||||
	"DP3 TempLightVector2.x, TempLightVector2, TempLightVector2; \n"\
 | 
			
		||||
	"MUL TempLightVector2.x, TempLightVector2.x, program.local[15].w;  \n"\
 | 
			
		||||
	"RSQ TempLightVector2, TempLightVector2.x; \n"\
 | 
			
		||||
	"MUL OutLightColor2, TempLightVector2, program.local[15]; # resulting light color = lightcolor * attenuation \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# move out texture coordinates and original alpha value\n"\
 | 
			
		||||
	"MOV OutTexCoord, InTexCoord; \n"\
 | 
			
		||||
	"MOV OutLightColor1.w, InColor.w; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"END\n";
 | 
			
		||||
 | 
			
		||||
// Irrlicht Engine OpenGL render path parallax map pixel shader
 | 
			
		||||
// I guess it could be optimized a bit, because I wrote it in D3D ASM and
 | 
			
		||||
// transfered it 1:1 to OpenGL
 | 
			
		||||
const char OPENGL_PARALLAX_MAP_PSH[] =
 | 
			
		||||
	"!!ARBfp1.0\n"\
 | 
			
		||||
	"#_IRR_FOG_MODE_\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"#Input\n"\
 | 
			
		||||
	"ATTRIB inTexCoord = fragment.texcoord[0];   \n"\
 | 
			
		||||
	"ATTRIB light1Vector = fragment.texcoord[1]; \n"\
 | 
			
		||||
	"ATTRIB light2Vector = fragment.texcoord[2];    \n"\
 | 
			
		||||
	"ATTRIB eyeVector = fragment.texcoord[3];    \n"\
 | 
			
		||||
	"ATTRIB light1Color = fragment.color.primary;   \n"\
 | 
			
		||||
	"ATTRIB light2Color = fragment.color.secondary; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"#Output\n"\
 | 
			
		||||
	"OUTPUT outColor = result.color;\n"\
 | 
			
		||||
	"TEMP temp;\n"\
 | 
			
		||||
	"TEMP temp2;\n"\
 | 
			
		||||
	"TEMP colorMapColor;\n"\
 | 
			
		||||
	"TEMP normalMapColor;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"PARAM height_scale = program.local[0]; \n"\
 | 
			
		||||
	"# fetch color and normal map; \n"\
 | 
			
		||||
	"TXP normalMapColor, inTexCoord, texture[1], 2D; \n"\
 | 
			
		||||
	"MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# extract eye vector (so substract 0.5f and multiply by 2)\n"\
 | 
			
		||||
	"MAD temp, eyeVector, {2,2,2,2}, {-1,-1,-1,-1};\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# height = height * scale \n"\
 | 
			
		||||
	"MUL normalMapColor, normalMapColor, height_scale;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate new texture coord: height * eye + oldTexCoord\n"\
 | 
			
		||||
	"MAD temp, temp, normalMapColor.wwww, inTexCoord;\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# fetch new textures \n"\
 | 
			
		||||
	"TXP colorMapColor, temp, texture[0], 2D; \n"\
 | 
			
		||||
	"TXP normalMapColor, temp, texture[1], 2D; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate color of light1; \n"\
 | 
			
		||||
	"MAD normalMapColor, normalMapColor, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
 | 
			
		||||
	"MAD temp, light1Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
 | 
			
		||||
	"DP3_SAT temp, normalMapColor, temp; \n"\
 | 
			
		||||
	"MUL temp, light1Color, temp; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# calculate color of light2; \n"\
 | 
			
		||||
	"MAD temp2, light2Vector, {2,2,2,2}, {-1,-1,-1,-1}; \n"\
 | 
			
		||||
	"DP3_SAT temp2, normalMapColor, temp2; \n"\
 | 
			
		||||
	"MAD temp, light2Color, temp2, temp; \n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"# luminance * base color; \n"\
 | 
			
		||||
	"MUL outColor, temp, colorMapColor; \n"\
 | 
			
		||||
	"MOV outColor.a, light1Color.a; #write interpolated vertex alpha value\n"\
 | 
			
		||||
	"\n"\
 | 
			
		||||
	"END\n";
 | 
			
		||||
 | 
			
		||||
//! Constructor
 | 
			
		||||
COpenGLParallaxMapRenderer::COpenGLParallaxMapRenderer(video::COpenGLDriver* driver,
 | 
			
		||||
	s32& outMaterialTypeNr, E_MATERIAL_TYPE baseMaterial)
 | 
			
		||||
	: COpenGLShaderMaterialRenderer(driver, 0, baseMaterial), CompiledShaders(true)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	#ifdef _DEBUG
 | 
			
		||||
	setDebugName("COpenGLParallaxMapRenderer");
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
	// set this as callback. We could have done this in
 | 
			
		||||
	// the initialization list, but some compilers don't like it.
 | 
			
		||||
 | 
			
		||||
	CallBack = this;
 | 
			
		||||
 | 
			
		||||
	// basically, this simply compiles the hard coded shaders if the
 | 
			
		||||
	// hardware is able to do them, otherwise it maps to the base material
 | 
			
		||||
 | 
			
		||||
	if (!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) ||
 | 
			
		||||
		!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
 | 
			
		||||
	{
 | 
			
		||||
		// this hardware is not able to do shaders. Fall back to
 | 
			
		||||
		// base material.
 | 
			
		||||
		outMaterialTypeNr = driver->addMaterialRenderer(this);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// check if already compiled normal map shaders are there.
 | 
			
		||||
 | 
			
		||||
	video::IMaterialRenderer* renderer = driver->getMaterialRenderer(EMT_PARALLAX_MAP_SOLID);
 | 
			
		||||
 | 
			
		||||
	if (renderer)
 | 
			
		||||
	{
 | 
			
		||||
		// use the already compiled shaders
 | 
			
		||||
		video::COpenGLParallaxMapRenderer* nmr = reinterpret_cast<video::COpenGLParallaxMapRenderer*>(renderer);
 | 
			
		||||
		CompiledShaders = false;
 | 
			
		||||
 | 
			
		||||
		VertexShader = nmr->VertexShader;
 | 
			
		||||
		PixelShader = nmr->PixelShader;
 | 
			
		||||
 | 
			
		||||
		outMaterialTypeNr = driver->addMaterialRenderer(this);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		// compile shaders on our own
 | 
			
		||||
		init(outMaterialTypeNr, OPENGL_PARALLAX_MAP_VSH, OPENGL_PARALLAX_MAP_PSH, EVT_TANGENTS);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// fallback if compilation has failed
 | 
			
		||||
	if (-1==outMaterialTypeNr)
 | 
			
		||||
		outMaterialTypeNr = driver->addMaterialRenderer(this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Destructor
 | 
			
		||||
COpenGLParallaxMapRenderer::~COpenGLParallaxMapRenderer()
 | 
			
		||||
{
 | 
			
		||||
	if (CallBack == this)
 | 
			
		||||
		CallBack = 0;
 | 
			
		||||
 | 
			
		||||
	if (!CompiledShaders)
 | 
			
		||||
	{
 | 
			
		||||
		// prevent this from deleting shaders we did not create
 | 
			
		||||
		VertexShader = 0;
 | 
			
		||||
		PixelShader.clear();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void COpenGLParallaxMapRenderer::OnSetMaterial(const video::SMaterial& material,
 | 
			
		||||
	const video::SMaterial& lastMaterial,
 | 
			
		||||
	bool resetAllRenderstates, video::IMaterialRendererServices* services)
 | 
			
		||||
{
 | 
			
		||||
	COpenGLShaderMaterialRenderer::OnSetMaterial(material, lastMaterial,
 | 
			
		||||
			resetAllRenderstates, services);
 | 
			
		||||
 | 
			
		||||
	CurrentScale = material.MaterialTypeParam;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Returns the render capability of the material.
 | 
			
		||||
s32 COpenGLParallaxMapRenderer::getRenderCapability() const
 | 
			
		||||
{
 | 
			
		||||
	if (Driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1) &&
 | 
			
		||||
		Driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Called by the engine when the vertex and/or pixel shader constants for an
 | 
			
		||||
//! material renderer should be set.
 | 
			
		||||
void COpenGLParallaxMapRenderer::OnSetConstants(IMaterialRendererServices* services, s32 userData)
 | 
			
		||||
{
 | 
			
		||||
	video::IVideoDriver* driver = services->getVideoDriver();
 | 
			
		||||
 | 
			
		||||
	// set transposed world matrix
 | 
			
		||||
	const core::matrix4& tWorld = driver->getTransform(video::ETS_WORLD).getTransposed();
 | 
			
		||||
	services->setVertexShaderConstant(tWorld.pointer(), 0, 4);
 | 
			
		||||
 | 
			
		||||
	// set transposed worldViewProj matrix
 | 
			
		||||
	core::matrix4 worldViewProj(driver->getTransform(video::ETS_PROJECTION));
 | 
			
		||||
	worldViewProj *= driver->getTransform(video::ETS_VIEW);
 | 
			
		||||
	worldViewProj *= driver->getTransform(video::ETS_WORLD);
 | 
			
		||||
	core::matrix4 tr(worldViewProj.getTransposed());
 | 
			
		||||
	services->setVertexShaderConstant(tr.pointer(), 8, 4);
 | 
			
		||||
 | 
			
		||||
	// here we fetch the fixed function lights from the driver
 | 
			
		||||
	// and set them as constants
 | 
			
		||||
 | 
			
		||||
	u32 cnt = driver->getDynamicLightCount();
 | 
			
		||||
 | 
			
		||||
	// Load the inverse world matrix.
 | 
			
		||||
	core::matrix4 invWorldMat;
 | 
			
		||||
	driver->getTransform(video::ETS_WORLD).getInverse(invWorldMat);
 | 
			
		||||
 | 
			
		||||
	for (u32 i=0; i<2; ++i)
 | 
			
		||||
	{
 | 
			
		||||
		video::SLight light;
 | 
			
		||||
 | 
			
		||||
		if (i<cnt)
 | 
			
		||||
			light = driver->getDynamicLight(i);
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			light.DiffuseColor.set(0,0,0); // make light dark
 | 
			
		||||
			light.Radius = 1.0f;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		light.DiffuseColor.a = 1.0f/(light.Radius*light.Radius); // set attenuation
 | 
			
		||||
 | 
			
		||||
		// Transform the light by the inverse world matrix to get it into object space.
 | 
			
		||||
		invWorldMat.transformVect(light.Position);
 | 
			
		||||
 | 
			
		||||
		services->setVertexShaderConstant(
 | 
			
		||||
			reinterpret_cast<const f32*>(&light.Position), 12+(i*2), 1);
 | 
			
		||||
 | 
			
		||||
		services->setVertexShaderConstant(
 | 
			
		||||
			reinterpret_cast<const f32*>(&light.DiffuseColor), 13+(i*2), 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Obtain the view position by transforming 0,0,0 by the inverse view matrix
 | 
			
		||||
	// and then multiply this by the inverse world matrix.
 | 
			
		||||
	core::vector3df viewPos(0.0f, 0.0f, 0.0f);
 | 
			
		||||
	core::matrix4 inverseView;
 | 
			
		||||
	driver->getTransform(video::ETS_VIEW).getInverse(inverseView);
 | 
			
		||||
	inverseView.transformVect(viewPos);
 | 
			
		||||
	invWorldMat.transformVect(viewPos);
 | 
			
		||||
	services->setVertexShaderConstant(reinterpret_cast<const f32*>(&viewPos.X), 16, 1);
 | 
			
		||||
 | 
			
		||||
	// set scale factor
 | 
			
		||||
	f32 factor = 0.02f; // default value
 | 
			
		||||
	if (CurrentScale != 0.0f)
 | 
			
		||||
		factor = CurrentScale;
 | 
			
		||||
 | 
			
		||||
	f32 c6[] = {factor, factor, factor, factor};
 | 
			
		||||
	services->setPixelShaderConstant(c6, 0, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace video
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -1,57 +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_OPENGL_PARALLAX_MAP_RENDERER_H_INCLUDED__
 | 
			
		||||
#define __C_OPENGL_PARALLAX_MAP_RENDERER_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "IrrCompileConfig.h"
 | 
			
		||||
 | 
			
		||||
#ifdef _IRR_COMPILE_WITH_OPENGL_
 | 
			
		||||
 | 
			
		||||
#include "IShaderConstantSetCallBack.h"
 | 
			
		||||
 | 
			
		||||
#include "COpenGLShaderMaterialRenderer.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//! Class for rendering normal maps with OpenGL
 | 
			
		||||
class COpenGLParallaxMapRenderer : public COpenGLShaderMaterialRenderer, public IShaderConstantSetCallBack
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	//! Constructor
 | 
			
		||||
	COpenGLParallaxMapRenderer(video::COpenGLDriver* driver,
 | 
			
		||||
		s32& outMaterialTypeNr, E_MATERIAL_TYPE baseMaterial);
 | 
			
		||||
 | 
			
		||||
	//! Destructor
 | 
			
		||||
	~COpenGLParallaxMapRenderer();
 | 
			
		||||
 | 
			
		||||
	//! Called by the engine when the vertex and/or pixel shader constants for an
 | 
			
		||||
	//! material renderer should be set.
 | 
			
		||||
	virtual void OnSetConstants(IMaterialRendererServices* services, s32 userData) _IRR_OVERRIDE_;
 | 
			
		||||
 | 
			
		||||
	//! Returns the render capability of the material.
 | 
			
		||||
	virtual s32 getRenderCapability() const _IRR_OVERRIDE_;
 | 
			
		||||
 | 
			
		||||
	virtual void OnSetMaterial(const SMaterial& material) _IRR_OVERRIDE_ { }
 | 
			
		||||
	virtual void OnSetMaterial(const video::SMaterial& material,
 | 
			
		||||
		const video::SMaterial& lastMaterial,
 | 
			
		||||
		bool resetAllRenderstates, video::IMaterialRendererServices* services) _IRR_OVERRIDE_;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
 | 
			
		||||
	bool CompiledShaders;
 | 
			
		||||
	f32 CurrentScale;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace video
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -58,13 +58,9 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(video::COpenGLDriver* drive
 | 
			
		||||
	{
 | 
			
		||||
	case EMT_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_TRANSPARENT_ALPHA_CHANNEL:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
		Alpha = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
		FixedBlending = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_ONETEXTURE_BLEND:
 | 
			
		||||
@@ -98,13 +94,9 @@ COpenGLSLMaterialRenderer::COpenGLSLMaterialRenderer(COpenGLDriver* driver,
 | 
			
		||||
	{
 | 
			
		||||
	case EMT_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_TRANSPARENT_ALPHA_CHANNEL:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
		Alpha = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
		FixedBlending = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_ONETEXTURE_BLEND:
 | 
			
		||||
 
 | 
			
		||||
@@ -42,13 +42,9 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(video::COpenGLDrive
 | 
			
		||||
	{
 | 
			
		||||
	case EMT_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_TRANSPARENT_ALPHA_CHANNEL:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
		Alpha = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
		FixedBlending = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_ONETEXTURE_BLEND:
 | 
			
		||||
@@ -86,13 +82,9 @@ COpenGLShaderMaterialRenderer::COpenGLShaderMaterialRenderer(COpenGLDriver* driv
 | 
			
		||||
	{
 | 
			
		||||
	case EMT_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_TRANSPARENT_ALPHA_CHANNEL:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
 | 
			
		||||
		Alpha = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
	case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
 | 
			
		||||
		FixedBlending = true;
 | 
			
		||||
		break;
 | 
			
		||||
	case EMT_ONETEXTURE_BLEND:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,713 +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 "CSoftwareDriver2.h"
 | 
			
		||||
#include "CBlit.h"
 | 
			
		||||
#include "os.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)
 | 
			
		||||
void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, const video::IImage* src, const core::rect<s32>* srcRect, size_t flags);
 | 
			
		||||
 | 
			
		||||
//nearest pow of 2 ( 257 will be 256 not 512 )
 | 
			
		||||
static inline core::dimension2d<u32> getOptimalSize(const core::dimension2d<u32>& original, const u32 allowNonPowerOfTwo, const u32 maxSize)
 | 
			
		||||
{
 | 
			
		||||
	u32 w, h;
 | 
			
		||||
	if (allowNonPowerOfTwo)
 | 
			
		||||
	{
 | 
			
		||||
		w = original.Width;
 | 
			
		||||
		h = original.Height;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		w = 1;
 | 
			
		||||
		while (w * 2 < original.Width) w *= 2;
 | 
			
		||||
		if (w * 2 - original.Width < original.Width - w) w *= 2;
 | 
			
		||||
 | 
			
		||||
		h = 1;
 | 
			
		||||
		while (h * 2 < original.Height) h *= 2;
 | 
			
		||||
		if (h * 2 - original.Height < original.Height - h) h *= 2;
 | 
			
		||||
	}
 | 
			
		||||
	if (maxSize && w > maxSize) w = maxSize;
 | 
			
		||||
	if (maxSize && h > maxSize) h = maxSize;
 | 
			
		||||
	return core::dimension2d<u32>(w, h);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! constructor
 | 
			
		||||
CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver)
 | 
			
		||||
	: ITexture(name
 | 
			
		||||
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
		, ETT_2D
 | 
			
		||||
#endif
 | 
			
		||||
	)
 | 
			
		||||
	, MipMapLOD(0), Flags(flags), Driver(driver)
 | 
			
		||||
{
 | 
			
		||||
#ifdef _DEBUG
 | 
			
		||||
	setDebugName("CSoftwareTexture2");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if SOFTWARE_DRIVER_2_MIPMAPPING_MAX <= 1
 | 
			
		||||
	Flags &= ~(GEN_MIPMAP | GEN_MIPMAP_AUTO);
 | 
			
		||||
#endif
 | 
			
		||||
	//set baseclass properties
 | 
			
		||||
	DriverType = EDT_BURNINGSVIDEO;
 | 
			
		||||
	ColorFormat = (Flags & IS_RENDERTARGET) ? SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT : SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT;
 | 
			
		||||
	IsRenderTarget = (Flags & IS_RENDERTARGET) != 0;
 | 
			
		||||
	HasMipMaps = (Flags & GEN_MIPMAP) != 0;
 | 
			
		||||
	MipMap0_Area[0] = 1;
 | 
			
		||||
	MipMap0_Area[1] = 1;
 | 
			
		||||
	LodBIAS = 1.f;
 | 
			
		||||
	for (size_t i = 0; i < array_size(MipMap); ++i) MipMap[i] = 0;
 | 
			
		||||
	if (!image) return;
 | 
			
		||||
 | 
			
		||||
	OriginalSize = image->getDimension();
 | 
			
		||||
	OriginalColorFormat = image->getColorFormat();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(IRRLICHT_sRGB)
 | 
			
		||||
	if (Flags & IMAGE_IS_LINEAR) image->set_sRGB(0);
 | 
			
		||||
#else
 | 
			
		||||
	//guessing linear image
 | 
			
		||||
	if (name.find("light") >= 0 ||
 | 
			
		||||
		name.find("bump") >= 0 ||
 | 
			
		||||
		name.find("height") >= 0
 | 
			
		||||
		)
 | 
			
		||||
	{
 | 
			
		||||
		Flags |= TEXTURE_IS_LINEAR | IMAGE_IS_LINEAR;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	bool isCompressed = IImage::isCompressedFormat(OriginalColorFormat);
 | 
			
		||||
	if (isCompressed)
 | 
			
		||||
	{
 | 
			
		||||
		os::Printer::log("Texture compression not available.", ELL_ERROR);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//visual studio code warning
 | 
			
		||||
	u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE;
 | 
			
		||||
 | 
			
		||||
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
	if (IsRenderTarget && name.find("RaceGUI::markers") >= 0)
 | 
			
		||||
	{
 | 
			
		||||
		maxTexSize = 0;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	/*
 | 
			
		||||
		core::dimension2d<u32> optSize(OriginalSize.getOptimalSize(
 | 
			
		||||
			(Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo
 | 
			
		||||
			false, // requireSquare
 | 
			
		||||
			(Flags & ALLOW_NPOT) ? 1 : maxTexSize == SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, // larger
 | 
			
		||||
			(Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue
 | 
			
		||||
		)
 | 
			
		||||
		);
 | 
			
		||||
	*/
 | 
			
		||||
	core::dimension2d<u32> optSize(getOptimalSize(OriginalSize, Flags & ALLOW_NPOT, maxTexSize));
 | 
			
		||||
	if (OriginalSize == optSize)
 | 
			
		||||
	{
 | 
			
		||||
		MipMap[0] = new CImage(ColorFormat, image->getDimension());
 | 
			
		||||
#if defined(IRRLICHT_sRGB)
 | 
			
		||||
		MipMap[0]->set_sRGB((Flags & TEXTURE_IS_LINEAR) ? 0 : image->get_sRGB());
 | 
			
		||||
#endif
 | 
			
		||||
		if (!isCompressed && image->getData())
 | 
			
		||||
			image->copyTo(MipMap[0]);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		MipMap[0] = new CImage(ColorFormat, optSize);
 | 
			
		||||
#if defined(IRRLICHT_sRGB)
 | 
			
		||||
		MipMap[0]->set_sRGB((Flags & TEXTURE_IS_LINEAR) ? 0 : image->get_sRGB());
 | 
			
		||||
#endif
 | 
			
		||||
		if (!isCompressed)
 | 
			
		||||
		{
 | 
			
		||||
			//image->copyToScalingBoxFilter ( MipMap[0],0, false );
 | 
			
		||||
			Resample_subSampling(BLITTER_TEXTURE, MipMap[0], 0, image, 0, Flags);
 | 
			
		||||
		}
 | 
			
		||||
		// if Original Size is used for calculation ( 2D position, font) it will be wrong
 | 
			
		||||
		//OriginalSize = optSize;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Show Information about resizing
 | 
			
		||||
	if (OriginalSize != optSize ||
 | 
			
		||||
		(	OriginalColorFormat != ColorFormat &&
 | 
			
		||||
			!((OriginalColorFormat == ECF_R8G8B8 || OriginalColorFormat == ECF_A1R5G5B5) && ColorFormat == ECF_A8R8G8B8)
 | 
			
		||||
		)
 | 
			
		||||
	)
 | 
			
		||||
	{
 | 
			
		||||
		char buf[256];
 | 
			
		||||
		core::stringw showName(name);
 | 
			
		||||
		snprintf_irr(buf, sizeof(buf), "Burningvideo: Texture '%ls' reformat %ux%u,%s -> %ux%u,%s",
 | 
			
		||||
			showName.c_str(),
 | 
			
		||||
			OriginalSize.Width, OriginalSize.Height, ColorFormatNames[OriginalColorFormat],
 | 
			
		||||
			optSize.Width, optSize.Height, ColorFormatNames[ColorFormat]
 | 
			
		||||
		);
 | 
			
		||||
		os::Printer::log(buf, ELL_DEBUG);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//select highest mipmap 0
 | 
			
		||||
	regenerateMipMapLevels(image->getMipMapsData());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! destructor
 | 
			
		||||
CSoftwareTexture2::~CSoftwareTexture2()
 | 
			
		||||
{
 | 
			
		||||
	for (size_t i = 0; i < array_size(MipMap); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		if (MipMap[i])
 | 
			
		||||
		{
 | 
			
		||||
			MipMap[i]->drop();
 | 
			
		||||
			MipMap[i] = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! Regenerates the mip map levels of the texture. Useful after locking and
 | 
			
		||||
//! modifying the texture
 | 
			
		||||
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
 | 
			
		||||
#else
 | 
			
		||||
void CSoftwareTexture2::regenerateMipMapLevels(void* data)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	size_t i;
 | 
			
		||||
 | 
			
		||||
	// release
 | 
			
		||||
	for (i = 1; i < array_size(MipMap); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		if (MipMap[i])
 | 
			
		||||
		{
 | 
			
		||||
			MipMap[i]->drop();
 | 
			
		||||
			MipMap[i] = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	core::dimension2d<u32> newSize;
 | 
			
		||||
 | 
			
		||||
	if (HasMipMaps && ((Flags & GEN_MIPMAP_AUTO) || 0 == data))
 | 
			
		||||
	{
 | 
			
		||||
		//need memory also if autogen mipmap disabled
 | 
			
		||||
		for (i = 1; i < array_size(MipMap); ++i)
 | 
			
		||||
		{
 | 
			
		||||
			const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
 | 
			
		||||
			//isotropic
 | 
			
		||||
			newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);
 | 
			
		||||
			newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);
 | 
			
		||||
			if (upperDim == newSize)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			MipMap[i] = new CImage(ColorFormat, newSize);
 | 
			
		||||
#if defined(IRRLICHT_sRGB)
 | 
			
		||||
			MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB());
 | 
			
		||||
#endif
 | 
			
		||||
			//MipMap[i]->fill ( 0xFFFF4040 );
 | 
			
		||||
			//MipMap[i-1]->copyToScalingBoxFilter( MipMap[i], 0, false );
 | 
			
		||||
			Resample_subSampling(BLITTER_TEXTURE, MipMap[i], 0, MipMap[0], 0, Flags);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else if (HasMipMaps && data)
 | 
			
		||||
	{
 | 
			
		||||
		//deactivated outside mipdata until TA knows how to handle this.
 | 
			
		||||
 | 
			
		||||
		//query mipmap dimension
 | 
			
		||||
		u8* mip_current = (u8*)data;
 | 
			
		||||
		const u8* mip_end = (u8*)data;
 | 
			
		||||
 | 
			
		||||
		core::dimension2d<u32> origSize = OriginalSize;
 | 
			
		||||
		i = 1;
 | 
			
		||||
		do
 | 
			
		||||
		{
 | 
			
		||||
			if (origSize.Width > 1) origSize.Width >>= 1;
 | 
			
		||||
			if (origSize.Height > 1) origSize.Height >>= 1;
 | 
			
		||||
			mip_end += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);
 | 
			
		||||
			i += 1;
 | 
			
		||||
		} while ((origSize.Width != 1 || origSize.Height != 1) && i < array_size(MipMap));
 | 
			
		||||
 | 
			
		||||
		//TODO: this is not true
 | 
			
		||||
		LodBIAS = i * 2.f;
 | 
			
		||||
 | 
			
		||||
		origSize = OriginalSize;
 | 
			
		||||
		for (i = 1; i < array_size(MipMap) && mip_current < mip_end; ++i)
 | 
			
		||||
		{
 | 
			
		||||
			const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
 | 
			
		||||
			//isotropic
 | 
			
		||||
			newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);
 | 
			
		||||
			newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);
 | 
			
		||||
			if (upperDim == newSize)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			if (origSize.Width > 1) origSize.Width >>= 1;
 | 
			
		||||
			if (origSize.Height > 1) origSize.Height >>= 1;
 | 
			
		||||
 | 
			
		||||
			if (OriginalColorFormat != ColorFormat)
 | 
			
		||||
			{
 | 
			
		||||
				IImage* tmpImage = new CImage(OriginalColorFormat, origSize, mip_current, true, false);
 | 
			
		||||
				MipMap[i] = new CImage(ColorFormat, newSize);
 | 
			
		||||
				if (origSize == newSize)
 | 
			
		||||
					tmpImage->copyTo(MipMap[i]);
 | 
			
		||||
				else
 | 
			
		||||
					tmpImage->copyToScalingBoxFilter(MipMap[i]);
 | 
			
		||||
				tmpImage->drop();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				if (origSize == newSize)
 | 
			
		||||
					MipMap[i] = new CImage(ColorFormat, newSize, mip_current, false);
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					MipMap[i] = new CImage(ColorFormat, newSize);
 | 
			
		||||
					IImage* tmpImage = new CImage(ColorFormat, origSize, mip_current, true, false);
 | 
			
		||||
					tmpImage->copyToScalingBoxFilter(MipMap[i]);
 | 
			
		||||
					tmpImage->drop();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			mip_current += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
	//visualize mipmap
 | 
			
		||||
	for (i = 1; i < 0 && i < array_size(MipMap); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		static u32 color[] = {
 | 
			
		||||
			0xFFFF0000,
 | 
			
		||||
			0xFFFF0000,0xFF00FF00,0xFF0000FF,
 | 
			
		||||
			0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,
 | 
			
		||||
			0xFFff6600,0xFF00ff66,0xFF6600FF,
 | 
			
		||||
			0xFF66ff00,0xFF0066ff,0xFFff0066,
 | 
			
		||||
			0xFF33ff00,0xFF0033ff,0xFF3300ff,
 | 
			
		||||
			0xFF0000FF,0xFF0000FF,0xFF0000FF
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		if (MipMap[i])
 | 
			
		||||
		{
 | 
			
		||||
			int border = 0;
 | 
			
		||||
			const core::dimension2du& d = MipMap[i]->getDimension();
 | 
			
		||||
			core::rect<s32> p(0, 0, d.Width, d.Height);
 | 
			
		||||
			SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000);
 | 
			
		||||
 | 
			
		||||
			core::rect<s32> dclip(border, border, d.Width - border, d.Height - border);
 | 
			
		||||
			
 | 
			
		||||
			Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], &dclip, 0, MipMap[i], &p, c.color);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//save mipmap chain
 | 
			
		||||
	if (0)
 | 
			
		||||
	{
 | 
			
		||||
		char buf[256];
 | 
			
		||||
		const char* name = getName().getPath().c_str();
 | 
			
		||||
		int filename = 0;
 | 
			
		||||
		//int ext = -1;
 | 
			
		||||
		i = 0;
 | 
			
		||||
		while (name[i])
 | 
			
		||||
		{
 | 
			
		||||
			if (name[i] == '/' || name[i] == '\\') filename = (s32)i + 1;
 | 
			
		||||
			//if (name[i] == '.') ext = i;
 | 
			
		||||
			i += 1;
 | 
			
		||||
		}
 | 
			
		||||
		for (i = 0; i < array_size(MipMap); ++i)
 | 
			
		||||
		{
 | 
			
		||||
			if (MipMap[i])
 | 
			
		||||
			{
 | 
			
		||||
				snprintf_irr(buf, sizeof(buf), "mip/%s_%02d.png", name + filename, (s32)i);
 | 
			
		||||
				Driver->writeImageToFile(MipMap[i], buf);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	calcDerivative();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSoftwareTexture2::calcDerivative()
 | 
			
		||||
{
 | 
			
		||||
	//reset current MipMap
 | 
			
		||||
	MipMapLOD = 0;
 | 
			
		||||
	if (MipMap[0])
 | 
			
		||||
	{
 | 
			
		||||
		const core::dimension2du& dim = MipMap[0]->getDimension();
 | 
			
		||||
		MipMap0_Area[0] = dim.Width;
 | 
			
		||||
		MipMap0_Area[1] = dim.Height; // screensize of a triangle
 | 
			
		||||
 | 
			
		||||
		//TA: try to mimic openGL mipmap. ( don't do this!)
 | 
			
		||||
		//if (MipMap0_Area[0] < 32) MipMap0_Area[0] = 32;
 | 
			
		||||
		//if (MipMap0_Area[1] < 32) MipMap0_Area[1] = 32;
 | 
			
		||||
 | 
			
		||||
		Size = dim; // MipMap[MipMapLOD]->getDimension();
 | 
			
		||||
		Pitch = MipMap[MipMapLOD]->getPitch();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//preCalc mipmap texel center boundaries
 | 
			
		||||
	for (size_t i = 0; i < array_size(MipMap); ++i)
 | 
			
		||||
	{
 | 
			
		||||
		CSoftwareTexture2_Bound& b = TexBound[i];
 | 
			
		||||
		if (MipMap[i])
 | 
			
		||||
		{
 | 
			
		||||
			const core::dimension2du& dim = MipMap[i]->getDimension();
 | 
			
		||||
			//f32 u = 1.f / dim.Width;
 | 
			
		||||
			//f32 v = 1.f / dim.Height;
 | 
			
		||||
 | 
			
		||||
			b.w = dim.Width - 1.f;
 | 
			
		||||
			b.h = dim.Height - 1.f;
 | 
			
		||||
			b.cx = 0.f; //u*0.005f;
 | 
			
		||||
			b.cy = 0.f; //v*0.005f;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			b.w = 0.f;
 | 
			
		||||
			b.h = 0.f;
 | 
			
		||||
			b.cx = 0.f;
 | 
			
		||||
			b.cy = 0.f;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Software Render Target 2 */
 | 
			
		||||
 | 
			
		||||
CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver)
 | 
			
		||||
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
	, IRenderTarget(0)
 | 
			
		||||
#endif
 | 
			
		||||
{
 | 
			
		||||
	DriverType = EDT_BURNINGSVIDEO;
 | 
			
		||||
 | 
			
		||||
	Textures.set_used(1);
 | 
			
		||||
	Textures[0] = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CSoftwareRenderTarget2::~CSoftwareRenderTarget2()
 | 
			
		||||
{
 | 
			
		||||
	if (Textures[0])
 | 
			
		||||
		Textures[0]->drop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CSoftwareRenderTarget2::setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces)
 | 
			
		||||
{
 | 
			
		||||
	if (!Textures.equals(textures, numTextures))
 | 
			
		||||
	{
 | 
			
		||||
		ITexture* prevTexture = Textures[0];
 | 
			
		||||
 | 
			
		||||
		bool textureDetected = false;
 | 
			
		||||
 | 
			
		||||
		for (u32 i = 0; i < numTextures; ++i)
 | 
			
		||||
		{
 | 
			
		||||
			if (textures[i] && textures[i]->getDriverType() == EDT_BURNINGSVIDEO)
 | 
			
		||||
			{
 | 
			
		||||
				Textures[0] = textures[i];
 | 
			
		||||
				Textures[0]->grab();
 | 
			
		||||
				textureDetected = true;
 | 
			
		||||
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (prevTexture)
 | 
			
		||||
			prevTexture->drop();
 | 
			
		||||
 | 
			
		||||
		if (!textureDetected)
 | 
			
		||||
			Textures[0] = 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static const float srgb_8bit_to_linear_float[1 << 8] = {
 | 
			
		||||
	0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f,
 | 
			
		||||
	0.001214108f, 0.001517635f, 0.001821162f, 0.0021246888f,
 | 
			
		||||
	0.002428216f, 0.002731743f, 0.00303527f, 0.0033465358f,
 | 
			
		||||
	0.0036765074f, 0.004024717f, 0.004391442f, 0.0047769537f,
 | 
			
		||||
	0.005181517f, 0.005605392f, 0.0060488335f, 0.006512091f,
 | 
			
		||||
	0.0069954107f, 0.007499032f, 0.008023193f, 0.008568126f,
 | 
			
		||||
	0.009134059f, 0.009721218f, 0.010329823f, 0.010960095f,
 | 
			
		||||
	0.011612245f, 0.012286489f, 0.0129830325f, 0.013702083f,
 | 
			
		||||
	0.014443845f, 0.015208516f, 0.015996294f, 0.016807377f,
 | 
			
		||||
	0.017641956f, 0.018500222f, 0.019382363f, 0.020288564f,
 | 
			
		||||
	0.021219011f, 0.022173885f, 0.023153368f, 0.024157634f,
 | 
			
		||||
	0.025186861f, 0.026241222f, 0.027320893f, 0.02842604f,
 | 
			
		||||
	0.029556835f, 0.030713445f, 0.031896032f, 0.033104766f,
 | 
			
		||||
	0.034339808f, 0.035601314f, 0.036889452f, 0.038204372f,
 | 
			
		||||
	0.039546236f, 0.0409152f, 0.04231141f, 0.04373503f,
 | 
			
		||||
	0.045186203f, 0.046665087f, 0.048171826f, 0.049706567f,
 | 
			
		||||
	0.051269464f, 0.05286065f, 0.05448028f, 0.056128494f,
 | 
			
		||||
	0.057805438f, 0.059511244f, 0.06124606f, 0.06301002f,
 | 
			
		||||
	0.06480327f, 0.066625945f, 0.068478175f, 0.0703601f,
 | 
			
		||||
	0.07227185f, 0.07421357f, 0.07618539f, 0.07818743f,
 | 
			
		||||
	0.08021983f, 0.082282715f, 0.084376216f, 0.086500466f,
 | 
			
		||||
	0.08865559f, 0.09084172f, 0.093058966f, 0.09530747f,
 | 
			
		||||
	0.097587354f, 0.09989873f, 0.10224174f, 0.10461649f,
 | 
			
		||||
	0.107023105f, 0.10946172f, 0.111932434f, 0.11443538f,
 | 
			
		||||
	0.11697067f, 0.119538434f, 0.122138776f, 0.12477182f,
 | 
			
		||||
	0.12743768f, 0.13013647f, 0.13286832f, 0.13563333f,
 | 
			
		||||
	0.13843162f, 0.14126329f, 0.14412847f, 0.14702727f,
 | 
			
		||||
	0.14995979f, 0.15292616f, 0.15592647f, 0.15896083f,
 | 
			
		||||
	0.16202939f, 0.1651322f, 0.1682694f, 0.17144111f,
 | 
			
		||||
	0.1746474f, 0.17788842f, 0.18116425f, 0.18447499f,
 | 
			
		||||
	0.18782078f, 0.19120169f, 0.19461784f, 0.19806932f,
 | 
			
		||||
	0.20155625f, 0.20507874f, 0.20863687f, 0.21223076f,
 | 
			
		||||
	0.21586053f, 0.21952623f, 0.22322798f, 0.2269659f,
 | 
			
		||||
	0.23074007f, 0.23455061f, 0.2383976f, 0.24228115f,
 | 
			
		||||
	0.24620135f, 0.2501583f, 0.25415212f, 0.25818288f,
 | 
			
		||||
	0.2622507f, 0.26635563f, 0.27049783f, 0.27467734f,
 | 
			
		||||
	0.2788943f, 0.28314877f, 0.28744087f, 0.29177067f,
 | 
			
		||||
	0.2961383f, 0.3005438f, 0.30498734f, 0.30946895f,
 | 
			
		||||
	0.31398875f, 0.3185468f, 0.32314324f, 0.32777813f,
 | 
			
		||||
	0.33245155f, 0.33716366f, 0.34191445f, 0.3467041f,
 | 
			
		||||
	0.35153264f, 0.35640016f, 0.36130682f, 0.36625263f,
 | 
			
		||||
	0.3712377f, 0.37626216f, 0.38132605f, 0.38642946f,
 | 
			
		||||
	0.3915725f, 0.39675525f, 0.4019778f, 0.40724024f,
 | 
			
		||||
	0.41254264f, 0.4178851f, 0.4232677f, 0.42869052f,
 | 
			
		||||
	0.43415368f, 0.4396572f, 0.44520122f, 0.45078582f,
 | 
			
		||||
	0.45641103f, 0.46207702f, 0.4677838f, 0.4735315f,
 | 
			
		||||
	0.4793202f, 0.48514995f, 0.4910209f, 0.496933f,
 | 
			
		||||
	0.5028865f, 0.50888133f, 0.5149177f, 0.5209956f,
 | 
			
		||||
	0.52711517f, 0.53327644f, 0.5394795f, 0.5457245f,
 | 
			
		||||
	0.55201143f, 0.55834043f, 0.5647115f, 0.57112485f,
 | 
			
		||||
	0.57758045f, 0.58407843f, 0.59061885f, 0.5972018f,
 | 
			
		||||
	0.60382736f, 0.61049557f, 0.6172066f, 0.62396044f,
 | 
			
		||||
	0.63075715f, 0.6375969f, 0.6444797f, 0.65140563f,
 | 
			
		||||
	0.65837485f, 0.66538733f, 0.67244315f, 0.6795425f,
 | 
			
		||||
	0.6866853f, 0.6938718f, 0.7011019f, 0.7083758f,
 | 
			
		||||
	0.71569353f, 0.7230551f, 0.73046076f, 0.73791045f,
 | 
			
		||||
	0.74540424f, 0.7529422f, 0.7605245f, 0.76815116f,
 | 
			
		||||
	0.7758222f, 0.7835378f, 0.791298f, 0.7991027f,
 | 
			
		||||
	0.8069523f, 0.8148466f, 0.82278574f, 0.8307699f,
 | 
			
		||||
	0.838799f, 0.8468732f, 0.8549926f, 0.8631572f,
 | 
			
		||||
	0.8713671f, 0.8796224f, 0.8879231f, 0.8962694f,
 | 
			
		||||
	0.9046612f, 0.91309863f, 0.92158186f, 0.9301109f,
 | 
			
		||||
	0.9386857f, 0.9473065f, 0.9559733f, 0.9646863f,
 | 
			
		||||
	0.9734453f, 0.9822506f, 0.9911021f, 1.0f,
 | 
			
		||||
};
 | 
			
		||||
/*
 | 
			
		||||
int linear_to_srgb_8bit(const float x) {
 | 
			
		||||
	if (x <= 0.f) return 0;
 | 
			
		||||
	if (x >= 1.f) return 255;
 | 
			
		||||
	const float *table = SRGB_8BIT_TO_LINEAR_FLOAT;
 | 
			
		||||
	int y = 0;
 | 
			
		||||
	for (int i = 128; i != 0; i >>= 1) {
 | 
			
		||||
		if (table[y + i] <= x)
 | 
			
		||||
			y += i;
 | 
			
		||||
	}
 | 
			
		||||
	if (x - table[y] <= table[y + 1] - x)
 | 
			
		||||
		return y;
 | 
			
		||||
	else
 | 
			
		||||
		return y + 1;
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
u32 linear_to_srgb_8bit(const float v)
 | 
			
		||||
{
 | 
			
		||||
	ieee754 c;
 | 
			
		||||
	c.f = v;
 | 
			
		||||
	const size_t x = c.u;
 | 
			
		||||
	const u32* table = (u32*)srgb_8bit_to_linear_float;
 | 
			
		||||
	u32 y = 0;
 | 
			
		||||
	y += table[y + 128] <= x ? 128 : 0;
 | 
			
		||||
	y += table[y + 64] <= x ? 64 : 0;
 | 
			
		||||
	y += table[y + 32] <= x ? 32 : 0;
 | 
			
		||||
	y += table[y + 16] <= x ? 16 : 0;
 | 
			
		||||
	y += table[y + 8] <= x ? 8 : 0;
 | 
			
		||||
	y += table[y + 4] <= x ? 4 : 0;
 | 
			
		||||
	y += table[y + 2] <= x ? 2 : 0;
 | 
			
		||||
	y += table[y + 1] <= x ? 1 : 0;
 | 
			
		||||
 | 
			
		||||
	return y;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 2D Region half open [x0;x1[
 | 
			
		||||
struct absrect2
 | 
			
		||||
{
 | 
			
		||||
	s32 x0;
 | 
			
		||||
	s32 y0;
 | 
			
		||||
	s32 x1;
 | 
			
		||||
	s32 y1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static inline int clipTest(absrect2& o, const core::rect<s32>* a, const absrect2& b)
 | 
			
		||||
{
 | 
			
		||||
	if (a == 0)
 | 
			
		||||
	{
 | 
			
		||||
		o.x0 = b.x0;
 | 
			
		||||
		o.y0 = b.y0;
 | 
			
		||||
		o.x1 = b.x1;
 | 
			
		||||
		o.y1 = b.y1;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		o.x0 = core::s32_max(a->UpperLeftCorner.X, b.x0);
 | 
			
		||||
		o.x1 = core::s32_min(a->LowerRightCorner.X, b.x1);
 | 
			
		||||
		o.y0 = core::s32_max(a->UpperLeftCorner.Y, b.y0);
 | 
			
		||||
		o.y1 = core::s32_min(a->LowerRightCorner.Y, b.y1);
 | 
			
		||||
	}
 | 
			
		||||
	int clipTest = 0;
 | 
			
		||||
	clipTest |= o.x0 >= o.x1 ? 1 : 0;
 | 
			
		||||
	clipTest |= o.y0 >= o.y1 ? 2 : 0;
 | 
			
		||||
	return clipTest;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)
 | 
			
		||||
// todo: texture jumps (mip selection problem)
 | 
			
		||||
void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect,
 | 
			
		||||
	const video::IImage* src, const core::rect<s32>* srcRect, size_t flags)
 | 
			
		||||
{
 | 
			
		||||
	u8* dstData = (u8*)dst->getData();
 | 
			
		||||
	const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height };
 | 
			
		||||
	absrect2 dc;
 | 
			
		||||
	if (clipTest(dc, dstRect, dst_clip) || !dstData) return;
 | 
			
		||||
	const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat();
 | 
			
		||||
 | 
			
		||||
	const u8* srcData = (u8*)src->getData();
 | 
			
		||||
	const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height };
 | 
			
		||||
	absrect2 sc;
 | 
			
		||||
	if (clipTest(sc, srcRect, src_clip) || !srcData) return;
 | 
			
		||||
	const video::ECOLOR_FORMAT srcFormat = src->getColorFormat();
 | 
			
		||||
 | 
			
		||||
#if defined(IRRLICHT_sRGB)
 | 
			
		||||
	const int dst_sRGB = dst->get_sRGB();
 | 
			
		||||
	const int src_sRGB = src->get_sRGB();
 | 
			
		||||
#else
 | 
			
		||||
	const int dst_sRGB = (flags & CSoftwareTexture2::TEXTURE_IS_LINEAR) ? 0 : 1;
 | 
			
		||||
	const int src_sRGB = (flags & CSoftwareTexture2::IMAGE_IS_LINEAR) ? 0 : 1;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	float scale[2];
 | 
			
		||||
	scale[0] = (float)(sc.x1 - sc.x0) / (float)(dc.x1 - dc.x0);
 | 
			
		||||
	scale[1] = (float)(sc.y1 - sc.y0) / (float)(dc.y1 - dc.y0);
 | 
			
		||||
	const float rs = 1.f / (scale[0] * scale[1]);
 | 
			
		||||
 | 
			
		||||
	float sum[4];
 | 
			
		||||
	u32 sbgra = 0;
 | 
			
		||||
 | 
			
		||||
	float f[4];
 | 
			
		||||
	int fi[4];
 | 
			
		||||
	f[3] = (float)sc.y0;
 | 
			
		||||
	for (int dy = dc.y0; dy < dc.y1; ++dy)
 | 
			
		||||
	{
 | 
			
		||||
		f[1] = f[3];
 | 
			
		||||
		f[3] = sc.y0 + (dy + 1 - dc.y0) * scale[1];
 | 
			
		||||
		if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough
 | 
			
		||||
 | 
			
		||||
		f[2] = (float)sc.x0;
 | 
			
		||||
		for (int dx = dc.x0; dx < dc.x1; ++dx)
 | 
			
		||||
		{
 | 
			
		||||
			f[0] = f[2];
 | 
			
		||||
			f[2] = sc.x0 + (dx + 1 - dc.x0) * scale[0];
 | 
			
		||||
			if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f;
 | 
			
		||||
 | 
			
		||||
			//accumulate linear color
 | 
			
		||||
			sum[0] = 0.f;
 | 
			
		||||
			sum[1] = 0.f;
 | 
			
		||||
			sum[2] = 0.f;
 | 
			
		||||
			sum[3] = 0.f;
 | 
			
		||||
 | 
			
		||||
			//sample border
 | 
			
		||||
			fi[0] = (int)(f[0]);
 | 
			
		||||
			fi[1] = (int)(f[1]);
 | 
			
		||||
			fi[2] = (int)(f[2]);
 | 
			
		||||
			fi[3] = (int)(f[3]);
 | 
			
		||||
 | 
			
		||||
			float w[2];
 | 
			
		||||
			for (int fy = fi[1]; fy <= fi[3]; ++fy)
 | 
			
		||||
			{
 | 
			
		||||
				w[1] = 1.f;
 | 
			
		||||
				if (fy == fi[1]) w[1] -= f[1] - fy;
 | 
			
		||||
				if (fy == fi[3]) w[1] -= fy + 1 - f[3];
 | 
			
		||||
 | 
			
		||||
				for (int fx = fi[0]; fx <= fi[2]; ++fx)
 | 
			
		||||
				{
 | 
			
		||||
					w[0] = 1.f;
 | 
			
		||||
					if (fx == fi[0]) w[0] -= f[0] - fx;
 | 
			
		||||
					if (fx == fi[2]) w[0] -= fx + 1 - f[2];
 | 
			
		||||
 | 
			
		||||
					const float ws = w[1] * w[0] * rs;
 | 
			
		||||
 | 
			
		||||
					switch (srcFormat)
 | 
			
		||||
					{
 | 
			
		||||
					case video::ECF_A1R5G5B5: sbgra = video::A1R5G5B5toA8R8G8B8(*(u16*)(srcData + (fy * src_clip.x1) * 2 + (fx * 2))); break;
 | 
			
		||||
					case video::ECF_R5G6B5: sbgra = video::R5G6B5toA8R8G8B8(*(u16*)(srcData + (fy * src_clip.x1) * 2 + (fx * 2))); break;
 | 
			
		||||
					case video::ECF_A8R8G8B8: sbgra = *(u32*)(srcData + (fy * src_clip.x1) * 4 + (fx * 4)); break;
 | 
			
		||||
					case video::ECF_R8G8B8:
 | 
			
		||||
					{
 | 
			
		||||
						const u8* p = srcData + (fy * src_clip.x1) * 3 + (fx * 3);
 | 
			
		||||
						sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2];
 | 
			
		||||
					} break;
 | 
			
		||||
					default: break;
 | 
			
		||||
					}
 | 
			
		||||
					if (src_sRGB)
 | 
			
		||||
					{
 | 
			
		||||
						sum[0] += srgb_8bit_to_linear_float[(sbgra) & 0xFF] * ws;
 | 
			
		||||
						sum[1] += srgb_8bit_to_linear_float[(sbgra >> 8) & 0xFF] * ws;
 | 
			
		||||
						sum[2] += srgb_8bit_to_linear_float[(sbgra >> 16) & 0xFF] * ws;
 | 
			
		||||
						sum[3] += ((sbgra >> 24) & 0xFF) * ws;
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						sum[0] += ((sbgra) & 0xFF) * ws;
 | 
			
		||||
						sum[1] += ((sbgra >> 8) & 0xFF) * ws;
 | 
			
		||||
						sum[2] += ((sbgra >> 16) & 0xFF) * ws;
 | 
			
		||||
						sum[3] += ((sbgra >> 24) & 0xFF) * ws;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			switch (op)
 | 
			
		||||
			{
 | 
			
		||||
			case BLITTER_TEXTURE_ALPHA_BLEND:
 | 
			
		||||
			case BLITTER_TEXTURE_ALPHA_COLOR_BLEND:
 | 
			
		||||
				break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (dst_sRGB)
 | 
			
		||||
			{
 | 
			
		||||
				sbgra = linear_to_srgb_8bit(sum[0]) |
 | 
			
		||||
					linear_to_srgb_8bit(sum[1]) << 8 |
 | 
			
		||||
					linear_to_srgb_8bit(sum[2]) << 16 |
 | 
			
		||||
					(u32)(sum[3]) << 24;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				sbgra = (u32)(sum[0]) |
 | 
			
		||||
					(u32)(sum[1]) << 8 |
 | 
			
		||||
					(u32)(sum[2]) << 16 |
 | 
			
		||||
					(u32)(sum[3]) << 24;
 | 
			
		||||
			}
 | 
			
		||||
			switch (dstFormat)
 | 
			
		||||
			{
 | 
			
		||||
			case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy * dst_clip.x1) * 4 + (dx * 4)) = sbgra; break;
 | 
			
		||||
			case video::ECF_R8G8B8:
 | 
			
		||||
			{
 | 
			
		||||
				u8* p = dstData + (dy * dst_clip.x1) * 3 + (dx * 3);
 | 
			
		||||
				p[2] = (sbgra) & 0xFF;
 | 
			
		||||
				p[1] = (sbgra >> 8) & 0xFF;
 | 
			
		||||
				p[0] = (sbgra >> 16) & 0xFF;
 | 
			
		||||
			} break;
 | 
			
		||||
			case video::ECF_A1R5G5B5: *(u16*)(dstData + (dy * dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toA1R5G5B5(sbgra); break;
 | 
			
		||||
			case video::ECF_R5G6B5:   *(u16*)(dstData + (dy * dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toR5G6B5(sbgra); break;
 | 
			
		||||
			default:
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // end namespace video
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
 | 
			
		||||
@@ -1,185 +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_SOFTWARE_2_TEXTURE_H_INCLUDED__
 | 
			
		||||
#define __C_SOFTWARE_2_TEXTURE_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "SoftwareDriver2_compile_config.h"
 | 
			
		||||
 | 
			
		||||
#include "ITexture.h"
 | 
			
		||||
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
#include "IVideoDriver.h"
 | 
			
		||||
#else
 | 
			
		||||
#include "IRenderTarget.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "CImage.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
class CBurningVideoDriver;
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	interface for a Video Driver dependent Texture.
 | 
			
		||||
*/
 | 
			
		||||
struct CSoftwareTexture2_Bound
 | 
			
		||||
{
 | 
			
		||||
	f32 w;  // width - 0.5f;
 | 
			
		||||
	f32 h;  // height- 0.5f;
 | 
			
		||||
	f32 cx; // texelcenter x 1.f/width*0.5f
 | 
			
		||||
	f32 cy; // texelcenter y 1.f/height*0.5f
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class CSoftwareTexture2 : public ITexture
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
	//! constructor
 | 
			
		||||
	enum eTex2Flags
 | 
			
		||||
	{
 | 
			
		||||
		GEN_MIPMAP			= 1,		// has mipmaps
 | 
			
		||||
		GEN_MIPMAP_AUTO		= 2,		// automatic mipmap generation
 | 
			
		||||
		IS_RENDERTARGET		= 4,
 | 
			
		||||
		ALLOW_NPOT			= 8,		//allow non power of two
 | 
			
		||||
		IMAGE_IS_LINEAR		= 16,
 | 
			
		||||
		TEXTURE_IS_LINEAR	= 32,
 | 
			
		||||
	};
 | 
			
		||||
	CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags /*eTex2Flags*/, CBurningVideoDriver* driver);
 | 
			
		||||
 | 
			
		||||
	//! destructor
 | 
			
		||||
	virtual ~CSoftwareTexture2();
 | 
			
		||||
 | 
			
		||||
	u32 getMipmapLevel(s32 newLevel) const
 | 
			
		||||
	{
 | 
			
		||||
		if ( newLevel < 0 ) newLevel = 0;
 | 
			
		||||
		else if ( newLevel >= (s32)array_size(MipMap)) newLevel = array_size(MipMap) - 1;
 | 
			
		||||
 | 
			
		||||
		while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1;
 | 
			
		||||
		return newLevel;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//! lock function
 | 
			
		||||
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
	virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
 | 
			
		||||
#else
 | 
			
		||||
	virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_
 | 
			
		||||
#endif
 | 
			
		||||
	{
 | 
			
		||||
		if (Flags & GEN_MIPMAP)
 | 
			
		||||
		{
 | 
			
		||||
			//called from outside. must test
 | 
			
		||||
			MipMapLOD = getMipmapLevel(mipmapLevel);
 | 
			
		||||
			Size = MipMap[MipMapLOD]->getDimension();
 | 
			
		||||
			Pitch = MipMap[MipMapLOD]->getPitch();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return MipMap[MipMapLOD]->getData();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//! unlock function
 | 
			
		||||
	virtual void unlock() _IRR_OVERRIDE_
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
/*
 | 
			
		||||
	//! compare the area drawn with the area of the texture
 | 
			
		||||
	f32 getLODFactor( const f32 texArea ) const
 | 
			
		||||
	{
 | 
			
		||||
		return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea;
 | 
			
		||||
		//return MipMap[0]->getImageDataSizeInPixels () * texArea;
 | 
			
		||||
	}
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
	const u32* getMipMap0_Area() const
 | 
			
		||||
	{
 | 
			
		||||
		return MipMap0_Area;
 | 
			
		||||
	}
 | 
			
		||||
	f32 get_lod_bias() const { return LodBIAS; }
 | 
			
		||||
 | 
			
		||||
	//! returns unoptimized surface (misleading name. burning can scale down originalimage)
 | 
			
		||||
	virtual CImage* getImage() const
 | 
			
		||||
	{
 | 
			
		||||
		return MipMap[0];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//! returns texture surface
 | 
			
		||||
	virtual CImage* getTexture() const
 | 
			
		||||
	{
 | 
			
		||||
		return MipMap[MipMapLOD];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//precalculated dimx-1/dimx*0.5f
 | 
			
		||||
	const CSoftwareTexture2_Bound& getTexBound() const
 | 
			
		||||
	{
 | 
			
		||||
		return TexBound[MipMapLOD];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
	virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;
 | 
			
		||||
#else
 | 
			
		||||
	virtual void regenerateMipMapLevels(void* data = 0);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
	const core::dimension2d<u32>& getOriginalSize() const { return OriginalSize; };
 | 
			
		||||
	const core::dimension2d<u32>& getSize() const { return Size; };
 | 
			
		||||
	E_DRIVER_TYPE getDriverType() const { return DriverType; };
 | 
			
		||||
	ECOLOR_FORMAT getColorFormat() const { return ColorFormat; };
 | 
			
		||||
	ECOLOR_FORMAT getOriginalColorFormat() const { return OriginalColorFormat; };
 | 
			
		||||
	u32 getPitch() const { return Pitch; };
 | 
			
		||||
	bool hasMipMaps() const { return HasMipMaps; }
 | 
			
		||||
	bool isRenderTarget() const { return IsRenderTarget; }
 | 
			
		||||
 | 
			
		||||
	core::dimension2d<u32> OriginalSize;
 | 
			
		||||
	core::dimension2d<u32> Size;
 | 
			
		||||
	E_DRIVER_TYPE DriverType;
 | 
			
		||||
	ECOLOR_FORMAT OriginalColorFormat;
 | 
			
		||||
	ECOLOR_FORMAT ColorFormat;
 | 
			
		||||
	u32 Pitch;
 | 
			
		||||
	bool HasMipMaps;
 | 
			
		||||
	bool IsRenderTarget;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	void calcDerivative();
 | 
			
		||||
 | 
			
		||||
	//! controls MipmapSelection. relation between drawn area and image size
 | 
			
		||||
	u32 MipMapLOD; // 0 .. original Texture pot -SOFTWARE_DRIVER_2_MIPMAPPING_MAX
 | 
			
		||||
	u32 Flags; //eTex2Flags
 | 
			
		||||
	CBurningVideoDriver* Driver;
 | 
			
		||||
 | 
			
		||||
	CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
 | 
			
		||||
	CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
 | 
			
		||||
	u32 MipMap0_Area[2];
 | 
			
		||||
	f32 LodBIAS;	// Tweak mipmap selection
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
interface for a Video Driver dependent render target.
 | 
			
		||||
*/
 | 
			
		||||
class CSoftwareRenderTarget2 : public IRenderTarget
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	CSoftwareRenderTarget2(CBurningVideoDriver* driver);
 | 
			
		||||
	virtual ~CSoftwareRenderTarget2();
 | 
			
		||||
 | 
			
		||||
	virtual void setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces) _IRR_OVERRIDE_;
 | 
			
		||||
 | 
			
		||||
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
	E_DRIVER_TYPE DriverType;
 | 
			
		||||
	core::array<ITexture*> Texture;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
	CBurningVideoDriver* Driver;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // end namespace video
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
#endif // __C_SOFTWARE_2_TEXTURE_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,875 +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 __S_4D_VERTEX_H_INCLUDED__
 | 
			
		||||
#define __S_4D_VERTEX_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "SoftwareDriver2_compile_config.h"
 | 
			
		||||
#include "SoftwareDriver2_helper.h"
 | 
			
		||||
#include "irrAllocator.h"
 | 
			
		||||
#include "EPrimitiveTypes.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
namespace video
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
//! sVec2 used in BurningShader texture coordinates
 | 
			
		||||
struct sVec2
 | 
			
		||||
{
 | 
			
		||||
	f32 x;
 | 
			
		||||
	f32 y;
 | 
			
		||||
 | 
			
		||||
	sVec2 () {}
 | 
			
		||||
 | 
			
		||||
	sVec2 ( f32 s) : x ( s ), y ( s ) {}
 | 
			
		||||
	sVec2 ( f32 _x, f32 _y )
 | 
			
		||||
		: x ( _x ), y ( _y ) {}
 | 
			
		||||
 | 
			
		||||
	void set ( f32 _x, f32 _y )
 | 
			
		||||
	{
 | 
			
		||||
		x = _x;
 | 
			
		||||
		y = _y;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// f = a * t + b * ( 1 - t )
 | 
			
		||||
	void interpolate(const sVec2& burning_restrict a, const sVec2& burning_restrict b, const ipoltype t)
 | 
			
		||||
	{
 | 
			
		||||
		x = (f32)(b.x + ( ( a.x - b.x ) * t ));
 | 
			
		||||
		y = (f32)(b.y + ( ( a.y - b.y ) * t ));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec2 operator-(const sVec2& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec2(x - other.x, y - other.y);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec2 operator+(const sVec2& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec2(x + other.x, y + other.y);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator+=(const sVec2& other)
 | 
			
		||||
	{
 | 
			
		||||
		x += other.x;
 | 
			
		||||
		y += other.y;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec2 operator*(const f32 s) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec2(x * s , y * s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator*=( const f32 s)
 | 
			
		||||
	{
 | 
			
		||||
		x *= s;
 | 
			
		||||
		y *= s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator=(const sVec2& other)
 | 
			
		||||
	{
 | 
			
		||||
		x = other.x;
 | 
			
		||||
		y = other.y;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#include "irrpack.h"
 | 
			
		||||
 | 
			
		||||
//! sVec2Pack is Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents Texutre Coordinates.
 | 
			
		||||
// Start address is not 4 byte aligned
 | 
			
		||||
struct sVec2Pack
 | 
			
		||||
{
 | 
			
		||||
	f32 x, y;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//! sVec3Pack used in BurningShader, packed direction
 | 
			
		||||
struct sVec3Pack
 | 
			
		||||
{
 | 
			
		||||
	f32 x, y, z;
 | 
			
		||||
	//f32 _can_pack;
 | 
			
		||||
 | 
			
		||||
	sVec3Pack() {}
 | 
			
		||||
	sVec3Pack(f32 _x, f32 _y, f32 _z)
 | 
			
		||||
		: x(_x), y(_y), z(_z) {}
 | 
			
		||||
 | 
			
		||||
	// f = a * t + b * ( 1 - t )
 | 
			
		||||
	void interpolate(const sVec3Pack& burning_restrict v0, const sVec3Pack& burning_restrict v1, const ipoltype t)
 | 
			
		||||
	{
 | 
			
		||||
		x = (f32)(v1.x + ((v0.x - v1.x) * t));
 | 
			
		||||
		y = (f32)(v1.y + ((v0.y - v1.y) * t));
 | 
			
		||||
		z = (f32)(v1.z + ((v0.z - v1.z) * t));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec3Pack operator-(const sVec3Pack& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec3Pack(x - other.x, y - other.y, z - other.z);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec3Pack operator+(const sVec3Pack& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec3Pack(x + other.x, y + other.y, z + other.z);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec3Pack operator*(const f32 s) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec3Pack(x * s, y * s, z * s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator+=(const sVec3Pack& other)
 | 
			
		||||
	{
 | 
			
		||||
		x += other.x;
 | 
			
		||||
		y += other.y;
 | 
			
		||||
		z += other.z;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator=(const sVec3Pack& other)
 | 
			
		||||
	{
 | 
			
		||||
		x = other.x;
 | 
			
		||||
		y = other.y;
 | 
			
		||||
		z = other.z;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}  PACK_STRUCT;
 | 
			
		||||
 | 
			
		||||
#include "irrunpack.h"
 | 
			
		||||
 | 
			
		||||
//! sVec4 used in Driver,BurningShader, direction/color
 | 
			
		||||
struct sVec4
 | 
			
		||||
{
 | 
			
		||||
	union
 | 
			
		||||
	{
 | 
			
		||||
		struct { f32 x, y, z, w; };
 | 
			
		||||
		struct { f32 a, r, g, b; };
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	sVec4 () {}
 | 
			
		||||
	sVec4 ( f32 _x, f32 _y, f32 _z, f32 _w )
 | 
			
		||||
		: x ( _x ), y ( _y ), z( _z ), w ( _w ){}
 | 
			
		||||
 | 
			
		||||
	// f = a * t + b * ( 1 - t )
 | 
			
		||||
	void interpolate(const sVec4& burning_restrict a, const sVec4& burning_restrict b, const ipoltype t)
 | 
			
		||||
	{
 | 
			
		||||
		x = (f32)(b.x + ( ( a.x - b.x ) * t ));
 | 
			
		||||
		y = (f32)(b.y + ( ( a.y - b.y ) * t ));
 | 
			
		||||
		z = (f32)(b.z + ( ( a.z - b.z ) * t ));
 | 
			
		||||
		w = (f32)(b.w + ( ( a.w - b.w ) * t ));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec4 operator-(const sVec4& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec4(x - other.x, y - other.y, z - other.z,w - other.w);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec4 operator+(const sVec4& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec4(x + other.x, y + other.y, z + other.z,w + other.w);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator+=(const sVec4& other)
 | 
			
		||||
	{
 | 
			
		||||
		x += other.x;
 | 
			
		||||
		y += other.y;
 | 
			
		||||
		z += other.z;
 | 
			
		||||
		w += other.w;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec4 operator*(const f32 s) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec4(x * s , y * s, z * s,w * s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sVec4 operator*(const sVec4 &other) const
 | 
			
		||||
	{
 | 
			
		||||
		return sVec4(x * other.x , y * other.y, z * other.z,w * other.w);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator*=(const sVec4 &other)
 | 
			
		||||
	{
 | 
			
		||||
		x *= other.x;
 | 
			
		||||
		y *= other.y;
 | 
			
		||||
		z *= other.z;
 | 
			
		||||
		w *= other.w;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator=(const sVec4& other)
 | 
			
		||||
	{
 | 
			
		||||
		x = other.x;
 | 
			
		||||
		y = other.y;
 | 
			
		||||
		z = other.z;
 | 
			
		||||
		w = other.w;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//outside shader
 | 
			
		||||
	void set(f32 _x, f32 _y, f32 _z, f32 _w)
 | 
			
		||||
	{
 | 
			
		||||
		x = _x;
 | 
			
		||||
		y = _y;
 | 
			
		||||
		z = _z;
 | 
			
		||||
		w = _w;
 | 
			
		||||
	}
 | 
			
		||||
	void setA8R8G8B8(const u32 argb)
 | 
			
		||||
	{
 | 
			
		||||
		a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
 | 
			
		||||
		r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);
 | 
			
		||||
		g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);
 | 
			
		||||
		b = ((argb & 0x000000FF)      ) * (1.f / 255.f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	REALINLINE ipoltype dot_xyzw(const sVec4& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return (ipoltype)x * other.x + (ipoltype)y * other.y + (ipoltype)z * other.z + (ipoltype)w * other.w;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	REALINLINE f32 dot_xyz(const sVec4& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return x * other.x + y * other.y + z * other.z;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	REALINLINE f32 dot_minus_xyz(const sVec4& other) const
 | 
			
		||||
	{
 | 
			
		||||
		return -x * other.x + -y * other.y + -z * other.z;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void mul_xyz(const f32 s)
 | 
			
		||||
	{
 | 
			
		||||
		x *= s;
 | 
			
		||||
		y *= s;
 | 
			
		||||
		z *= s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	f32 length_xyz() const
 | 
			
		||||
	{
 | 
			
		||||
		return sqrtf(x * x + y * y + z * z);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void normalize_dir_xyz()
 | 
			
		||||
	{
 | 
			
		||||
		//const f32 l = core::reciprocal_squareroot(x * x + y * y + z * z);
 | 
			
		||||
		f32 l = x * x + y * y + z * z;
 | 
			
		||||
		l = l > 0.0000001f ? 1.f / sqrtf(l) : 1.f;
 | 
			
		||||
		x *= l;
 | 
			
		||||
		y *= l;
 | 
			
		||||
		z *= l;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	//unpack sVec3 to aligned during runtime
 | 
			
		||||
	sVec4(const sVec3Pack& other)
 | 
			
		||||
	{
 | 
			
		||||
		x = other.x;
 | 
			
		||||
		y = other.y;
 | 
			
		||||
		z = other.z;
 | 
			
		||||
		w = 0.f;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void normalize_pack_xyz(sVec3Pack& out, const f32 len, const f32 ofs) const
 | 
			
		||||
	{
 | 
			
		||||
		//const f32 l = len * core::reciprocal_squareroot ( r * r + g * g + b * b );
 | 
			
		||||
		f32 l = x * x + y * y + z * z;
 | 
			
		||||
 | 
			
		||||
		l = l > 0.0000001f ? len / sqrtf(l) : 0.f;
 | 
			
		||||
		out.x = (x*l) + ofs;
 | 
			
		||||
		out.y = (y*l) + ofs;
 | 
			
		||||
		out.z = (z*l) + ofs;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//!during runtime sVec3Pack
 | 
			
		||||
typedef sVec4 sVec3Pack_unpack;
 | 
			
		||||
 | 
			
		||||
//!sVec4 is argb. sVec3Color is rgba
 | 
			
		||||
struct sVec3Color
 | 
			
		||||
{
 | 
			
		||||
	f32 r, g, b,a;
 | 
			
		||||
 | 
			
		||||
	void set(const f32 s)
 | 
			
		||||
	{
 | 
			
		||||
		r = s;
 | 
			
		||||
		g = s;
 | 
			
		||||
		b = s;
 | 
			
		||||
		a = s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void setA8R8G8B8(const u32 argb)
 | 
			
		||||
	{
 | 
			
		||||
		r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);
 | 
			
		||||
		g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);
 | 
			
		||||
		b = ((argb & 0x000000FF)      ) * (1.f / 255.f);
 | 
			
		||||
		a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void setColorf(const video::SColorf & color)
 | 
			
		||||
	{
 | 
			
		||||
		r = color.r;
 | 
			
		||||
		g = color.g;
 | 
			
		||||
		b = color.b;
 | 
			
		||||
		a = color.a;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void add_rgb(const sVec3Color& other)
 | 
			
		||||
	{
 | 
			
		||||
		r += other.r;
 | 
			
		||||
		g += other.g;
 | 
			
		||||
		b += other.b;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void mad_rgb(const sVec3Color& other, const f32 v)
 | 
			
		||||
	{
 | 
			
		||||
		r += other.r * v;
 | 
			
		||||
		g += other.g * v;
 | 
			
		||||
		b += other.b * v;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void mad_rgbv(const sVec3Color& v0, const sVec3Color& v1)
 | 
			
		||||
	{
 | 
			
		||||
		r += v0.r * v1.r;
 | 
			
		||||
		g += v0.g * v1.g;
 | 
			
		||||
		b += v0.b * v1.b;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//sVec4 is a,r,g,b, alpha pass
 | 
			
		||||
	void sat(sVec4 &dest, const u32 argb) const
 | 
			
		||||
	{
 | 
			
		||||
		dest.a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
 | 
			
		||||
		dest.r = r <= 1.f ? r : 1.f;
 | 
			
		||||
		dest.g = g <= 1.f ? g : 1.f;
 | 
			
		||||
		dest.b = b <= 1.f ? b : 1.f;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void sat_xyz(sVec3Pack &dest, const sVec3Color& v1) const
 | 
			
		||||
	{
 | 
			
		||||
		f32 v;
 | 
			
		||||
		v = r * v1.r;	dest.x = v < 1.f ? v : 1.f;
 | 
			
		||||
		v = g * v1.g;	dest.y = v < 1.f ? v : 1.f;
 | 
			
		||||
		v = b * v1.b;	dest.z = v < 1.f ? v : 1.f;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void sat_xyz(sVec4 &dest, const sVec3Color& v1) const
 | 
			
		||||
	{
 | 
			
		||||
		f32 v;
 | 
			
		||||
		dest.a = 1.f;
 | 
			
		||||
		v = r * v1.r;	dest.r = v < 1.f ? v : 1.f;
 | 
			
		||||
		v = g * v1.g;	dest.g = v < 1.f ? v : 1.f;
 | 
			
		||||
		v = b * v1.b;	dest.b = v < 1.f ? v : 1.f;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//internal BurningShaderFlag for a Vertex
 | 
			
		||||
enum e4DVertexFlag
 | 
			
		||||
{
 | 
			
		||||
	VERTEX4D_CLIPMASK				= 0x0000003F,
 | 
			
		||||
	VERTEX4D_CLIP_NEAR				= 0x00000001,
 | 
			
		||||
	VERTEX4D_CLIP_FAR				= 0x00000002,
 | 
			
		||||
	VERTEX4D_CLIP_LEFT				= 0x00000004,
 | 
			
		||||
	VERTEX4D_CLIP_RIGHT				= 0x00000008,
 | 
			
		||||
	VERTEX4D_CLIP_BOTTOM			= 0x00000010,
 | 
			
		||||
	VERTEX4D_CLIP_TOP				= 0x00000020,
 | 
			
		||||
	VERTEX4D_INSIDE					= 0x0000003F,
 | 
			
		||||
 | 
			
		||||
	VERTEX4D_PROJECTED				= 0x00000100,
 | 
			
		||||
	VERTEX4D_VAL_ZERO				= 0x00000200,
 | 
			
		||||
	VERTEX4D_VAL_ONE				= 0x00000400,
 | 
			
		||||
 | 
			
		||||
	VERTEX4D_FORMAT_MASK			= 0xFFFF0000,
 | 
			
		||||
 | 
			
		||||
	VERTEX4D_FORMAT_MASK_TEXTURE	= 0x000F0000,
 | 
			
		||||
	VERTEX4D_FORMAT_TEXTURE_1		= 0x00010000,
 | 
			
		||||
	VERTEX4D_FORMAT_TEXTURE_2		= 0x00020000,
 | 
			
		||||
	VERTEX4D_FORMAT_TEXTURE_3		= 0x00030000,
 | 
			
		||||
	VERTEX4D_FORMAT_TEXTURE_4		= 0x00040000,
 | 
			
		||||
 | 
			
		||||
	VERTEX4D_FORMAT_MASK_COLOR		= 0x00F00000,
 | 
			
		||||
	VERTEX4D_FORMAT_COLOR_1			= 0x00100000,
 | 
			
		||||
	VERTEX4D_FORMAT_COLOR_2_FOG		= 0x00200000,
 | 
			
		||||
	VERTEX4D_FORMAT_COLOR_3			= 0x00300000,
 | 
			
		||||
	VERTEX4D_FORMAT_COLOR_4			= 0x00400000,
 | 
			
		||||
 | 
			
		||||
	VERTEX4D_FORMAT_MASK_LIGHT		= 0x0F000000,
 | 
			
		||||
	VERTEX4D_FORMAT_LIGHT_1			= 0x01000000,
 | 
			
		||||
	VERTEX4D_FORMAT_LIGHT_2			= 0x02000000,
 | 
			
		||||
 | 
			
		||||
	VERTEX4D_FORMAT_MASK_TANGENT	= 0xF0000000,
 | 
			
		||||
	VERTEX4D_FORMAT_BUMP_DOT3		= 0x10000000,
 | 
			
		||||
	VERTEX4D_FORMAT_SPECULAR		= 0x20000000,
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//! vertex layout
 | 
			
		||||
enum e4DVertexType
 | 
			
		||||
{
 | 
			
		||||
	E4VT_STANDARD = 0,			// EVT_STANDARD, video::S3DVertex.
 | 
			
		||||
	E4VT_2TCOORDS = 1,			// EVT_2TCOORDS, video::S3DVertex2TCoords.
 | 
			
		||||
	E4VT_TANGENTS = 2,			// EVT_TANGENTS, video::S3DVertexTangents
 | 
			
		||||
	E4VT_REFLECTION_MAP = 3,
 | 
			
		||||
	E4VT_SHADOW = 4,			// float * 3
 | 
			
		||||
	E4VT_NO_TEXTURE = 5,		// runtime if texture missing
 | 
			
		||||
	E4VT_LINE = 6,
 | 
			
		||||
 | 
			
		||||
	E4VT_COUNT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum e4DIndexType
 | 
			
		||||
{
 | 
			
		||||
	E4IT_16BIT = 1, // EIT_16BIT,
 | 
			
		||||
	E4IT_32BIT = 2, // EIT_32BIT,
 | 
			
		||||
	E4IT_NONE  = 4, //
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
 | 
			
		||||
	#define BURNING_MATERIAL_MAX_TEXTURES 4
 | 
			
		||||
	#define BURNING_MATERIAL_MAX_COLORS 4
 | 
			
		||||
	#define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
 | 
			
		||||
 | 
			
		||||
	//ensure handcrafted sizeof(s4DVertex)
 | 
			
		||||
	#define sizeof_s4DVertex	128
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	#define BURNING_MATERIAL_MAX_TEXTURES 2
 | 
			
		||||
	#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
 | 
			
		||||
		#define BURNING_MATERIAL_MAX_COLORS 1
 | 
			
		||||
	#else
 | 
			
		||||
		#define BURNING_MATERIAL_MAX_COLORS 0
 | 
			
		||||
	#endif
 | 
			
		||||
	#define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
 | 
			
		||||
 | 
			
		||||
	//ensure handcrafted sizeof(s4DVertex)
 | 
			
		||||
	#define sizeof_s4DVertex	64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// dummy Vertex. used for calculation vertex memory size
 | 
			
		||||
struct s4DVertex_proxy
 | 
			
		||||
{
 | 
			
		||||
	sVec4 Pos;
 | 
			
		||||
#if BURNING_MATERIAL_MAX_TEXTURES > 0
 | 
			
		||||
	sVec2 Tex[BURNING_MATERIAL_MAX_TEXTURES];
 | 
			
		||||
#endif
 | 
			
		||||
#if BURNING_MATERIAL_MAX_COLORS > 0
 | 
			
		||||
	sVec4 Color[BURNING_MATERIAL_MAX_COLORS];
 | 
			
		||||
#endif
 | 
			
		||||
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
 | 
			
		||||
	sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
 | 
			
		||||
#endif
 | 
			
		||||
	u32 flag; // e4DVertexFlag
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	Internal BurningVideo Vertex
 | 
			
		||||
*/
 | 
			
		||||
struct s4DVertex
 | 
			
		||||
{
 | 
			
		||||
	sVec4 Pos;
 | 
			
		||||
#if BURNING_MATERIAL_MAX_TEXTURES > 0
 | 
			
		||||
	sVec2 Tex[ BURNING_MATERIAL_MAX_TEXTURES ];
 | 
			
		||||
#endif
 | 
			
		||||
#if BURNING_MATERIAL_MAX_COLORS > 0
 | 
			
		||||
	sVec4 Color[ BURNING_MATERIAL_MAX_COLORS ];
 | 
			
		||||
#endif
 | 
			
		||||
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
 | 
			
		||||
	sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	u32 flag; // e4DVertexFlag
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_COLORS < 1 || BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
 | 
			
		||||
	u8 __align [sizeof_s4DVertex - sizeof (s4DVertex_proxy) ];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	// f = a * t + b * ( 1 - t )
 | 
			
		||||
	void interpolate(const s4DVertex& burning_restrict b, const s4DVertex& burning_restrict a, const ipoltype t)
 | 
			
		||||
	{
 | 
			
		||||
		Pos.interpolate ( a.Pos, b.Pos, t );
 | 
			
		||||
#if 0
 | 
			
		||||
		Tex[0].interpolate(a.Tex[0], b.Tex[0], t);
 | 
			
		||||
		Tex[1].interpolate(a.Tex[1], b.Tex[1], t);
 | 
			
		||||
		Color[0].interpolate(a.Color[0], b.Color[0], t);
 | 
			
		||||
		LightTangent[0].interpolate(a.LightTangent[0], b.LightTangent[0], t);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		size_t i;
 | 
			
		||||
		size_t size;
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_TEXTURES > 0
 | 
			
		||||
		size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;
 | 
			
		||||
		for ( i = 0; i!= size; ++i )
 | 
			
		||||
		{
 | 
			
		||||
			Tex[i].interpolate ( a.Tex[i], b.Tex[i], t );
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_COLORS > 0
 | 
			
		||||
		size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;
 | 
			
		||||
		for ( i = 0; i!= size; ++i )
 | 
			
		||||
		{
 | 
			
		||||
			Color[i].interpolate ( a.Color[i], b.Color[i], t );
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
 | 
			
		||||
		size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24;
 | 
			
		||||
		for ( i = 0; i!= size; ++i )
 | 
			
		||||
		{
 | 
			
		||||
			LightTangent[i].interpolate ( a.LightTangent[i], b.LightTangent[i], t );
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// ----------------- Vertex Cache ---------------------------
 | 
			
		||||
 | 
			
		||||
// Buffer is used as pairs of S4DVertex (0 ... ndc, 1 .. dc and projected)
 | 
			
		||||
typedef s4DVertex s4DVertexPair;
 | 
			
		||||
#define sizeof_s4DVertexPairRel 2
 | 
			
		||||
#define s4DVertex_ofs(index)  ((index)*sizeof_s4DVertexPairRel)
 | 
			
		||||
#define s4DVertex_proj(index) ((index)*sizeof_s4DVertexPairRel) + 1
 | 
			
		||||
 | 
			
		||||
struct SAligned4DVertex
 | 
			
		||||
{
 | 
			
		||||
	SAligned4DVertex()
 | 
			
		||||
		:data(0),ElementSize(0),mem(0)	{}
 | 
			
		||||
 | 
			
		||||
	virtual ~SAligned4DVertex ()
 | 
			
		||||
	{
 | 
			
		||||
		if (mem)
 | 
			
		||||
		{
 | 
			
		||||
			delete[] mem;
 | 
			
		||||
			mem = 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void resize(size_t element)
 | 
			
		||||
	{
 | 
			
		||||
		if (element > ElementSize)
 | 
			
		||||
		{
 | 
			
		||||
			if (mem) delete[] mem;
 | 
			
		||||
			size_t byteSize = align_next(element * sizeof_s4DVertex, 4096);
 | 
			
		||||
			mem = new u8[byteSize];
 | 
			
		||||
		}
 | 
			
		||||
		ElementSize = element;
 | 
			
		||||
		data = (s4DVertex*)mem;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s4DVertex* data;	//align to 16 byte
 | 
			
		||||
	size_t ElementSize;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
	u8* mem;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//#define memcpy_s4DVertexPair(dst,src) memcpy(dst,src,sizeof_s4DVertex * 2)
 | 
			
		||||
static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const void* burning_restrict src)
 | 
			
		||||
{
 | 
			
		||||
	//test alignment -> if already in aligned data
 | 
			
		||||
#if 0
 | 
			
		||||
	if (((size_t)dst & 0xC) | ((size_t)src & 0xC))
 | 
			
		||||
	{
 | 
			
		||||
		int g = 1;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(ENV64BIT) && (sizeof_s4DVertex * sizeof_s4DVertexPairRel == 128)
 | 
			
		||||
	u64* burning_restrict dst64 = (u64*)dst;
 | 
			
		||||
	const u64* burning_restrict src64 = (const u64*)src;
 | 
			
		||||
 | 
			
		||||
	dst64[0]  = src64[0];
 | 
			
		||||
	dst64[1]  = src64[1];
 | 
			
		||||
	dst64[2]  = src64[2];
 | 
			
		||||
	dst64[3]  = src64[3];
 | 
			
		||||
	dst64[4]  = src64[4];
 | 
			
		||||
	dst64[5]  = src64[5];
 | 
			
		||||
	dst64[6]  = src64[6];
 | 
			
		||||
	dst64[7]  = src64[7];
 | 
			
		||||
 | 
			
		||||
	dst64[8]  = src64[8];
 | 
			
		||||
	dst64[9]  = src64[9];
 | 
			
		||||
	dst64[10] = src64[10];
 | 
			
		||||
	dst64[11] = src64[11];
 | 
			
		||||
	dst64[12] = src64[12];
 | 
			
		||||
	dst64[13] = src64[13];
 | 
			
		||||
	dst64[14] = src64[14];
 | 
			
		||||
	dst64[15] = src64[15];
 | 
			
		||||
 | 
			
		||||
#elif defined(ENV64BIT) && (sizeof_s4DVertex * sizeof_s4DVertexPairRel == 256)
 | 
			
		||||
	u64* burning_restrict dst64 = (u64*)dst;
 | 
			
		||||
	const u64* burning_restrict src64 = (const u64*)src;
 | 
			
		||||
 | 
			
		||||
	dst64[0]  = src64[0];
 | 
			
		||||
	dst64[1]  = src64[1];
 | 
			
		||||
	dst64[2]  = src64[2];
 | 
			
		||||
	dst64[3]  = src64[3];
 | 
			
		||||
	dst64[4]  = src64[4];
 | 
			
		||||
	dst64[5]  = src64[5];
 | 
			
		||||
	dst64[6]  = src64[6];
 | 
			
		||||
	dst64[7]  = src64[7];
 | 
			
		||||
 | 
			
		||||
	dst64[8]  = src64[8];
 | 
			
		||||
	dst64[9]  = src64[9];
 | 
			
		||||
	dst64[10] = src64[10];
 | 
			
		||||
	dst64[11] = src64[11];
 | 
			
		||||
	dst64[12] = src64[12];
 | 
			
		||||
	dst64[13] = src64[13];
 | 
			
		||||
	dst64[14] = src64[14];
 | 
			
		||||
	dst64[15] = src64[15];
 | 
			
		||||
 | 
			
		||||
	dst64[16] = src64[16];
 | 
			
		||||
	dst64[17] = src64[17];
 | 
			
		||||
	dst64[18] = src64[18];
 | 
			
		||||
	dst64[19] = src64[19];
 | 
			
		||||
	dst64[20] = src64[20];
 | 
			
		||||
	dst64[21] = src64[21];
 | 
			
		||||
	dst64[22] = src64[22];
 | 
			
		||||
	dst64[23] = src64[23];
 | 
			
		||||
 | 
			
		||||
	dst64[24] = src64[24];
 | 
			
		||||
	dst64[25] = src64[25];
 | 
			
		||||
	dst64[26] = src64[26];
 | 
			
		||||
	dst64[27] = src64[27];
 | 
			
		||||
	dst64[28] = src64[28];
 | 
			
		||||
	dst64[29] = src64[29];
 | 
			
		||||
	dst64[30] = src64[30];
 | 
			
		||||
	dst64[31] = src64[31];
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
	u32* dst32 = (u32*)dst;
 | 
			
		||||
	const u32* src32 = (const u32*)src;
 | 
			
		||||
 | 
			
		||||
	size_t len = sizeof_s4DVertex * sizeof_s4DVertexPairRel;
 | 
			
		||||
	while (len >= 32)
 | 
			
		||||
	{
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		len -= 32;
 | 
			
		||||
	}
 | 
			
		||||
/*
 | 
			
		||||
	while (len >= 4)
 | 
			
		||||
	{
 | 
			
		||||
		*dst32++ = *src32++;
 | 
			
		||||
		len -= 4;
 | 
			
		||||
	}
 | 
			
		||||
*/
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! hold info for different Vertex Types
 | 
			
		||||
struct SVSize
 | 
			
		||||
{
 | 
			
		||||
	size_t Format;		// e4DVertexFlag VERTEX4D_FORMAT_MASK_TEXTURE
 | 
			
		||||
	size_t Pitch;		// sizeof Vertex
 | 
			
		||||
	size_t TexSize;	// amount Textures
 | 
			
		||||
	size_t TexCooSize;	// sizeof TextureCoordinates
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// a cache info
 | 
			
		||||
struct SCacheInfo
 | 
			
		||||
{
 | 
			
		||||
	u32 index;
 | 
			
		||||
	u32 hit;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//must at least hold all possible (clipped) vertices of primitive.
 | 
			
		||||
#define VERTEXCACHE_ELEMENT	16			
 | 
			
		||||
#define VERTEXCACHE_MISS 0xFFFFFFFF
 | 
			
		||||
struct SVertexCache
 | 
			
		||||
{
 | 
			
		||||
	SVertexCache () {}
 | 
			
		||||
	~SVertexCache() {}
 | 
			
		||||
 | 
			
		||||
	//VertexType
 | 
			
		||||
	SVSize vSize[E4VT_COUNT];
 | 
			
		||||
 | 
			
		||||
	SCacheInfo info[VERTEXCACHE_ELEMENT];
 | 
			
		||||
	SCacheInfo info_temp[VERTEXCACHE_ELEMENT];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Transformed and lite, clipping state
 | 
			
		||||
	// + Clipped, Projected
 | 
			
		||||
	SAligned4DVertex mem;
 | 
			
		||||
 | 
			
		||||
	// source
 | 
			
		||||
	const void* vertices;
 | 
			
		||||
	u32 vertexCount;
 | 
			
		||||
 | 
			
		||||
	const void* indices;
 | 
			
		||||
	u32 indexCount;
 | 
			
		||||
	u32 indicesIndex;
 | 
			
		||||
	u32 indicesRun;
 | 
			
		||||
	u32 indicesPitch;
 | 
			
		||||
 | 
			
		||||
	// primitives consist of x vertices
 | 
			
		||||
	size_t primitiveHasVertex;
 | 
			
		||||
 | 
			
		||||
	e4DVertexType vType;		//E_VERTEX_TYPE
 | 
			
		||||
	scene::E_PRIMITIVE_TYPE pType;		//scene::E_PRIMITIVE_TYPE
 | 
			
		||||
	e4DIndexType iType;		//E_INDEX_TYPE iType
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// swap 2 pointer
 | 
			
		||||
REALINLINE void swapVertexPointer(const s4DVertex** v1, const s4DVertex** v2)
 | 
			
		||||
{
 | 
			
		||||
	const s4DVertex* b = *v1;
 | 
			
		||||
	*v1 = *v2;
 | 
			
		||||
	*v2 = b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ------------------------ Internal Scanline Rasterizer -----------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// internal scan convert
 | 
			
		||||
struct sScanConvertData
 | 
			
		||||
{
 | 
			
		||||
	u32 left;			// major edge left/right
 | 
			
		||||
	u32 right;			// !left
 | 
			
		||||
	u8 _unused_pack[8];
 | 
			
		||||
 | 
			
		||||
	f32 invDeltaY[4];	// inverse edge delta for screen space sorted triangle 
 | 
			
		||||
 | 
			
		||||
	f32 x[2];			// x coordinate
 | 
			
		||||
	f32 slopeX[2];		// x slope along edges
 | 
			
		||||
 | 
			
		||||
#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )
 | 
			
		||||
	f32 w[2];			// w coordinate
 | 
			
		||||
	fp24 slopeW[2];		// w slope along edges
 | 
			
		||||
#else
 | 
			
		||||
	f32 z[2];			// z coordinate
 | 
			
		||||
	f32 slopeZ[2];		// z slope along edges
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_COLORS > 0
 | 
			
		||||
	sVec4 c[BURNING_MATERIAL_MAX_COLORS][2];		// color
 | 
			
		||||
	sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS][2];	// color slope along edges
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_TEXTURES > 0
 | 
			
		||||
	sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2];		// texture
 | 
			
		||||
	sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES][2];	// texture slope along edges
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
 | 
			
		||||
	sVec3Pack_unpack l[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2];		// Light Tangent
 | 
			
		||||
	sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2];	// tanget slope along edges
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// passed to scan Line
 | 
			
		||||
struct sScanLineData
 | 
			
		||||
{
 | 
			
		||||
	s32 y;				// y position of scanline
 | 
			
		||||
	u8 _unused_pack[4];
 | 
			
		||||
	f32 x[2];			// x start, x end of scanline
 | 
			
		||||
 | 
			
		||||
#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )
 | 
			
		||||
	f32 w[2];			// w start, w end of scanline
 | 
			
		||||
#else
 | 
			
		||||
	f32 z[2];			// z start, z end of scanline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	s32 x_edgetest;		// slope x
 | 
			
		||||
	u8 _unused_pack_1[4];
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_COLORS > 0
 | 
			
		||||
	sVec4 c[BURNING_MATERIAL_MAX_COLORS][2];			// color start, color end of scanline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_TEXTURES > 0
 | 
			
		||||
	sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2];		// texture start, texture end of scanline
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
 | 
			
		||||
	sVec3Pack_unpack l[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2];		// Light Tangent start, end
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// passed to pixel Shader
 | 
			
		||||
struct sPixelShaderData
 | 
			
		||||
{
 | 
			
		||||
	tVideoSample *dst;
 | 
			
		||||
	fp24 *z;
 | 
			
		||||
 | 
			
		||||
	s32 xStart;
 | 
			
		||||
	s32 xEnd;
 | 
			
		||||
	s32 dx;
 | 
			
		||||
	s32 i;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	load a color value
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE void getTexel_plain2 (	tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v	)
 | 
			
		||||
{
 | 
			
		||||
	r = tofix(v.r, FIX_POINT_F32_MUL);
 | 
			
		||||
	g = tofix(v.g, FIX_POINT_F32_MUL);
 | 
			
		||||
	b = tofix(v.b, FIX_POINT_F32_MUL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
/*
 | 
			
		||||
	load a color value
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE void getSample_color (	tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,	const sVec4 &v )
 | 
			
		||||
{
 | 
			
		||||
	a = tofix ( v.a, FIX_POINT_F32_MUL);
 | 
			
		||||
	r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL);
 | 
			
		||||
	g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);
 | 
			
		||||
	b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	load a color value
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )
 | 
			
		||||
{
 | 
			
		||||
	r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL);
 | 
			
		||||
	g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);
 | 
			
		||||
	b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	load a color value. mulby controls [0;1] or [0;ColorMax]
 | 
			
		||||
	aka getSample_color
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE void vec4_to_fix(tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby )
 | 
			
		||||
{
 | 
			
		||||
	r = tofix(v.r, mulby);
 | 
			
		||||
	g = tofix(v.g, mulby);
 | 
			
		||||
	b = tofix(v.b, mulby);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
REALINLINE void vec4_to_fix(tFixPoint &a,tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby)
 | 
			
		||||
{
 | 
			
		||||
	a = tofix(v.a, mulby);
 | 
			
		||||
	r = tofix(v.r, mulby);
 | 
			
		||||
	g = tofix(v.g, mulby);
 | 
			
		||||
	b = tofix(v.b, mulby);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@@ -7,28 +7,6 @@
 | 
			
		||||
 | 
			
		||||
#include "IrrCompileConfig.h"
 | 
			
		||||
 | 
			
		||||
// Generic Render Flags for burning's video rasterizer
 | 
			
		||||
// defined now in irrlicht compile config
 | 
			
		||||
 | 
			
		||||
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
 | 
			
		||||
#define SOFTWARE_DRIVER_2_SUBTEXEL
 | 
			
		||||
#define SOFTWARE_DRIVER_2_BILINEAR
 | 
			
		||||
#define SOFTWARE_DRIVER_2_LIGHTING
 | 
			
		||||
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
 | 
			
		||||
#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
 | 
			
		||||
#define SOFTWARE_DRIVER_2_USE_WBUFFER
 | 
			
		||||
#define SOFTWARE_DRIVER_2_32BIT
 | 
			
		||||
#define	SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT	ECF_A8R8G8B8
 | 
			
		||||
#define	SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT	ECF_A8R8G8B8
 | 
			
		||||
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE		0x100000
 | 
			
		||||
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
 | 
			
		||||
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX		16
 | 
			
		||||
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE   1
 | 
			
		||||
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
 | 
			
		||||
#define SOFTWARE_DRIVER_2_CLIPPING
 | 
			
		||||
#define SOFTWARE_DRIVER_2_2D_AS_3D
 | 
			
		||||
#define SOFTWARE_DRIVER_2_INTERLACED
 | 
			
		||||
 | 
			
		||||
#ifndef REALINLINE
 | 
			
		||||
#ifdef _MSC_VER
 | 
			
		||||
#define REALINLINE __forceinline
 | 
			
		||||
@@ -37,195 +15,12 @@
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f)
 | 
			
		||||
#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)
 | 
			
		||||
 | 
			
		||||
//Control Scanline output
 | 
			
		||||
#define SOFTWARE_DRIVER_2_STEP_X 1
 | 
			
		||||
#define SOFTWARE_DRIVER_2_STEP_Y 1
 | 
			
		||||
 | 
			
		||||
// null check necessary (burningvideo only)
 | 
			
		||||
#define fill_step_y(y) ((y) != 0.f ? (float)1.f / (y):0.f)
 | 
			
		||||
static inline float fill_step_x(float x) { return x != 0.f ? (float)SOFTWARE_DRIVER_2_STEP_X / x : 0.f; }
 | 
			
		||||
 | 
			
		||||
#define interlace_control_bit 1
 | 
			
		||||
#define interlace_control_mask ((1<<interlace_control_bit)-1)
 | 
			
		||||
struct interlaced_control
 | 
			
		||||
{
 | 
			
		||||
	unsigned enable : 1;
 | 
			
		||||
	unsigned bypass : 1;
 | 
			
		||||
	unsigned nr : interlace_control_bit;
 | 
			
		||||
};
 | 
			
		||||
struct interlace_scanline_data { unsigned int y; };
 | 
			
		||||
 | 
			
		||||
static inline interlaced_control interlace_disabled()
 | 
			
		||||
{
 | 
			
		||||
	interlaced_control v;
 | 
			
		||||
	v.enable = 0;
 | 
			
		||||
	v.bypass = 1;
 | 
			
		||||
	v.nr = 0;
 | 
			
		||||
	return v;
 | 
			
		||||
}
 | 
			
		||||
#if defined(SOFTWARE_DRIVER_2_INTERLACED)
 | 
			
		||||
#define interlace_scanline if ( Interlaced.bypass | ((line.y & interlace_control_mask) == Interlaced.nr) )
 | 
			
		||||
#define interlace_scanline_enabled if ( (line.y & interlace_control_mask) == Interlaced.nr )
 | 
			
		||||
//#define interlace_scanline if ( Interlaced.disabled | (((line.y >> (interlace_control_bit-1) ) & 1) == (Interlaced.nr & 1)) )
 | 
			
		||||
//#define interlace_scanline
 | 
			
		||||
#else
 | 
			
		||||
#define interlace_scanline
 | 
			
		||||
#define interlace_scanline_enabled
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define scissor_test_y if ((~TL_Flag & TL_SCISSOR) || ((line.y >= Scissor.y0) & (line.y <= Scissor.y1)))
 | 
			
		||||
#define scissor_test_x if ((~TL_Flag & TL_SCISSOR) || ((i+xStart >= Scissor.x0) & (i+xStart <= Scissor.x1)))
 | 
			
		||||
 | 
			
		||||
#define fill_convention_left(x) (s32) ceilf(x)
 | 
			
		||||
#define fill_convention_right(x) ((s32) ceilf(x))-1
 | 
			
		||||
#define fill_convention_none(x) (s32) (x)
 | 
			
		||||
#define fill_convention_edge(x) (s32) floorf(fabsf(x)+0.f)
 | 
			
		||||
//#define fill_convention_left(x) 65536 - int(65536.0f - x)
 | 
			
		||||
//#define fill_convention_right(x) 65535 - int(65536.0f - x)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//Check coordinates are in render target/window space
 | 
			
		||||
//#define SOFTWARE_DRIVER_2_DO_CLIPCHECK
 | 
			
		||||
#if defined (SOFTWARE_DRIVER_2_DO_CLIPCHECK) && defined(_WIN32)
 | 
			
		||||
#define SOFTWARE_DRIVER_2_CLIPCHECK      if( xStart < 0 || xStart + dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
 | 
			
		||||
#define SOFTWARE_DRIVER_2_CLIPCHECK_REF  if( pShader.xStart < 0 || pShader.xStart + pShader.dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
 | 
			
		||||
#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE if( aposx < 0 || aposx >= (s32)RenderTarget->getDimension().Width || aposy < 0 || aposy >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
 | 
			
		||||
 | 
			
		||||
inline float reciprocal_zero_no(const float x)
 | 
			
		||||
{
 | 
			
		||||
	if (x * x <= 0.00001f) __debugbreak();
 | 
			
		||||
	return 1.f / x;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
#define SOFTWARE_DRIVER_2_CLIPCHECK
 | 
			
		||||
#define SOFTWARE_DRIVER_2_CLIPCHECK_REF
 | 
			
		||||
#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE
 | 
			
		||||
 | 
			
		||||
#define reciprocal_zero_no(x) 1.f/x
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//!scanline renderer emulate line
 | 
			
		||||
enum edge_test_flag
 | 
			
		||||
{
 | 
			
		||||
	edge_test_pass = 1,		//! not wireframe
 | 
			
		||||
	edge_test_left = 0,
 | 
			
		||||
	edge_test_first_line = 2,
 | 
			
		||||
	edge_test_point = 4
 | 
			
		||||
};
 | 
			
		||||
//if any edge test flag is set result=1 else 0. ( pass height test for degenerate triangle )
 | 
			
		||||
#define reciprocal_edge(x) ((x) != 0.f ? 1.f / (x):(~EdgeTestPass)&1)
 | 
			
		||||
 | 
			
		||||
//! normalize from fixed point Color Max to fixed point [0;1]
 | 
			
		||||
#define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2
 | 
			
		||||
 | 
			
		||||
//! from 1 bit to 5 bit
 | 
			
		||||
#if defined(SOFTWARE_DRIVER_2_32BIT)
 | 
			
		||||
#define fix_alpha_color_max(x)
 | 
			
		||||
#else
 | 
			
		||||
#define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Check windows
 | 
			
		||||
#if _WIN32 || _WIN64
 | 
			
		||||
#if _WIN64
 | 
			
		||||
#define ENV64BIT
 | 
			
		||||
#else
 | 
			
		||||
#define ENV32BIT
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Check GCC
 | 
			
		||||
#if __GNUC__
 | 
			
		||||
#if __x86_64__ || __ppc64__
 | 
			
		||||
#define ENV64BIT
 | 
			
		||||
#else
 | 
			
		||||
#define ENV32BIT
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL)
 | 
			
		||||
typedef float ipoltype;
 | 
			
		||||
#else
 | 
			
		||||
typedef float ipoltype;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define	ipol_lower_equal_0(n)	((n) <= (ipoltype)0.0)
 | 
			
		||||
#define	ipol_greater_0(n)		((n) >  (ipoltype)0.0)
 | 
			
		||||
 | 
			
		||||
#if	(_MSC_VER > 1700 )
 | 
			
		||||
#define burning_restrict __restrict
 | 
			
		||||
#else
 | 
			
		||||
#define burning_restrict
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	if (condition) state |= mask; else state &= ~mask;
 | 
			
		||||
*/
 | 
			
		||||
static inline void burning_setbit(size_t& state, int condition, size_t mask)
 | 
			
		||||
{
 | 
			
		||||
	if (condition) state |= mask;
 | 
			
		||||
	else state &= ~mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	if (condition) state |= m; else state &= ~m;
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE void burning_setbit32(unsigned int& state, int condition, const unsigned int mask)
 | 
			
		||||
{
 | 
			
		||||
	// 0, or any positive to mask
 | 
			
		||||
	//s32 conmask = -condition >> 31;
 | 
			
		||||
	state ^= ((-condition >> 31) ^ state) & mask;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define burning_stringify(s) #s
 | 
			
		||||
#define burning_create_indirect(s) create_##s
 | 
			
		||||
#define burning_create(s) burning_create_indirect(s)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
 | 
			
		||||
#define snprintf_irr sprintf_s
 | 
			
		||||
#define EVDF_DEPTH_CLAMP 43
 | 
			
		||||
#define E_CUBE_SURFACE int
 | 
			
		||||
#define ECFN_DISABLED 0
 | 
			
		||||
 | 
			
		||||
namespace irr {
 | 
			
		||||
	namespace video {
 | 
			
		||||
 | 
			
		||||
		//! Enum for the flags of clear buffer
 | 
			
		||||
		enum E_CLEAR_BUFFER_FLAG
 | 
			
		||||
		{
 | 
			
		||||
			ECBF_NONE = 0,
 | 
			
		||||
			ECBF_COLOR = 1,
 | 
			
		||||
			ECBF_DEPTH = 2,
 | 
			
		||||
			ECBF_STENCIL = 4,
 | 
			
		||||
			ECBF_ALL = ECBF_COLOR | ECBF_DEPTH | ECBF_STENCIL
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		//! For SMaterial.ZWriteEnable
 | 
			
		||||
		enum E_ZWRITE
 | 
			
		||||
		{
 | 
			
		||||
			EZW_OFF = 0,
 | 
			
		||||
			EZW_AUTO,
 | 
			
		||||
			EZW_ON
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#endif // PATCH_SUPERTUX_8_0_1_with_1_9_0
 | 
			
		||||
 | 
			
		||||
//! Size of a static C-style array.
 | 
			
		||||
#define array_size(_arr)  ((sizeof(_arr)/sizeof(*_arr)))
 | 
			
		||||
 | 
			
		||||
//! Compiler Align
 | 
			
		||||
#if defined(_MSC_VER)
 | 
			
		||||
#if defined(ENV64BIT)
 | 
			
		||||
#define ALIGN(x) __declspec(align(x))
 | 
			
		||||
#else
 | 
			
		||||
// ALIGN(16) not working
 | 
			
		||||
#define ALIGN(x) __declspec(align(8))
 | 
			
		||||
#endif
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
#define ALIGN(x) __attribute__ ((aligned(x)))
 | 
			
		||||
#else
 | 
			
		||||
 
 | 
			
		||||
@@ -12,61 +12,12 @@
 | 
			
		||||
 | 
			
		||||
#include "SoftwareDriver2_compile_config.h"
 | 
			
		||||
#include "irrMath.h"
 | 
			
		||||
#include "irrMathFastCompat.h"
 | 
			
		||||
#include "CSoftwareTexture2.h"
 | 
			
		||||
#include "SMaterial.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// supporting different packed pixel needs many defines...
 | 
			
		||||
 | 
			
		||||
#if defined(SOFTWARE_DRIVER_2_32BIT)
 | 
			
		||||
	typedef u32	tVideoSample;
 | 
			
		||||
	typedef u32	tStencilSample;
 | 
			
		||||
 | 
			
		||||
	#define	MASK_A	0xFF000000
 | 
			
		||||
	#define	MASK_R	0x00FF0000
 | 
			
		||||
	#define	MASK_G	0x0000FF00
 | 
			
		||||
	#define	MASK_B	0x000000FF
 | 
			
		||||
 | 
			
		||||
	#define	SHIFT_A	(unsigned)24
 | 
			
		||||
	#define	SHIFT_R	(unsigned)16
 | 
			
		||||
	#define	SHIFT_G	(unsigned)8
 | 
			
		||||
	#define	SHIFT_B	(unsigned)0
 | 
			
		||||
 | 
			
		||||
	#define	COLOR_MAX					0xFF
 | 
			
		||||
	#define	COLOR_MAX_LOG2				8
 | 
			
		||||
	#define	COLOR_BRIGHT_WHITE			0xFFFFFFFF
 | 
			
		||||
 | 
			
		||||
	#define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY	(unsigned)2
 | 
			
		||||
	#define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY	(unsigned)2
 | 
			
		||||
#else
 | 
			
		||||
	typedef u16	tVideoSample;
 | 
			
		||||
	typedef u8	tStencilSample;
 | 
			
		||||
 | 
			
		||||
	#define	MASK_A	0x8000
 | 
			
		||||
	#define	MASK_R	0x7C00
 | 
			
		||||
	#define	MASK_G	0x03E0
 | 
			
		||||
	#define	MASK_B	0x001F
 | 
			
		||||
 | 
			
		||||
	#define	SHIFT_A	(unsigned)15
 | 
			
		||||
	#define	SHIFT_R	(unsigned)10
 | 
			
		||||
	#define	SHIFT_G	(unsigned)5
 | 
			
		||||
	#define	SHIFT_B	(unsigned)0
 | 
			
		||||
 | 
			
		||||
	#define	COLOR_MAX					0x1F
 | 
			
		||||
	#define	COLOR_MAX_LOG2				5
 | 
			
		||||
	#define	COLOR_BRIGHT_WHITE			0xFFFF
 | 
			
		||||
	#define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY	(unsigned)1
 | 
			
		||||
	#define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY	(unsigned)1
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ----------------------- Generic ----------------------------------
 | 
			
		||||
//! align_next - align to next upper 2^n
 | 
			
		||||
#define align_next(num,to) (((num) + (to-1)) & (~(to-1)))
 | 
			
		||||
@@ -141,50 +92,6 @@ inline void memset16(void * dest, const u16 value, size_t bytesize)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//! memset interleaved
 | 
			
		||||
inline void memset32_interlaced(void* dest, const u32 value, size_t pitch,u32 height,const interlaced_control Interlaced)
 | 
			
		||||
{
 | 
			
		||||
	if (Interlaced.bypass) return memset32(dest, value, pitch * height);
 | 
			
		||||
 | 
			
		||||
	u8* dst = (u8*)dest;
 | 
			
		||||
	interlace_scanline_data line;
 | 
			
		||||
	for (line.y = 0; line.y < height; line.y += SOFTWARE_DRIVER_2_STEP_Y)
 | 
			
		||||
	{
 | 
			
		||||
		interlace_scanline_enabled memset32(dst, value, pitch);
 | 
			
		||||
		dst += pitch;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// byte-align structures
 | 
			
		||||
#include "irrpack.h"
 | 
			
		||||
 | 
			
		||||
//IEEE Standard for Floating - Point Arithmetic(IEEE 754)
 | 
			
		||||
typedef union {
 | 
			
		||||
	float f;
 | 
			
		||||
	unsigned int u;
 | 
			
		||||
	struct { unsigned int frac:23; unsigned exp:8; unsigned int sign:1; } fields;
 | 
			
		||||
	struct { unsigned int frac_exp:31; } abs;
 | 
			
		||||
} PACK_STRUCT ieee754;
 | 
			
		||||
 | 
			
		||||
// Default alignment
 | 
			
		||||
#include "irrunpack.h"
 | 
			
		||||
 | 
			
		||||
// 0.5f as integer
 | 
			
		||||
#define ieee754_zero_dot_5	0x3f000000
 | 
			
		||||
#define ieee754_one			0x3f800000
 | 
			
		||||
#define ieee754_two			0x40000000
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
// integer log2 of a float ieee 754. [not used anymore]
 | 
			
		||||
static inline s32 s32_log2_f32( f32 f)
 | 
			
		||||
{
 | 
			
		||||
	//u32 x = IR ( f ); return ((x & 0x7F800000) >> 23) - 127;
 | 
			
		||||
	ieee754 _log2;
 | 
			
		||||
	_log2.f = f;
 | 
			
		||||
	return _log2.fields.exp ? _log2.fields.exp - 127 : 10000000; /*denormal very high number*/
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// integer log2 of an integer. returning 0 as denormal
 | 
			
		||||
static inline s32 s32_log2_s32(u32 in)
 | 
			
		||||
{
 | 
			
		||||
@@ -195,25 +102,8 @@ static inline s32 s32_log2_s32(u32 in)
 | 
			
		||||
		ret++;
 | 
			
		||||
	}
 | 
			
		||||
	return ret;
 | 
			
		||||
	//return s32_log2_f32( (f32) x);
 | 
			
		||||
	//ieee754 _log2;_log2.f = (f32) in; return _log2.fields.exp - 127;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
static inline s32 s32_abs(s32 x)
 | 
			
		||||
{
 | 
			
		||||
	s32 b = x >> 31;
 | 
			
		||||
	return (x ^ b ) - b;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! conditional set based on mask and arithmetic shift
 | 
			
		||||
REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b )
 | 
			
		||||
{
 | 
			
		||||
	return ( mask & ( a ^ b ) ) ^ b;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// ------------------ Video---------------------------------------
 | 
			
		||||
/*!
 | 
			
		||||
	Pixel = dest * ( 1 - alpha ) + source * alpha
 | 
			
		||||
@@ -331,53 +221,12 @@ REALINLINE u32 PixelAdd32 ( const u32 c2, const u32 c1)
 | 
			
		||||
	return modulo | clamp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
 | 
			
		||||
// 1 - Bit Alpha Blending
 | 
			
		||||
inline u16 PixelBlend16 ( const u16 destination, const u16 source )
 | 
			
		||||
{
 | 
			
		||||
	if((source & 0x8000) == 0x8000)
 | 
			
		||||
		return source; // The source is visible, so use it.
 | 
			
		||||
	else
 | 
			
		||||
		return destination; // The source is transparent, so use the destination.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 1 - Bit Alpha Blending 16Bit SIMD
 | 
			
		||||
inline u32 PixelBlend16_simd ( const u32 destination, const u32 source )
 | 
			
		||||
{
 | 
			
		||||
	switch(source & 0x80008000)
 | 
			
		||||
	{
 | 
			
		||||
		case 0x80008000: // Both source pixels are visible
 | 
			
		||||
			return source;
 | 
			
		||||
 | 
			
		||||
		case 0x80000000: // Only the first source pixel is visible
 | 
			
		||||
			return (source & 0xFFFF0000) | (destination & 0x0000FFFF);
 | 
			
		||||
 | 
			
		||||
		case 0x00008000: // Only the second source pixel is visible.
 | 
			
		||||
			return (destination & 0xFFFF0000) | (source & 0x0000FFFF);
 | 
			
		||||
 | 
			
		||||
		default: // Neither source pixel is visible.
 | 
			
		||||
			return destination;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// 1 - Bit Alpha Blending
 | 
			
		||||
inline u16 PixelBlend16 ( const u16 c2, const u16 c1 )
 | 
			
		||||
{
 | 
			
		||||
	u16 mask = ((c1 & 0x8000) >> 15 ) + 0x7fff;
 | 
			
		||||
	return (c2 & mask ) | ( c1 & ~mask );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 1 - Bit Alpha Blending 16Bit SIMD
 | 
			
		||||
inline u32 PixelBlend16_simd ( const u32 c2, const u32 c1 )
 | 
			
		||||
{
 | 
			
		||||
	u32 mask = ((c1 & 0x80008000) >> 15 ) + 0x7fff7fff;
 | 
			
		||||
	return (c2 & mask ) | ( c1 & ~mask );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	Pixel = dest * ( 1 - SourceAlpha ) + source * SourceAlpha (OpenGL blending)
 | 
			
		||||
*/
 | 
			
		||||
@@ -423,762 +272,6 @@ inline u32 PixelBlend32 ( const u32 c2, const u32 c1 )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ------------------ Fix Point ----------------------------------
 | 
			
		||||
 | 
			
		||||
#if defined(ENV64BIT)
 | 
			
		||||
typedef s32 tFixPoint;
 | 
			
		||||
typedef u32 tFixPointu;
 | 
			
		||||
#else
 | 
			
		||||
typedef s32 tFixPoint;
 | 
			
		||||
typedef u32 tFixPointu;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Fix Point 12 (overflow on s32)
 | 
			
		||||
#if 0
 | 
			
		||||
	#define FIX_POINT_PRE			12
 | 
			
		||||
	#define FIX_POINT_FRACT_MASK	0xFFF
 | 
			
		||||
	#define FIX_POINT_UNSIGNED_MASK	0x7FFFF000
 | 
			
		||||
	#define FIX_POINT_ONE			0x1000
 | 
			
		||||
	#define FIX_POINT_ZERO_DOT_FIVE	0x0800
 | 
			
		||||
	#define FIX_POINT_F32_MUL		4096.f
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Fix Point 11 (overflow on s32)
 | 
			
		||||
#if 0
 | 
			
		||||
	#define FIX_POINT_PRE			11
 | 
			
		||||
	#define FIX_POINT_FRACT_MASK	0x7FF
 | 
			
		||||
	#define FIX_POINT_UNSIGNED_MASK	0xFFFFF800
 | 
			
		||||
	#define FIX_POINT_ONE			0x800
 | 
			
		||||
	#define FIX_POINT_ZERO_DOT_FIVE	0x400
 | 
			
		||||
	#define FIX_POINT_F32_MUL		2048.f
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Fix Point 10
 | 
			
		||||
#if 1
 | 
			
		||||
	#define FIX_POINT_PRE			10
 | 
			
		||||
	#define FIX_POINT_FRACT_MASK	0x000003FF
 | 
			
		||||
	#define FIX_POINT_UNSIGNED_MASK	0x7FFFFE00
 | 
			
		||||
	#define FIX_POINT_ONE			0x00000400
 | 
			
		||||
	#define FIX_POINT_ZERO_DOT_FIVE	0x00000200
 | 
			
		||||
	#define FIX_POINT_F32_MUL		1024.f
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Fix Point 9
 | 
			
		||||
#if 0
 | 
			
		||||
	#define FIX_POINT_PRE			9
 | 
			
		||||
	#define FIX_POINT_FRACT_MASK	0x1FF
 | 
			
		||||
	#define FIX_POINT_UNSIGNED_MASK	0x7FFFFE00
 | 
			
		||||
	#define FIX_POINT_ONE			0x200
 | 
			
		||||
	#define FIX_POINT_ZERO_DOT_FIVE	0x100
 | 
			
		||||
	#define FIX_POINT_F32_MUL		512.f
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// Fix Point 7
 | 
			
		||||
#if 0
 | 
			
		||||
	#define FIX_POINT_PRE			7
 | 
			
		||||
	#define FIX_POINT_FRACT_MASK	0x7F
 | 
			
		||||
	#define FIX_POINT_UNSIGNED_MASK	0x7FFFFF80
 | 
			
		||||
	#define FIX_POINT_ONE			0x80
 | 
			
		||||
	#define FIX_POINT_ZERO_DOT_FIVE	0x40
 | 
			
		||||
	#define FIX_POINT_F32_MUL		128.f
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define	FIXPOINT_COLOR_MAX		( COLOR_MAX << FIX_POINT_PRE )
 | 
			
		||||
 | 
			
		||||
#if   FIX_POINT_PRE == 10 && COLOR_MAX == 255
 | 
			
		||||
	#define FIX_POINT_HALF_COLOR	0x1FE00
 | 
			
		||||
	#define FIX_POINT_COLOR_ERROR	4
 | 
			
		||||
#elif FIX_POINT_PRE == 12 && COLOR_MAX == 255
 | 
			
		||||
	#define FIX_POINT_HALF_COLOR	0x7F800
 | 
			
		||||
	#define FIX_POINT_COLOR_ERROR	16
 | 
			
		||||
#elif FIX_POINT_PRE == 10 && COLOR_MAX == 31
 | 
			
		||||
	#define FIX_POINT_HALF_COLOR	0x3E00
 | 
			
		||||
	#define FIX_POINT_COLOR_ERROR	32
 | 
			
		||||
#else
 | 
			
		||||
	#define FIX_POINT_HALF_COLOR	( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )
 | 
			
		||||
	#define FIX_POINT_COLOR_ERROR	(1<<(FIX_POINT_PRE-COLOR_MAX_LOG2))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	convert signed integer to fixpoint
 | 
			
		||||
*/
 | 
			
		||||
inline tFixPoint s32_to_fixPoint (const s32 x)
 | 
			
		||||
{
 | 
			
		||||
	return x << FIX_POINT_PRE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
inline tFixPointu u32_to_fixPoint (const u32 x)
 | 
			
		||||
{
 | 
			
		||||
	return x << FIX_POINT_PRE;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
inline u32 fixPointu_to_u32 (const tFixPointu x)
 | 
			
		||||
{
 | 
			
		||||
	return (u32)(x >> FIX_POINT_PRE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 1/x * FIX_POINT
 | 
			
		||||
#define fix_inverse32(x) (FIX_POINT_F32_MUL / (x))
 | 
			
		||||
#define fix_inverse32_color(x) ((FIX_POINT_F32_MUL*COLOR_MAX) / (x))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	convert float to fixpoint
 | 
			
		||||
	fast convert (fistp on x86) HAS to be used..
 | 
			
		||||
	hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different
 | 
			
		||||
	others should use their favourite assembler..
 | 
			
		||||
*/
 | 
			
		||||
#if 0
 | 
			
		||||
static inline int f_round2(f32 f)
 | 
			
		||||
{
 | 
			
		||||
	f += (3<<22);
 | 
			
		||||
	return IR(f) - 0x4b400000;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	convert f32 to Fix Point.
 | 
			
		||||
	multiply is needed anyway, so scale mulby
 | 
			
		||||
*/
 | 
			
		||||
/*
 | 
			
		||||
REALINLINE tFixPoint tofix0 (const f32 x, const f32 mulby = FIX_POINT_F32_MUL )
 | 
			
		||||
{
 | 
			
		||||
	return (tFixPoint) (x * mulby);
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
#define tofix(x,y) (tFixPoint)(x * y)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Fix Point , Fix Point Multiply
 | 
			
		||||
*/
 | 
			
		||||
/*
 | 
			
		||||
REALINLINE tFixPointu imulFixu(const tFixPointu x, const tFixPointu y)
 | 
			
		||||
{
 | 
			
		||||
	return (x * y) >> (tFixPointu) FIX_POINT_PRE;
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
#define imulFixu(x,y) (((x) * (y)) >> (tFixPointu) FIX_POINT_PRE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Fix Point , Fix Point Multiply
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y)
 | 
			
		||||
{
 | 
			
		||||
	return (x * y) >> FIX_POINT_PRE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define imulFix_simple(x,y) ((x*y)>>FIX_POINT_PRE)
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
/*
 | 
			
		||||
	Fix Point , Fix Point Multiply x * y * 2
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y)
 | 
			
		||||
{
 | 
			
		||||
	return ( x * y) >> ( FIX_POINT_PRE -1 );
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Multiply x * y * 1 FIXPOINT_COLOR_MAX
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y)
 | 
			
		||||
{
 | 
			
		||||
#if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8
 | 
			
		||||
	return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4);
 | 
			
		||||
#else
 | 
			
		||||
	return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Multiply x * y * 2
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y)
 | 
			
		||||
{
 | 
			
		||||
	return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 3 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	Multiply x * y * 4 clamp
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)
 | 
			
		||||
{
 | 
			
		||||
#if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8
 | 
			
		||||
	tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2);
 | 
			
		||||
#else
 | 
			
		||||
	tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3);
 | 
			
		||||
#endif
 | 
			
		||||
	tFixPoint mask = (a - FIXPOINT_COLOR_MAX) >> 31;
 | 
			
		||||
	return (a & mask) | (FIXPOINT_COLOR_MAX & ~mask);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX)
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a)
 | 
			
		||||
{
 | 
			
		||||
	tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;
 | 
			
		||||
	return (a & c) | ( FIXPOINT_COLOR_MAX & ~c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	clamp FixPoint to 0 in FixPoint, max(a,0)
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE tFixPoint clampfix_mincolor ( const tFixPoint a)
 | 
			
		||||
{
 | 
			
		||||
	return a - ( a & ( a >> 31 ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
REALINLINE tFixPoint saturateFix ( const tFixPoint a)
 | 
			
		||||
{
 | 
			
		||||
	return clampfix_mincolor ( clampfix_maxcolor ( a ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
// rount fixpoint to int
 | 
			
		||||
inline s32 roundFix ( const tFixPoint x )
 | 
			
		||||
{
 | 
			
		||||
	return (s32)(( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// x in [0;1[
 | 
			
		||||
#if 0
 | 
			
		||||
inline s32 f32_to_23Bits(const f32 x)
 | 
			
		||||
{
 | 
			
		||||
	f32 y = x + 1.f;
 | 
			
		||||
	return IR(y) & 0x7FFFFF;	// last 23 bits
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	fixpoint in [0..Fixpoint_color] to VideoSample xrgb
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE tVideoSample fix_to_sample ( const tFixPoint r, const tFixPoint g, const tFixPoint b )
 | 
			
		||||
{
 | 
			
		||||
	return	( FIXPOINT_COLOR_MAX & FIXPOINT_COLOR_MAX) << ( SHIFT_A - FIX_POINT_PRE ) |
 | 
			
		||||
			( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |
 | 
			
		||||
			( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) |
 | 
			
		||||
			( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	fixpoint to VideoSample argb
 | 
			
		||||
	a in [0;1]
 | 
			
		||||
	rgb in [0;255] colormax
 | 
			
		||||
*/
 | 
			
		||||
REALINLINE tVideoSample fix4_to_sample ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )
 | 
			
		||||
{
 | 
			
		||||
	return	( a & (FIX_POINT_FRACT_MASK - 1 )) << ( SHIFT_A - 1 ) |
 | 
			
		||||
			( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |
 | 
			
		||||
			( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) |
 | 
			
		||||
			( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX
 | 
			
		||||
*/
 | 
			
		||||
inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
 | 
			
		||||
{
 | 
			
		||||
	(tFixPointu&) r =	(t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE );
 | 
			
		||||
	(tFixPointu&) g =	(t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
 | 
			
		||||
	(tFixPointu&) b =	(t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX
 | 
			
		||||
*/
 | 
			
		||||
inline void color_to_fix ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
 | 
			
		||||
{
 | 
			
		||||
	(tFixPointu&) a =	(t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE );
 | 
			
		||||
	(tFixPointu&) r =	(t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE );
 | 
			
		||||
	(tFixPointu&) g =	(t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
 | 
			
		||||
	(tFixPointu&) b =	(t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	return fixpoint from VideoSample granularity 0..FIX_POINT_ONE
 | 
			
		||||
*/
 | 
			
		||||
inline void color_to_fix1 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
 | 
			
		||||
{
 | 
			
		||||
	(tFixPointu&) r =	(t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );
 | 
			
		||||
	(tFixPointu&) g =	(t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );
 | 
			
		||||
	(tFixPointu&) b =	(t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );
 | 
			
		||||
 | 
			
		||||
	//0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0
 | 
			
		||||
	r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
	g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
	b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	return fixpoint from VideoSample granularity 0..FIX_POINT_ONE
 | 
			
		||||
*/
 | 
			
		||||
inline void color_to_fix1 ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )
 | 
			
		||||
{
 | 
			
		||||
	(tFixPointu&) a =	(t00 & MASK_A) >> ( SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE );
 | 
			
		||||
	(tFixPointu&) r =	(t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );
 | 
			
		||||
	(tFixPointu&) g =	(t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );
 | 
			
		||||
	(tFixPointu&) b =	(t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );
 | 
			
		||||
 | 
			
		||||
	//0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0
 | 
			
		||||
	a += (a & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
	r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
	g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
	b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX
 | 
			
		||||
*/
 | 
			
		||||
inline void color_to_fix(tFixPoint c[4], const tVideoSample t00)
 | 
			
		||||
{
 | 
			
		||||
	c[0] = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);
 | 
			
		||||
	c[1] = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
 | 
			
		||||
	c[2] = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
 | 
			
		||||
	c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*!
 | 
			
		||||
	return fixpoint from VideoSample granularity 0..FIX_POINT_ONE
 | 
			
		||||
*/
 | 
			
		||||
inline void color_to_fix1(tFixPoint c[4], const tVideoSample t00)
 | 
			
		||||
{
 | 
			
		||||
	c[0] = (t00 & MASK_A) >> (SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE);
 | 
			
		||||
	c[1] = (t00 & MASK_R) >> (SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE);
 | 
			
		||||
	c[2] = (t00 & MASK_G) >> (SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE);
 | 
			
		||||
	c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - COLOR_MAX_LOG2);
 | 
			
		||||
 | 
			
		||||
	//0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0
 | 
			
		||||
	c[0] += (c[0] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
	c[1] += (c[1] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
	c[2] += (c[2] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
	c[3] += (c[3] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//! ----- FP24 1.23 fix point z-buffer
 | 
			
		||||
 | 
			
		||||
#if 1
 | 
			
		||||
typedef f32 fp24;
 | 
			
		||||
#else
 | 
			
		||||
struct fp24
 | 
			
		||||
{
 | 
			
		||||
	u32 v;
 | 
			
		||||
 | 
			
		||||
	fp24() {}
 | 
			
		||||
 | 
			
		||||
	fp24 ( const f32 f )
 | 
			
		||||
	{
 | 
			
		||||
		f32 y = f + 1.f;
 | 
			
		||||
		v = ((u32&)y) & 0x7FFFFF;	// last 23 bits
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void operator=(const f32 f )
 | 
			
		||||
	{
 | 
			
		||||
	f32 y = f + 1.f;
 | 
			
		||||
		v = ((u32&)y) & 0x7FFFFF;	// last 23 bits
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	void operator+=(const fp24 &other )
 | 
			
		||||
	{
 | 
			
		||||
		v += other.v;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	operator f32 () const
 | 
			
		||||
	{
 | 
			
		||||
		f32 r = FR ( v );
 | 
			
		||||
		return r + 1.f;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// ------------------------ Internal Texture -----------------------------
 | 
			
		||||
 | 
			
		||||
struct sInternalTexture
 | 
			
		||||
{
 | 
			
		||||
	//power-of-two
 | 
			
		||||
	void* data; //tVideoSample* Texture->lock(miplevel)
 | 
			
		||||
	size_t textureXMask;
 | 
			
		||||
	size_t textureYMask;
 | 
			
		||||
 | 
			
		||||
	size_t pitchlog2;
 | 
			
		||||
 | 
			
		||||
	video::CSoftwareTexture2 *Texture;
 | 
			
		||||
	s32 lodFactor; // magnify/minify
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// get video sample plain
 | 
			
		||||
static inline tVideoSample getTexel_plain ( const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty )
 | 
			
		||||
{
 | 
			
		||||
	size_t ofs;
 | 
			
		||||
 | 
			
		||||
	ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
 | 
			
		||||
	ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
 | 
			
		||||
 | 
			
		||||
	// texel
 | 
			
		||||
	return *((tVideoSample*)( (u8*) t->data + ofs ));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get video sample to fix
 | 
			
		||||
inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
 | 
			
		||||
						const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty
 | 
			
		||||
								)
 | 
			
		||||
{
 | 
			
		||||
	size_t ofs;
 | 
			
		||||
 | 
			
		||||
	ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
 | 
			
		||||
	ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
 | 
			
		||||
 | 
			
		||||
	// texel
 | 
			
		||||
	tVideoSample t00;
 | 
			
		||||
	t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
 | 
			
		||||
 | 
			
		||||
	r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);
 | 
			
		||||
	g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );
 | 
			
		||||
	b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get video sample to fixpoint colormax
 | 
			
		||||
inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
 | 
			
		||||
	const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	size_t ofs;
 | 
			
		||||
 | 
			
		||||
	ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
 | 
			
		||||
	ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
 | 
			
		||||
	// texel
 | 
			
		||||
	tVideoSample t00;
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)t->data + ofs));
 | 
			
		||||
 | 
			
		||||
	a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);
 | 
			
		||||
	r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
 | 
			
		||||
	g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
 | 
			
		||||
	b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
// get video sample to fixpoint
 | 
			
		||||
static REALINLINE void getTexel_fix ( tFixPoint &a,
 | 
			
		||||
			const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty)
 | 
			
		||||
{
 | 
			
		||||
	size_t ofs;
 | 
			
		||||
 | 
			
		||||
	ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
 | 
			
		||||
	ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
 | 
			
		||||
 | 
			
		||||
	// texel
 | 
			
		||||
	tVideoSample t00;
 | 
			
		||||
	t00 = *((tVideoSample*)( (u8*) t->data + ofs ));
 | 
			
		||||
 | 
			
		||||
	a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
	load a sample from internal texture at position tx,ty to fixpoint
 | 
			
		||||
*/
 | 
			
		||||
#if defined(SOFTWARE_DRIVER_2_BILINEAR)
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
// texture2D in fixpoint color range bilinear
 | 
			
		||||
static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,
 | 
			
		||||
	const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#if 0
 | 
			
		||||
	if (t->lodFactor > 0)
 | 
			
		||||
	{
 | 
			
		||||
		size_t ofs;
 | 
			
		||||
 | 
			
		||||
		ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
 | 
			
		||||
		ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
 | 
			
		||||
		// texel
 | 
			
		||||
		tVideoSample t00;
 | 
			
		||||
		t00 = *((tVideoSample*)((u8*)t->data + ofs));
 | 
			
		||||
 | 
			
		||||
		r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
 | 
			
		||||
		g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
 | 
			
		||||
		b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	tFixPointu r00, g00, b00;
 | 
			
		||||
	tFixPointu r01, g01, b01;
 | 
			
		||||
	tFixPointu r10, g10, b10;
 | 
			
		||||
	tFixPointu r11, g11, b11;
 | 
			
		||||
 | 
			
		||||
	size_t o0, o1, o2, o3;
 | 
			
		||||
	tVideoSample t00;
 | 
			
		||||
 | 
			
		||||
	//wraps positive (ignoring negative)
 | 
			
		||||
	o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
 | 
			
		||||
	o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
 | 
			
		||||
	o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
	o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2)));
 | 
			
		||||
	r00 = (t00 & MASK_R) >> SHIFT_R;
 | 
			
		||||
	g00 = (t00 & MASK_G) >> SHIFT_G;
 | 
			
		||||
	b00 = (t00 & MASK_B);
 | 
			
		||||
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)t->data + (o0 + o3)));
 | 
			
		||||
	r10 = (t00 & MASK_R) >> SHIFT_R;
 | 
			
		||||
	g10 = (t00 & MASK_G) >> SHIFT_G;
 | 
			
		||||
	b10 = (t00 & MASK_B);
 | 
			
		||||
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)t->data + (o1 + o2)));
 | 
			
		||||
	r01 = (t00 & MASK_R) >> SHIFT_R;
 | 
			
		||||
	g01 = (t00 & MASK_G) >> SHIFT_G;
 | 
			
		||||
	b01 = (t00 & MASK_B);
 | 
			
		||||
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)t->data + (o1 + o3)));
 | 
			
		||||
	r11 = (t00 & MASK_R) >> SHIFT_R;
 | 
			
		||||
	g11 = (t00 & MASK_G) >> SHIFT_G;
 | 
			
		||||
	b11 = (t00 & MASK_B);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;
 | 
			
		||||
	tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;
 | 
			
		||||
 | 
			
		||||
	//w00 w01 w10 w11
 | 
			
		||||
	tFixPointu w[4];
 | 
			
		||||
	w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);
 | 
			
		||||
	w[1] = imulFixu(FIX_POINT_ONE - fracx, fracy);
 | 
			
		||||
	w[2] = imulFixu(fracx, FIX_POINT_ONE - fracy);
 | 
			
		||||
	w[3] = imulFixu(fracx, fracy);
 | 
			
		||||
 | 
			
		||||
	r = (r00 * w[0]) +
 | 
			
		||||
		(r01 * w[1]) +
 | 
			
		||||
		(r10 * w[2]) +
 | 
			
		||||
		(r11 * w[3]);
 | 
			
		||||
 | 
			
		||||
	g = (g00 * w[0]) +
 | 
			
		||||
		(g01 * w[1]) +
 | 
			
		||||
		(g10 * w[2]) +
 | 
			
		||||
		(g11 * w[3]);
 | 
			
		||||
 | 
			
		||||
	b = (b00 * w[0]) +
 | 
			
		||||
		(b01 * w[1]) +
 | 
			
		||||
		(b10 * w[2]) +
 | 
			
		||||
		(b11 * w[3]);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
// texture2D in fixpoint color range bilinear
 | 
			
		||||
static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,
 | 
			
		||||
	const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
#if 0
 | 
			
		||||
	if (tex->lodFactor > 1)
 | 
			
		||||
	{
 | 
			
		||||
		//nearest neighbor
 | 
			
		||||
		size_t ofs;
 | 
			
		||||
		ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
 | 
			
		||||
		ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
 | 
			
		||||
		tVideoSample t00;
 | 
			
		||||
		t00 = *((tVideoSample*)((u8*)tex->data + ofs));
 | 
			
		||||
 | 
			
		||||
		r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
 | 
			
		||||
		g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
 | 
			
		||||
		b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	//w00 w01 w10 w11
 | 
			
		||||
	tFixPointu w[4];
 | 
			
		||||
	{
 | 
			
		||||
		tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;
 | 
			
		||||
		tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;
 | 
			
		||||
		w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);
 | 
			
		||||
		w[1] = imulFixu(fracx, FIX_POINT_ONE - fracy);
 | 
			
		||||
		w[2] = imulFixu(FIX_POINT_ONE - fracx, fracy);
 | 
			
		||||
		w[3] = imulFixu(fracx, fracy);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	//wraps positive (ignoring negative)
 | 
			
		||||
	tVideoSample t[4];
 | 
			
		||||
	{
 | 
			
		||||
		size_t o0, o1, o2, o3;
 | 
			
		||||
		o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
 | 
			
		||||
		o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
 | 
			
		||||
		o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
		o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
 | 
			
		||||
		t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));
 | 
			
		||||
		t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));
 | 
			
		||||
		t[2] = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));
 | 
			
		||||
		t[3] = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	r = (((t[0] & MASK_R) >> SHIFT_R) * w[0]) +
 | 
			
		||||
		(((t[1] & MASK_R) >> SHIFT_R) * w[1]) +
 | 
			
		||||
		(((t[2] & MASK_R) >> SHIFT_R) * w[2]) +
 | 
			
		||||
		(((t[3] & MASK_R) >> SHIFT_R) * w[3]);
 | 
			
		||||
 | 
			
		||||
	g = (((t[0] & MASK_G) >> SHIFT_G) * w[0]) +
 | 
			
		||||
		(((t[1] & MASK_G) >> SHIFT_G) * w[1]) +
 | 
			
		||||
		(((t[2] & MASK_G) >> SHIFT_G) * w[2]) +
 | 
			
		||||
		(((t[3] & MASK_G) >> SHIFT_G) * w[3]);
 | 
			
		||||
 | 
			
		||||
	b = ((t[0] & MASK_B) * w[0]) +
 | 
			
		||||
		((t[1] & MASK_B) * w[1]) +
 | 
			
		||||
		((t[2] & MASK_B) * w[2]) +
 | 
			
		||||
		((t[3] & MASK_B) * w[3]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// get Sample bilinear
 | 
			
		||||
static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
 | 
			
		||||
	const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	tFixPointu a00, r00, g00, b00;
 | 
			
		||||
	tFixPointu a01, r01, g01, b01;
 | 
			
		||||
	tFixPointu a10, r10, g10, b10;
 | 
			
		||||
	tFixPointu a11, r11, g11, b11;
 | 
			
		||||
 | 
			
		||||
	size_t o0, o1, o2, o3;
 | 
			
		||||
	tVideoSample t00;
 | 
			
		||||
 | 
			
		||||
	o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
 | 
			
		||||
	o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
 | 
			
		||||
	o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
	o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));
 | 
			
		||||
	a00 = (t00 & MASK_A) >> SHIFT_A;
 | 
			
		||||
	r00 = (t00 & MASK_R) >> SHIFT_R;
 | 
			
		||||
	g00 = (t00 & MASK_G) >> SHIFT_G;
 | 
			
		||||
	b00 = (t00 & MASK_B);
 | 
			
		||||
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));
 | 
			
		||||
	a10 = (t00 & MASK_A) >> SHIFT_A;
 | 
			
		||||
	r10 = (t00 & MASK_R) >> SHIFT_R;
 | 
			
		||||
	g10 = (t00 & MASK_G) >> SHIFT_G;
 | 
			
		||||
	b10 = (t00 & MASK_B);
 | 
			
		||||
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));
 | 
			
		||||
	a01 = (t00 & MASK_A) >> SHIFT_A;
 | 
			
		||||
	r01 = (t00 & MASK_R) >> SHIFT_R;
 | 
			
		||||
	g01 = (t00 & MASK_G) >> SHIFT_G;
 | 
			
		||||
	b01 = (t00 & MASK_B);
 | 
			
		||||
 | 
			
		||||
	t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));
 | 
			
		||||
	a11 = (t00 & MASK_A) >> SHIFT_A;
 | 
			
		||||
	r11 = (t00 & MASK_R) >> SHIFT_R;
 | 
			
		||||
	g11 = (t00 & MASK_G) >> SHIFT_G;
 | 
			
		||||
	b11 = (t00 & MASK_B);
 | 
			
		||||
 | 
			
		||||
	const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;
 | 
			
		||||
	const tFixPointu txFractInv = FIX_POINT_ONE - txFract;
 | 
			
		||||
 | 
			
		||||
	const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;
 | 
			
		||||
	const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;
 | 
			
		||||
 | 
			
		||||
	const tFixPointu w00 = imulFixu(txFractInv, tyFractInv);
 | 
			
		||||
	const tFixPointu w10 = imulFixu(txFract, tyFractInv);
 | 
			
		||||
	const tFixPointu w01 = imulFixu(txFractInv, tyFract);
 | 
			
		||||
	const tFixPointu w11 = imulFixu(txFract, tyFract);
 | 
			
		||||
 | 
			
		||||
	a = (a00 * w00) +
 | 
			
		||||
		(a01 * w01) +
 | 
			
		||||
		(a10 * w10) +
 | 
			
		||||
		(a11 * w11);
 | 
			
		||||
 | 
			
		||||
	fix_alpha_color_max(a);
 | 
			
		||||
 | 
			
		||||
	r = (r00 * w00) +
 | 
			
		||||
		(r01 * w01) +
 | 
			
		||||
		(r10 * w10) +
 | 
			
		||||
		(r11 * w11);
 | 
			
		||||
 | 
			
		||||
	g = (g00 * w00) +
 | 
			
		||||
		(g01 * w01) +
 | 
			
		||||
		(g10 * w10) +
 | 
			
		||||
		(g11 * w11);
 | 
			
		||||
 | 
			
		||||
	b = (b00 * w00) +
 | 
			
		||||
		(b01 * w01) +
 | 
			
		||||
		(b10 * w10) +
 | 
			
		||||
		(b11 * w11);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else // SOFTWARE_DRIVER_2_BILINEAR
 | 
			
		||||
 | 
			
		||||
// get Sample linear == getSample_fixpoint
 | 
			
		||||
 | 
			
		||||
static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,
 | 
			
		||||
	const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	size_t ofs;
 | 
			
		||||
	ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
 | 
			
		||||
	ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
 | 
			
		||||
	// texel
 | 
			
		||||
	const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));
 | 
			
		||||
 | 
			
		||||
	(tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
 | 
			
		||||
	(tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
 | 
			
		||||
	(tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
 | 
			
		||||
	const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
	size_t ofs;
 | 
			
		||||
	ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
 | 
			
		||||
	ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
 | 
			
		||||
 | 
			
		||||
	// texel
 | 
			
		||||
	const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));
 | 
			
		||||
 | 
			
		||||
	(tFixPointu &)a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);
 | 
			
		||||
	fix_alpha_color_max(a);
 | 
			
		||||
	(tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);
 | 
			
		||||
	(tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);
 | 
			
		||||
	(tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // SOFTWARE_DRIVER_2_BILINEAR
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 2D Region closed [x0;x1]
 | 
			
		||||
struct AbsRectangle
 | 
			
		||||
{
 | 
			
		||||
@@ -1198,45 +291,6 @@ inline bool intersect ( AbsRectangle &dest, const AbsRectangle& a, const AbsRect
 | 
			
		||||
	return dest.x0 < dest.x1 && dest.y0 < dest.y1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
// some 1D defines
 | 
			
		||||
struct sIntervall
 | 
			
		||||
{
 | 
			
		||||
	s32 start;
 | 
			
		||||
	s32 end;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// returning intersection width
 | 
			
		||||
inline s32 intervall_intersect_test( const sIntervall& a, const sIntervall& b)
 | 
			
		||||
{
 | 
			
		||||
	return core::s32_min( a.end, b.end ) - core::s32_max( a.start, b.start );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// strings
 | 
			
		||||
static inline void tiny_strncpy(char* to, const char* from, const size_t count)
 | 
			
		||||
{
 | 
			
		||||
	for (size_t r = 0; r < count && (*to = *from) != '\0'; ++from, ++to, ++r);
 | 
			
		||||
	*to = '\0';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define tiny_strcpy(a, b) tiny_strncpy(a,b,sizeof(a)-1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// tiny_isequal = !strncmp(a,b,sizeof(a)-1)
 | 
			
		||||
static inline int tiny_isequal(const char *s1, const char *s2, size_t n)
 | 
			
		||||
{
 | 
			
		||||
	do {
 | 
			
		||||
		if (*s1 != *s2++) return 0;
 | 
			
		||||
		if (*s1++ == 0)
 | 
			
		||||
			break;
 | 
			
		||||
	} while (--n != 0);
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // end namespace irr
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
// This file is part of the "Irrlicht Engine".
 | 
			
		||||
// For conditions of distribution and use, see copyright notice in irrlicht.h
 | 
			
		||||
 | 
			
		||||
#ifndef __IRR_FAST_MATH_COMPAT_H_INCLUDED__
 | 
			
		||||
#define __IRR_FAST_MATH_COMPAT_H_INCLUDED__
 | 
			
		||||
 | 
			
		||||
#include "irrMath.h"
 | 
			
		||||
 | 
			
		||||
namespace irr
 | 
			
		||||
{
 | 
			
		||||
namespace core
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// IRRLICHT_FAST_MATH functions which I wanted to kick out because they return
 | 
			
		||||
// wrong results. But last time I proposed that I've been asked to keep them for 
 | 
			
		||||
// Burnings software renderer. So to avoid changing that accidentally or messing up
 | 
			
		||||
// it's speed I'll keep them around, but only as internal header.
 | 
			
		||||
// They should not be used otherwise any longer.
 | 
			
		||||
 | 
			
		||||
	// Some examples for unexpected results when using this with IRRLICHT_FAST_MATH:
 | 
			
		||||
	// Input 1, expected 1, got 0
 | 
			
		||||
	// Input 3, expected 3, got 2
 | 
			
		||||
	// Input -1.40129846e-45, expected -1, got 0
 | 
			
		||||
	REALINLINE s32 floor32_fast(f32 x)
 | 
			
		||||
	{
 | 
			
		||||
		return (s32) floorf ( x );
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	// Some examples for unexpected results when using this with IRRLICHT_FAST_MATH:
 | 
			
		||||
	// Input 1.40129846e-45, expected 1, got 0
 | 
			
		||||
	// Input -1, expected -1, got 0
 | 
			
		||||
	// Input -3, expected -3, got -2
 | 
			
		||||
	REALINLINE s32 ceil32_fast ( f32 x )
 | 
			
		||||
	{
 | 
			
		||||
		return (s32) ceilf ( x );
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	// Some examples for unexpected results when using this with IRRLICHT_FAST_MATH:
 | 
			
		||||
	// Input 0.5, expected 1, got 0
 | 
			
		||||
	// Input 2.5, expected 3, got 2
 | 
			
		||||
	// Input -1.40129846e-45, expected -nan(ind), got -inf
 | 
			
		||||
	// Input -2.80259693e-45, expected -nan(ind), got -inf	
 | 
			
		||||
	REALINLINE s32 round32_fast(f32 x)
 | 
			
		||||
	{
 | 
			
		||||
		return (s32) round_(x);
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
} // end namespace core
 | 
			
		||||
} // end namespace irr	
 | 
			
		||||
 | 
			
		||||
#endif // __IRR_FAST_MATH_COMPAT_H_INCLUDED__
 | 
			
		||||
		Reference in New Issue
	
	Block a user