File: model_renderer_d3d9.cpp

package info (click to toggle)
glest 3.2.2-2
  • links: PTS, VCS
  • area: contrib
  • in suites: squeeze
  • size: 2,800 kB
  • ctags: 6,581
  • sloc: cpp: 32,575; sh: 8,341; makefile: 63
file content (173 lines) | stat: -rw-r--r-- 5,051 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include "model_renderer_d3d9.h"

#include <cassert>

#include "graphics_interface.h"
#include "context_d3d9.h"
#include "texture_d3d9.h"
#include "interpolation.h"
#include "d3d9_util.h"

#include "leak_dumper.h"

namespace Shared{ namespace Graphics{ namespace D3d9{

// ===============================================
//	class ModelRendererD3d9
// ===============================================

D3DVERTEXELEMENT9 d3dVertexElementsPNT[]=
{
	{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
	{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
	{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
	D3DDECL_END()
};

D3DVERTEXELEMENT9 d3dVertexElementsPNTT[]=
{
	{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
	{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
	{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
	{0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
	D3DDECL_END()
};

ModelRendererD3d9::ModelRendererD3d9(){
	rendering= false;

	GraphicsInterface &gi= GraphicsInterface::getInstance();
	d3dDevice= static_cast<ContextD3d9*>(gi.getCurrentContext())->getD3dDevice();

	bufferPointCount= 0;
	bufferIndexCount= 0;

	D3DCALL(d3dDevice->CreateVertexDeclaration(d3dVertexElementsPNT, &d3dVertexDeclarationPNT));
	D3DCALL(d3dDevice->CreateVertexDeclaration(d3dVertexElementsPNTT, &d3dVertexDeclarationPNTT));

	readyBuffers(defBufferPointCount, defBufferIndexCount);
}

ModelRendererD3d9::~ModelRendererD3d9(){
	d3dVertexBuffer->Release();
}

void ModelRendererD3d9::begin(bool renderNormals, bool renderTextures, bool renderColors){
	rendering= true;
}

void ModelRendererD3d9::end(){
	rendering= false;
}

void ModelRendererD3d9::render(const Model *model){
	assert(rendering);

	//render every mesh
	for(uint32 i=0; i<model->getMeshCount(); ++i){
		renderMesh(model->getMesh(i));	
	}
}

void ModelRendererD3d9::renderNormalsOnly(const Model *model){
}

// ====================== Private ===============================================

void ModelRendererD3d9::renderMesh(const Mesh *mesh){

	CustomVertexPNTT *vertices;
	uint32 *indices;

	readyBuffers(mesh->getVertexCount(), mesh->getIndexCount());

	//lock vertex buffer
	D3DCALL(d3dVertexBuffer->Lock(0, mesh->getVertexCount()*sizeof(CustomVertexPNTT), (void**) &vertices, 0));

	//copy data vertex buffer
	const InterpolationData *interpolationData= mesh->getInterpolationData();

	for(int i=0; i<mesh->getVertexCount(); ++i){
		vertices[i].vertex= interpolationData->getVertices()[i];
		vertices[i].normal= interpolationData->getNormals()[i];
		Vec2f texCoord= mesh->getTexCoords()[i];
		vertices[i].texCoord= Vec2f(texCoord.x, texCoord.y);
	}
	if(mesh->getTangents()!=NULL){
		for(int i=0; i<mesh->getVertexCount(); ++i){
			vertices[i].tangent= mesh->getTangents()[i];
		}
	}

	//unlock vertex buffer
	D3DCALL(d3dVertexBuffer->Unlock());
	
	//lock index buffer
	D3DCALL(d3dIndexBuffer->Lock(0, mesh->getIndexCount()*sizeof(uint32), (void**) &indices, 0));

	//copy data
	for(int i=0; i<mesh->getIndexCount(); i+=3){
		indices[i]= mesh->getIndices()[i];
		indices[i+1]= mesh->getIndices()[i+2];
		indices[i+2]= mesh->getIndices()[i+1];
	}

	//unlock
	D3DCALL(d3dIndexBuffer->Unlock());

	//set stream data
	D3DCALL(d3dDevice->SetStreamSource(0, d3dVertexBuffer, 0, sizeof(CustomVertexPNTT)));
	D3DCALL(d3dDevice->SetVertexDeclaration(mesh->getTangents()==NULL? d3dVertexDeclarationPNT: d3dVertexDeclarationPNTT));
	D3DCALL(d3dDevice->SetIndices(d3dIndexBuffer));

	//set textures
	int textureUnit= 0;
	for(int i=0; i<meshTextureCount; ++i){
		if(mesh->getTexture(i)!=NULL){
		const Texture2DD3d9* texture2DD3d9= static_cast<const Texture2DD3d9*>(mesh->getTexture(i));
			D3DCALL(d3dDevice->SetTexture(textureUnit, texture2DD3d9->getD3dTexture()));
			++textureUnit;
		}
	}

	//render
	D3DCALL(d3dDevice->BeginScene());
	D3DCALL(d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, mesh->getVertexCount(), 0, mesh->getIndexCount()/3));
	D3DCALL(d3dDevice->EndScene());

	//reset textures
	for(int i=0; i<meshTextureCount; ++i){
		D3DCALL(d3dDevice->SetTexture(i, NULL));
	}
}

void ModelRendererD3d9::readyBuffers(int newPointCount, int newIndexCount){
	
	//vertices, if the buffer is to small allocate a new buffer
	if(bufferPointCount<newPointCount){
		bufferPointCount= newPointCount;
		
		D3DCALL(d3dDevice->CreateVertexBuffer( 
			bufferPointCount*sizeof(CustomVertexPNTT),
			0, 
			0, 
			D3DPOOL_MANAGED, 
			&d3dVertexBuffer, 
			NULL));
	}

	//indices
	if(bufferIndexCount<newIndexCount){
		bufferIndexCount= newIndexCount;
		
		D3DCALL(d3dDevice->CreateIndexBuffer( 
			bufferIndexCount*sizeof(uint32),
			0, 
			D3DFMT_INDEX32, 
			D3DPOOL_MANAGED, 
			&d3dIndexBuffer, 
			NULL));
	}
}

}}}//end namespace