www.pudn.com > zfxcengine-0.1.0.zip > ceRenderObject_D3D9.cpp


#include  
#include  
#include "Core/ceExceptions.h" 
#include "Math/ceMath.h" 
#include "Render/RenderD3D9/ceRenderObject_D3D9.h" 
#include "Core/ceMemManager.h" 
 
using std::cout; using std::endl; 
namespace ZFXCE { 
	namespace Render { 
		//////////////////////////////////////////////////////////////////////////////////////// 
		D3DPRIMITIVETYPE GetD3DPrimType(UINT PrimType) 
		{ 
			if(PrimType == CE_RS_PRIM_POINTS) 
				return D3DPT_POINTLIST; 
			if(PrimType == CE_RS_PRIM_LINES) 
				return D3DPT_LINELIST; 
			if(PrimType == CE_RS_PRIM_LINESTRIP) 
				return D3DPT_LINESTRIP; 
			if(PrimType == CE_RS_PRIM_TRIFAN) 
				return D3DPT_TRIANGLEFAN; 
			if(PrimType == CE_RS_PRIM_TRISTRIP) 
				return D3DPT_TRIANGLESTRIP; 
        //    if(PrimType == CE_TRIANGLES) 
		//		return D3DPT_TRIANGLELIST; 
 
			return D3DPT_TRIANGLELIST; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		DWORD GetD3DFVF(UINT FVF) 
		{ 
			DWORD d3d = 0; 
			/*if(FVF & CEFVF_XYZ) 
				d3d |= D3DFVF_XYZ; 
			if(FVF & CEFVF_DIFFUSE) 
				d3d |= D3DFVF_DIFFUSE; 
			if(FVF & CEFVF_NORMAL) 
				d3d |= D3DFVF_NORMAL; 
 
			if(FVF & CEFVF_TEXCOORD0) 
				d3d |= D3DFVF_TEX1; 
			if(FVF & CEFVF_TEXCOORD1) 
				d3d |= D3DFVF_TEX2; 
			if(FVF & CEFVF_TEXCOORD2) 
				d3d |= D3DFVF_TEX3; 
			if(FVF & CEFVF_TEXCOORD3) 
				d3d |= D3DFVF_TEX4; 
*/ 
			return d3d; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		ceVertexBufferD3D9::ceVertexBufferD3D9(void):m_pD3DDevice(NULL), m_VertexBuffer(NULL), m_NumOfVertices(0), 
										m_VertexSize(0) 
		{ 
            m_pLockedData = NULL; 
            m_pColorData  = NULL; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		ceVertexBufferD3D9::ceVertexBufferD3D9(LPDIRECT3DDEVICE9 D3DDevice): 
                                                m_pD3DDevice(D3DDevice), m_VertexBuffer(NULL), 
												m_NumOfVertices(0), m_VertexSize(0) 
		{ 
            m_pLockedData = NULL; 
            m_pColorData  = NULL; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		ceVertexBufferD3D9::~ceVertexBufferD3D9() 
		{ 
            if (m_pColorData) 
                delete [] m_pColorData; 
 
			m_VertexBuffer->Release(); 
			m_VertexBuffer = NULL; 
			m_pD3DDevice = NULL; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
        void ceVertexBufferD3D9::ConvertVertexColorToARGB(BYTE* pDest, BYTE* pSrc) 
        { 
            for (unsigned int i=0; i < m_VertexDesc.getNum(); i++) 
			{ 
                if (CE_RS_VU_COLOR == (ceVertexUsage)m_VertexDesc.getVertexUsage(i)) 
                { 
                    switch (m_VertexDesc.getAttributeSize(i)) 
                    { 
			        case CE_RS_VT_SHORT4: ConvertVertexColorToARGB(pDest, pSrc, m_VertexDesc.getOffset(i), 4, ShortColorTo255); return; 
			        case CE_RS_VT_UBYTE4: ConvertVertexColorToARGB(pDest, pSrc, m_VertexDesc.getOffset(i), 4, UByteColorTo255); return; 
                    case CE_RS_VT_FLOAT3: ConvertVertexColorToARGB(pDest, pSrc, m_VertexDesc.getOffset(i), 3, FloatColorTo255); return; 
			        case CE_RS_VT_FLOAT4: ConvertVertexColorToARGB(pDest, pSrc, m_VertexDesc.getOffset(i), 4, FloatColorTo255); return; 
#ifdef _DEBUG 
				default: 
					CE_EXCEPTION(std::string(__FUNCTION__)+": Unsupported Attribute!\nPlease report to maintainer!\n", CELS_LOWERROR); 
					break; 
#endif 
                    } 
                } 
            } 
        } 
        //////////////////////////////////////////////////////////////////////////////////////// 
        void ceVertexBufferD3D9::ConvertVertexColorToRGBA(BYTE* pDest, BYTE* pSrc) 
        { 
            for (unsigned int i=0; i < m_VertexDesc.getNum(); i++) 
			{ 
                if (CE_RS_VU_COLOR == (ceVertexUsage)m_VertexDesc.getVertexUsage(i)) 
                { 
                    switch (m_VertexDesc.getAttributeSize(i)) 
                    { 
			        case CE_RS_VT_SHORT4: ConvertVertexColorToRGBA(pDest, pSrc, m_VertexDesc.getOffset(i), 4, Color255ToShort); return; 
			        case CE_RS_VT_UBYTE4: ConvertVertexColorToRGBA(pDest, pSrc, m_VertexDesc.getOffset(i), 4, Color255ToUByte); return; 
                    case CE_RS_VT_FLOAT3: ConvertVertexColorToRGBA(pDest, pSrc, m_VertexDesc.getOffset(i), 3, Color255ToFloat); return; 
			        case CE_RS_VT_FLOAT4: ConvertVertexColorToRGBA(pDest, pSrc, m_VertexDesc.getOffset(i), 4, Color255ToFloat); return; 
#ifdef _DEBUG 
				default: 
					CE_EXCEPTION(std::string(__FUNCTION__)+": Unsupported Attribute!\nPlease report to maintainer!\n", CELS_LOWERROR); 
					break; 
#endif 
                    } 
                } 
            } 
        } 
		//////////////////////////////////////////////////////////////////////////////////////// 
		void ceVertexBufferD3D9::CreateStatic(const cePrimitive Primitive, ceVertexDescription& VertexDesc,const FLOAT* pVertices, const UINT uiNumOfVertices) 
		{ 
            m_VertexDesc    = VertexDesc; 
            m_NumOfVertices = uiNumOfVertices; 
 
            // FVF brechnen 
            m_D3DFVF = CalculateFVF(VertexDesc); 
 
            // Vertexgröße berechnen 
            m_VertexSize = CalculateFVFVertexSize(VertexDesc); 
 
            // Primitivtype übernehmen 
            m_D3DPrimType = GetD3DPrimType(Primitive); 
            switch(Primitive) 
			{ 
			case CE_RS_PRIM_POINTS:  
                m_NumOfPrimitives = uiNumOfVertices;  
                break; 
 
			case CE_RS_PRIM_LINES:  
                m_NumOfPrimitives = (UINT)(uiNumOfVertices * 0.5f);  
                break; 
 
			case CE_RS_PRIM_LINESTRIP:  
                m_NumOfPrimitives = uiNumOfVertices - 1; 
                break; 
 
			case CE_RS_PRIM_TRIANGLES:  
                m_NumOfPrimitives = uiNumOfVertices / 3; 
                break; 
 
			case CE_RS_PRIM_TRISTRIP:  
                m_NumOfPrimitives = uiNumOfVertices - 2;  
                break; 
 
			case CE_RS_PRIM_TRIFAN:  
                m_NumOfPrimitives = uiNumOfVertices - 2;  
                break; 
			} 
 
            // Vertexbuffer erstellen 
            if (FAILED( m_pD3DDevice->CreateVertexBuffer(uiNumOfVertices * m_VertexSize,  
                                             D3DUSAGE_WRITEONLY, m_D3DFVF,  
											 D3DPOOL_DEFAULT, &m_VertexBuffer, NULL) )) 
				CE_EXCEPTION(std::string(__FUNCTION__)+"Konnte den VertexBuffer nicht erstellen!", CELS_ERROR); 
 
             
			void* Vertices = NULL; 
			m_VertexBuffer->Lock(0, uiNumOfVertices*m_VertexSize, (void**) &Vertices, NULL); 
 
            // wir müssen wenigstens die Farbdaten hier konvertieren, da diese als RGBA kommen,  
			// wir hir aber ARGB brauchen 
			if (m_D3DFVF & D3DFVF_DIFFUSE) 
                ConvertVertexColorToARGB((BYTE*)Vertices, (BYTE*)pVertices); 
            else 
                memcpy(Vertices, pVertices, uiNumOfVertices*m_VertexSize); 
 
			m_VertexBuffer->Unlock(); 
 
			/* 
			// wir müssen wenigstens die Farbdaten hier konvertieren, da diese als RGBA kommen,  
			// wir hir aber ARGB brauchen 
			if(FVF & CEFVF_DIFFUSE) 
			{ 
				struct DefaultVertex 
				{ 
					ceVec3f vPosition; 
					UINT Color; 
				}; 
				UCHAR* Vertices = (UCHAR*) pVertices; 
				ceColorRGBA color(1.0, 0.0, 0.0, 1.0); 
				UCHAR null = 0; 
				for(UINT v=0; v < m_NumOfVertices; v++) 
				{	 
					DefaultVertex* vertex = (DefaultVertex*) &Vertices[v*uiVertexSize]; 
 
					//vertex->Color = 0xff00ff00; = grün 
					//continue; 
					UCHAR* Colors = (UCHAR*) &vertex->Color; 
					UCHAR r=0,g=0,b=0,a=0; 
					memcpy(&r, &Colors[0], sizeof(UCHAR) ); 
					memcpy(&g, &Colors[1], sizeof(UCHAR) ); 
					memcpy(&b, &Colors[2], sizeof(UCHAR) ); 
					memcpy(&a, &Colors[3], sizeof(UCHAR) ); 
 
					// Mal die einzelnen Farben separat testen 
					memcpy(&Colors[0], &b, sizeof(UCHAR) ); 
					memcpy(&Colors[1], &g, sizeof(UCHAR) ); 
					memcpy(&Colors[2], &r, sizeof(UCHAR) ); 
					memcpy(&Colors[3], &b, sizeof(UCHAR) ); 
				} 
 
			}*/ 
		} 
		/// 
		/// 
		void ceVertexBufferD3D9::CreateDynamic(const cePrimitive Primitive,  
                                               ceVertexDescription& VertexDesc,  
                                               const FLOAT* pVertices,  
							                   const UINT uiNumOfVertices) 
		{ 
            m_VertexDesc = VertexDesc; 
            m_NumOfVertices = uiNumOfVertices; 
 
            // FVF brechnen 
            m_D3DFVF = CalculateFVF(VertexDesc); 
 
            // Vertexgröße berechnen 
            m_VertexSize = CalculateFVFVertexSize(VertexDesc); 
 
            // Primitivtype übernehmen 
            m_D3DPrimType = GetD3DPrimType(Primitive); 
            switch(Primitive) 
			{ 
			case CE_RS_PRIM_POINTS:  
                m_NumOfPrimitives = uiNumOfVertices;  
                break; 
 
			case CE_RS_PRIM_LINES:  
                m_NumOfPrimitives = (UINT)(uiNumOfVertices * 0.5f);  
                break; 
 
			case CE_RS_PRIM_LINESTRIP:  
                m_NumOfPrimitives = uiNumOfVertices - 1; 
                break; 
 
			case CE_RS_PRIM_TRIANGLES:  
                m_NumOfPrimitives = uiNumOfVertices / 3; 
                break; 
 
			case CE_RS_PRIM_TRISTRIP:  
                m_NumOfPrimitives = uiNumOfVertices - 2;  
                break; 
 
			case CE_RS_PRIM_TRIFAN:  
                m_NumOfPrimitives = uiNumOfVertices - 2;  
                break; 
			} 
 
            // Vertexbuffer erstellen 
            if (FAILED( m_pD3DDevice->CreateVertexBuffer(uiNumOfVertices * m_VertexSize,  
                                             D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, m_D3DFVF,  
											 D3DPOOL_DEFAULT, &m_VertexBuffer, NULL) )) 
				CE_EXCEPTION(std::string(__FUNCTION__)+"Konnte den VertexBuffer nicht erstellen!", CELS_ERROR); 
 
		/*	void* Vertices = NULL; 
			m_VertexBuffer->Lock(0, uiNumOfVertices*m_VertexSize, (void**) &Vertices, NULL); 
 
            // wir müssen wenigstens die Farbdaten hier konvertieren, da diese als RGBA kommen,  
			// wir hir aber ARGB brauchen 
			if (m_D3DFVF & D3DFVF_DIFFUSE) 
                ConvertVertexColorToARGB((BYTE*)Vertices, (BYTE*)pVertices); 
            else 
                memcpy(Vertices, pVertices, uiNumOfVertices*m_VertexSize); 
 
			m_VertexBuffer->Unlock();*/ 
 
            void* Vertices = Lock(); 
            memcpy(Vertices, pVertices, uiNumOfVertices*m_VertexSize); 
            Unlock(); 
        }        
 
        //////////////////////////////////////////////////////////////////////////////// 
		UINT ceVertexBufferD3D9::CalculateFVFVertexSize(const ceVertexDescription& VertexDesc) 
		{ 
			PUSH_FUNCTION; 
			UINT ret=0; 
					 
			for(UCHAR i=0; i < VertexDesc.getNum(); i++) 
			{ 
			//	UINT AttribSize = VertexDesc.getAttributeSize(i); 
                ceVertexUsage usage = (ceVertexUsage)VertexDesc.getVertexUsage(i); 
 
                switch(usage) 
                { 
                case CE_RS_VU_TEXCOORD0: ret += sizeof(FLOAT) * 2; break; 
	            case CE_RS_VU_TEXCOORD1: ret += sizeof(FLOAT) * 2; break; 
	            case CE_RS_VU_TEXCOORD2: ret += sizeof(FLOAT) * 2; break; 
	            case CE_RS_VU_TEXCOORD3: ret += sizeof(FLOAT) * 2; break; 
	            case CE_RS_VU_TEXCOORD4: ret += sizeof(FLOAT) * 2; break; 
	            case CE_RS_VU_TEXCOORD5: ret += sizeof(FLOAT) * 2; break; 
	            case CE_RS_VU_TEXCOORD6: ret += sizeof(FLOAT) * 2; break; 
	            case CE_RS_VU_TEXCOORD7: ret += sizeof(FLOAT) * 2; break; 
	            case CE_RS_VU_POSITION: ret += sizeof(FLOAT) * 3; break; 
	            case CE_RS_VU_NORMAL: ret += sizeof(FLOAT) * 3; break; 
	            case CE_RS_VU_COLOR: ret += sizeof(DWORD); break; 
#ifdef _DEBUG 
				default: 
					CE_EXCEPTION(std::string(__FUNCTION__)+": Unsupported Attribute!\nPlease report to maintainer!\n", CELS_LOWERROR); 
					break; 
#endif 
				} 
			} 
			return ret; 
		} 
         
        DWORD ceVertexBufferD3D9::CalculateFVF(const ceVertexDescription& VertexDesc) 
        { 
			PUSH_FUNCTION; 
			DWORD dwFVF = 0; 
					 
			for(UCHAR i=0; i < VertexDesc.getNum(); i++) 
			{ 
                ceVertexUsage usage = (ceVertexUsage)VertexDesc.getVertexUsage(i); 
 
                switch(usage) 
                { 
                case CE_RS_VU_TEXCOORD0: dwFVF |= D3DFVF_TEX1; break; 
	            case CE_RS_VU_TEXCOORD1: dwFVF |= D3DFVF_TEX2; break; 
	            case CE_RS_VU_TEXCOORD2: dwFVF |= D3DFVF_TEX3; break; 
	            case CE_RS_VU_TEXCOORD3: dwFVF |= D3DFVF_TEX4; break; 
	            case CE_RS_VU_TEXCOORD4: dwFVF |= D3DFVF_TEX5; break; 
	            case CE_RS_VU_TEXCOORD5: dwFVF |= D3DFVF_TEX6; break; 
	            case CE_RS_VU_TEXCOORD6: dwFVF |= D3DFVF_TEX7; break; 
	            case CE_RS_VU_TEXCOORD7: dwFVF |= D3DFVF_TEX8; break; 
	            case CE_RS_VU_POSITION: dwFVF |= D3DFVF_XYZ; break; 
	            case CE_RS_VU_NORMAL: dwFVF |= D3DFVF_NORMAL; break; 
	            case CE_RS_VU_COLOR: dwFVF |= D3DFVF_DIFFUSE; break; 
#ifdef _DEBUG 
				default: 
					CE_EXCEPTION(std::string(__FUNCTION__)+": Unsupported Attribute!\nPlease report to maintainer!\n", CELS_LOWERROR); 
					break; 
#endif 
				} 
			} 
			return dwFVF; 
		} 
 
		//////////////////////////////////////////////////////////////////////////////////////// 
		//////////////////////////////////////////////////////////////////////////////////////// 
		void ceVertexBufferD3D9::Release(void) 
		{ 
			m_VertexBuffer->Release(); 
			m_VertexBuffer = NULL; 
			m_pD3DDevice = NULL; 
		} 
 
		void* ceVertexBufferD3D9::Lock(void) 
		{ 
            PUSH_FUNCTION; 
 
            if (m_D3DFVF & D3DFVF_DIFFUSE) 
            { 
                if (m_pColorData) 
                { 
                    delete [] m_pColorData; 
                    m_pColorData = NULL; 
                } 
 
                m_pColorData = new BYTE [m_NumOfVertices*m_VertexDesc.getVertexSize()]; 
                 
                m_VertexBuffer->Lock(0, 0, (&m_pLockedData), 0); 
 
                ConvertVertexColorToRGBA(m_pColorData, (BYTE*)m_pLockedData); 
 
			    return m_pColorData; 
            } 
            else 
            { 
                m_VertexBuffer->Lock(0, 0, (&m_pLockedData), 0); 
			    return m_pLockedData; 
            } 
		} 
		 
		void ceVertexBufferD3D9::Unlock(void) 
		{ 
            PUSH_FUNCTION; 
 
            if (m_pColorData) 
            { 
                ConvertVertexColorToARGB((BYTE*)m_pLockedData, (BYTE*)m_pColorData); 
                delete [] m_pColorData; 
                m_pColorData = NULL; 
            } 
 
            m_VertexBuffer->Unlock(); 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		 
 
		//////////////////////////////////////////////////////////////////////////////////////// 
 
		//////////////////////////////////////////////////////////////////////////////////////// 
		 
		//////////////////////////////////////////////////////////////////////////////////////// 
		ceIndexBufferD3D9::ceIndexBufferD3D9(void) 
		{ 
            m_pD3DDevice = NULL; 
            m_IndexBuffer = NULL; 
            m_bHasWordIndices = FALSE; 
            m_NumOfIndices = 0; 
            m_bDynamic = FALSE; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		ceIndexBufferD3D9::ceIndexBufferD3D9(LPDIRECT3DDEVICE9 D3DDevice) 
		{ 
            m_pD3DDevice = D3DDevice; 
            m_IndexBuffer = NULL; 
            m_bHasWordIndices = FALSE; 
            m_NumOfIndices = 0; 
            m_bDynamic = FALSE; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		ceIndexBufferD3D9::~ceIndexBufferD3D9(void) 
		{ 
			Release(); 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		//////////////////////////////////////////////////////////////////////////////////////// 
		void ceIndexBufferD3D9::Create(const cePrimitive Primitive, BOOL bDynamic, UINT uiNumOfIndices, const WORD* pIndices) 
		{ 
			if(!uiNumOfIndices || !pIndices) 
				return; 
 
			assert(m_pD3DDevice != NULL); 
 
            if (m_IndexBuffer) 
                m_IndexBuffer->Release(); 
 
			m_D3DPrimType = GetD3DPrimType(Primitive); 
			m_NumOfIndices = uiNumOfIndices; 
 
			switch(Primitive)  
            { 
			case CE_RS_PRIM_POINTS:  
				m_NumOfPrimitives = uiNumOfIndices;  
				break; 
			case CE_RS_PRIM_LINES:  
				m_NumOfPrimitives = (UINT)(uiNumOfIndices * 0.5f);  
				break; 
			case CE_RS_PRIM_LINESTRIP: 
				break; 
			case CE_RS_PRIM_TRIANGLES: 
				m_NumOfPrimitives = uiNumOfIndices / 3;  
				break; 
			case CE_RS_PRIM_TRISTRIP:  
				m_NumOfPrimitives = uiNumOfIndices - 2; 
				break; 
			case CE_RS_PRIM_TRIFAN: 
				m_NumOfPrimitives = uiNumOfIndices - 2; 
				break; 
            } 
 
            DWORD dwUsage  = D3DUSAGE_WRITEONLY; 
 
	        if (bDynamic) 
		        dwUsage |= D3DUSAGE_DYNAMIC; 
	 
			UINT Size = sizeof(WORD) * uiNumOfIndices; 
			m_pD3DDevice->CreateIndexBuffer(Size, bDynamic, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_IndexBuffer, NULL); 
 
			void* Indices=NULL; 
			m_IndexBuffer->Lock(0, Size, (void**) &Indices, 0); 
		//	memcpy(Indices, &pIndices, Size); 
            for (int i=0; iUnlock(); 
		} 
 
		void ceIndexBufferD3D9::Create(const cePrimitive Primitive, BOOL bDynamic, UINT uiNumOfIndices, const UINT* pIndices) 
		{ 
			if(!uiNumOfIndices || !pIndices) 
				return; 
 
			assert(m_pD3DDevice != NULL); 
 
            if (m_IndexBuffer) 
                m_IndexBuffer->Release(); 
 
			m_D3DPrimType = GetD3DPrimType(Primitive); 
			m_NumOfIndices = uiNumOfIndices; 
 
			switch(Primitive) { 
			case CE_RS_PRIM_POINTS:  
				m_NumOfPrimitives = uiNumOfIndices;  
				break; 
			case CE_RS_PRIM_LINES:  
				m_NumOfPrimitives = (UINT)(uiNumOfIndices * 0.5f);  
				break; 
			case CE_RS_PRIM_LINESTRIP: 
				break; 
			case CE_RS_PRIM_TRIANGLES: 
				m_NumOfPrimitives = uiNumOfIndices / 3;  
				break; 
			case CE_RS_PRIM_TRISTRIP:  
				m_NumOfPrimitives = uiNumOfIndices - 2; 
				break; 
			case CE_RS_PRIM_TRIFAN: 
				m_NumOfPrimitives = uiNumOfIndices - 2; 
				break; 
            default: 
                ce_assert(false && "unknown prim"); 
			} 
 
            DWORD dwUsage  = D3DUSAGE_WRITEONLY; 
	        if (bDynamic) 
		        dwUsage |= D3DUSAGE_DYNAMIC; 
	 
            UINT Size = sizeof(UINT) * uiNumOfIndices; 
			m_pD3DDevice->CreateIndexBuffer(Size, dwUsage, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_IndexBuffer, NULL); 
 
            void* Indices=NULL; 
			m_IndexBuffer->Lock(0, Size, (void**)(&Indices), 0); 
	//		memcpy(Indices, &pIndices, Size); 
            for (int i=0; iUnlock(); 
            Indices = NULL; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		void ceIndexBufferD3D9::Release(void) 
		{ 
			m_IndexBuffer->Release(); 
			m_IndexBuffer = NULL; 
			m_pD3DDevice = NULL; 
		} 
		//////////////////////////////////////////////////////////////////////////////////////// 
		void* ceIndexBufferD3D9::Lock(void) 
		{ 
			return NULL; 
		} 
		 
		void ceIndexBufferD3D9::Unlock(void) 
		{ 
		} 
 
	}	// namespace Render 
}	// namespace ZFXCE