1 #include "model_renderer_d3d9.h"
2 
3 #include <cassert>
4 
5 #include "graphics_interface.h"
6 #include "context_d3d9.h"
7 #include "texture_d3d9.h"
8 #include "interpolation.h"
9 #include "d3d9_util.h"
10 
11 #include "leak_dumper.h"
12 
13 namespace Shared{ namespace Graphics{ namespace D3d9{
14 
15 // ===============================================
16 //	class ModelRendererD3d9
17 // ===============================================
18 
19 D3DVERTEXELEMENT9 d3dVertexElementsPNT[]=
20 {
21 	{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
22 	{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
23 	{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
24 	D3DDECL_END()
25 };
26 
27 D3DVERTEXELEMENT9 d3dVertexElementsPNTT[]=
28 {
29 	{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
30 	{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
31 	{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
32 	{0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
33 	D3DDECL_END()
34 };
35 
ModelRendererD3d9()36 ModelRendererD3d9::ModelRendererD3d9(){
37 	rendering= false;
38 
39 	GraphicsInterface &gi= GraphicsInterface::getInstance();
40 	d3dDevice= static_cast<ContextD3d9*>(gi.getCurrentContext())->getD3dDevice();
41 
42 	bufferPointCount= 0;
43 	bufferIndexCount= 0;
44 
45 	D3DCALL(d3dDevice->CreateVertexDeclaration(d3dVertexElementsPNT, &d3dVertexDeclarationPNT));
46 	D3DCALL(d3dDevice->CreateVertexDeclaration(d3dVertexElementsPNTT, &d3dVertexDeclarationPNTT));
47 
48 	readyBuffers(defBufferPointCount, defBufferIndexCount);
49 }
50 
~ModelRendererD3d9()51 ModelRendererD3d9::~ModelRendererD3d9(){
52 	d3dVertexBuffer->Release();
53 }
54 
begin(bool renderNormals,bool renderTextures,bool renderColors)55 void ModelRendererD3d9::begin(bool renderNormals, bool renderTextures, bool renderColors){
56 	rendering= true;
57 }
58 
end()59 void ModelRendererD3d9::end(){
60 	rendering= false;
61 }
62 
render(const Model * model)63 void ModelRendererD3d9::render(const Model *model){
64 	assert(rendering);
65 
66 	//render every mesh
67 	for(uint32 i=0; i<model->getMeshCount(); ++i){
68 		renderMesh(model->getMesh(i));
69 	}
70 }
71 
renderNormalsOnly(const Model * model)72 void ModelRendererD3d9::renderNormalsOnly(const Model *model){
73 }
74 
75 // ====================== Private ===============================================
76 
renderMesh(const Mesh * mesh)77 void ModelRendererD3d9::renderMesh(const Mesh *mesh){
78 
79 	CustomVertexPNTT *vertices;
80 	uint32 *indices;
81 
82 	readyBuffers(mesh->getVertexCount(), mesh->getIndexCount());
83 
84 	//lock vertex buffer
85 	D3DCALL(d3dVertexBuffer->Lock(0, mesh->getVertexCount()*sizeof(CustomVertexPNTT), (void**) &vertices, 0));
86 
87 	//copy data vertex buffer
88 	const InterpolationData *interpolationData= mesh->getInterpolationData();
89 
90 	for(int i=0; i<mesh->getVertexCount(); ++i){
91 		vertices[i].vertex= interpolationData->getVertices()[i];
92 		vertices[i].normal= interpolationData->getNormals()[i];
93 		Vec2f texCoord= mesh->getTexCoords()[i];
94 		vertices[i].texCoord= Vec2f(texCoord.x, texCoord.y);
95 	}
96 	if(mesh->getTangents()!=NULL){
97 		for(int i=0; i<mesh->getVertexCount(); ++i){
98 			vertices[i].tangent= mesh->getTangents()[i];
99 		}
100 	}
101 
102 	//unlock vertex buffer
103 	D3DCALL(d3dVertexBuffer->Unlock());
104 
105 	//lock index buffer
106 	D3DCALL(d3dIndexBuffer->Lock(0, mesh->getIndexCount()*sizeof(uint32), (void**) &indices, 0));
107 
108 	//copy data
109 	for(int i=0; i<mesh->getIndexCount(); i+=3){
110 		indices[i]= mesh->getIndices()[i];
111 		indices[i+1]= mesh->getIndices()[i+2];
112 		indices[i+2]= mesh->getIndices()[i+1];
113 	}
114 
115 	//unlock
116 	D3DCALL(d3dIndexBuffer->Unlock());
117 
118 	//set stream data
119 	D3DCALL(d3dDevice->SetStreamSource(0, d3dVertexBuffer, 0, sizeof(CustomVertexPNTT)));
120 	D3DCALL(d3dDevice->SetVertexDeclaration(mesh->getTangents()==NULL? d3dVertexDeclarationPNT: d3dVertexDeclarationPNTT));
121 	D3DCALL(d3dDevice->SetIndices(d3dIndexBuffer));
122 
123 	//set textures
124 	int textureUnit= 0;
125 	for(int i=0; i<meshTextureCount; ++i){
126 		if(mesh->getTexture(i)!=NULL){
127 		const Texture2DD3d9* texture2DD3d9= static_cast<const Texture2DD3d9*>(mesh->getTexture(i));
128 			D3DCALL(d3dDevice->SetTexture(textureUnit, texture2DD3d9->getD3dTexture()));
129 			++textureUnit;
130 		}
131 	}
132 
133 	//render
134 	D3DCALL(d3dDevice->BeginScene());
135 	D3DCALL(d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mesh->getVertexCount(), 0, mesh->getIndexCount()/3));
136 	D3DCALL(d3dDevice->EndScene());
137 
138 	//reset textures
139 	for(int i=0; i<meshTextureCount; ++i){
140 		D3DCALL(d3dDevice->SetTexture(i, NULL));
141 	}
142 }
143 
readyBuffers(int newPointCount,int newIndexCount)144 void ModelRendererD3d9::readyBuffers(int newPointCount, int newIndexCount){
145 
146 	//vertices, if the buffer is to small allocate a new buffer
147 	if(bufferPointCount<newPointCount){
148 		bufferPointCount= newPointCount;
149 
150 		D3DCALL(d3dDevice->CreateVertexBuffer(
151 			bufferPointCount*sizeof(CustomVertexPNTT),
152 			0,
153 			0,
154 			D3DPOOL_MANAGED,
155 			&d3dVertexBuffer,
156 			NULL));
157 	}
158 
159 	//indices
160 	if(bufferIndexCount<newIndexCount){
161 		bufferIndexCount= newIndexCount;
162 
163 		D3DCALL(d3dDevice->CreateIndexBuffer(
164 			bufferIndexCount*sizeof(uint32),
165 			0,
166 			D3DFMT_INDEX32,
167 			D3DPOOL_MANAGED,
168 			&d3dIndexBuffer,
169 			NULL));
170 	}
171 }
172 
173 }}}//end namespace