예제 #1
0
Graphics::Graphics()
{
	mBufferFactory = new BufferFactory();

	initBuffers();
	initEffect();
	initFonts();

	mWhiteTexture = loadTexture("data/imgs/white.bmp");

	// TESTING.. 
	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
	UINT numElems = 0;
	VertexPNT::Decl->GetDeclaration(elems, &numElems);
	D3DXCreateMesh(2, 4, D3DXMESH_MANAGED, elems, gd3dDevice, &mRayMesh);
	
	onResetDevice();
}
예제 #2
0
파일: ObjParser.cpp 프로젝트: bobxiv/ICCore
void ObjParser::Load(LPCSTR Filename, LPDIRECT3DDEVICE9 pDevice)
{
		FILE* fileHandle = fopen(Filename, "r+");
		if( fileHandle == NULL )
			return;

		char line[256];
		D3DXVECTOR3 vec;

		while( !feof(fileHandle) )//Foreach Line
		{
			fgets(line, 256, fileHandle);

			#pragma region Line Read
			switch(line[0])
			{
			case 'm':
				{
				LPCSTR name = new CHAR[256];
				sscanf_s(line, "mtllib %s", name, 255);

				ParseMaterial(name);
				}
				break;
			case 'v'://Vertex Item
				{
				switch(line[1])
					{
					case ' '://Vertex
						{
						sscanf_s(line, "v %f %f %f", &vec.x, &vec.y, &vec.z );

						Vertexs.push_back(vec);
						mVertexsHT.push_back(NULL);//expand HashTable
						}
						break;
					case 't'://Texture Coordinates
						{
						D3DXVECTOR3 tex;
						sscanf_s(line, "vt %f %f %f", &vec.x, &vec.y, &vec.z);

						Textures.push_back(vec);
						}
						break;
					case 'n'://Normal
						{
						D3DXVECTOR3 nor;
						sscanf_s(line, "vn %f %f %f", &vec.x, &vec.y, &vec.z );

						Normals.push_back(vec);
						}
						break;
					default:// Not supposed to happen
						assert( false );
					}

				}
				break;
			case 'f'://Face Item
				{
				DWORD quadP[4];//Position Index quad
				DWORD quadT[4];//Texture  Index quad
				DWORD quadN[4];//Normal   Index quad
				memset(quadP, -1, sizeof(DWORD)*4);
				memset(quadT, -1, sizeof(DWORD)*4);
				memset(quadN, -1, sizeof(DWORD)*4);

				int size = strlen(line);
				int barCount = std::count(line, line+size, '/');

				int readed = 0;

				//By default .obj file puts faces with CW winding
				switch( barCount )
					{
					case 0:// tri/quad	pos
						{
							if( m_Winding == VertexWinding::CCW )
								readed = sscanf_s(line, "f %d %d %d %d", &quadP[3], &quadP[2], &quadP[1], &quadP[0] );
							else
								readed = sscanf_s(line, "f %d %d %d %d", &quadP[0], &quadP[1], &quadP[2], &quadP[3] );
							assert( readed == 3 || readed == 4 );
						}
						break;
					case 3:// tri	pos/tex
						{
							if( m_Winding == VertexWinding::CCW )
								readed = sscanf_s(line, "f %d/%d %d/%d %d/%d", 
								&quadP[2], &quadT[2],
								&quadP[1], &quadT[1],
								&quadP[0], &quadT[0]
								);
							else
								readed = sscanf_s(line, "f %d/%d %d/%d %d/%d", 
								&quadP[0], quadT[0],
								&quadP[1], quadT[1],
								&quadP[2], quadT[2]
								);
							assert( readed == 6 );
							readed /= 2;
						}
						break;
					case 4:// quad	pos/tex
						{
							if( m_Winding == VertexWinding::CCW )
								readed = sscanf_s(line, "f %d/%d %d/%d %d/%d %d/%d", 
								&quadP[3], &quadT[3],
								&quadP[2], &quadT[2], 
								&quadP[1], &quadT[1],
								&quadP[0], &quadT[0] 
								);
							else
								readed = sscanf_s(line, "f %d/%d %d/%d %d/%d %d/%d", 
								&quadP[0], &quadT[0],
								&quadP[1], &quadT[1],
								&quadP[2], &quadT[2],
								&quadP[3], &quadT[3]
								);
							assert( readed == 8 );
							readed /= 2;
						}
						break;
					case 6:// tri	pos/tex/nor
						{
							if( m_Winding == VertexWinding::CCW )
								readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", 
								&quadP[2], &quadT[2], &quadN[2],
								&quadP[1], &quadT[1], &quadN[1],
								&quadP[0], &quadT[0], &quadN[0]
								);
							else
								readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", 
								&quadP[0], &quadT[0], &quadN[0],
								&quadP[1], &quadT[1], &quadN[1],
								&quadP[2], &quadT[2], &quadN[2]
								);
							assert( readed == 9 );
							readed /= 3;
						}
						break;
					case 8:// quad	pos/tex/nor
						{
							if( m_Winding == VertexWinding::CCW )
								readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", 
								&quadP[3], &quadT[3], &quadN[3],
								&quadP[2], &quadT[2], &quadN[2],
								&quadP[1], &quadT[1], &quadN[1],
								&quadP[0], &quadT[0], &quadN[0]
								);
							else
								readed = sscanf_s(line, "f %d/%d/%d %d/%d/%d %d/%d/%d %d/%d/%d", 
								&quadP[0], &quadT[0], &quadN[0],
								&quadP[1], &quadT[1], &quadN[1],
								&quadP[2], &quadT[2], &quadN[2],
								&quadP[3], &quadT[3], &quadN[3]
								);
							assert( readed == 12 );
							readed /= 3;
						}
						break;
					default:// Not supposed to happen
						assert( false );
					}

				//The indexs are in 1 Base, we transform to 0 Base
				for( int i=0; i < 4 ; ++i )
				{
					quadP[i]--; quadT[i]--; quadN[i]--;
				}

				for(int j=0; j < 3 ; ++j)
					{
						VertexTextureNormal NewVertex;
						NewVertex.SetPosition( Vertexs[quadP[j]] );
						if( quadT[j] != (DWORD(-1)-1) )
							NewVertex.SetTexture ( Textures[quadT[j]].x, Textures[quadT[j]].y );
						if( quadN[j] != (DWORD(-1)-1) )
							NewVertex.SetNormal  ( Normals[quadN[j]] );
						
						DWORD index = AddVertex(quadP[j], NewVertex);
						mIndexs.push_back(index);
					}
 
				if( readed == 4 )// quad readed
					{
						quadP[1] = quadP[2]; quadT[1] = quadT[2]; quadN[1] = quadN[2]; 
						quadP[2] = quadP[3]; quadT[2] = quadT[3]; quadN[1] = quadN[2]; 
												
						for(int j=0; j < 3 ; ++j)
							{
							VertexTextureNormal NewVertex;
							NewVertex.SetPosition( Vertexs[quadP[j]] );
							if( quadT[j] != (DWORD(-1)-1) )
								NewVertex.SetTexture ( Textures[quadT[j]].x, Textures[quadT[j]].y );
							if( quadN[j] != (DWORD(-1)-1) )
								NewVertex.SetNormal  ( Normals[quadN[j]] );
						
							DWORD index = AddVertex(quadP[j], NewVertex);
							mIndexs.push_back(index);
							}
					}

				}
				break;

			}
			#pragma endregion

		}
			
		fclose(fileHandle);
		
		DWORD FVF = NULL;
		D3DVERTEXELEMENT9* pMeshVDeclaration = NULL;
		int code = 0;
		IdentifieLoadedFormat(FVF, pMeshVDeclaration, code);
		if( code == 0 )
			return;
		
		//Setup Mesh with VertexDeclaration corresponding to the loaded data
		LPD3DXMESH pMesh = NULL;
		HRESULT hr = NULL;
		
		int FacesCount = mIndexs.size()/3;
		switch( m_VertexMetaFormat )
		{
		case VertexMetaFormat::VertexDeclaration:
			{
				if( FacesCount > 65535 )// if huge mesh, 32 bits face index
					hr = D3DXCreateMesh(FacesCount, mVertexs.size(), D3DXMESH_32BIT | D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , 
						pMeshVDeclaration, pDevice, &pMesh);
				else
					hr = D3DXCreateMesh(FacesCount, mVertexs.size(), D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM , 
						pMeshVDeclaration, pDevice, &pMesh);
			}
			break;
		case VertexMetaFormat::FVF:
			{
				if( FacesCount > 65535 )// if huge mesh, 32 bits face index
					hr = D3DXCreateMeshFVF(FacesCount, Vertexs.size(), D3DXMESH_32BIT | D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM ,
						FVF, pDevice, &pMesh);
				else
					hr = D3DXCreateMeshFVF(FacesCount, Vertexs.size(), D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM | D3DXMESH_SYSTEMMEM ,
						FVF, pDevice, &pMesh);
			}
			break;
		default:
			assert( false );
		}

		assert( !FAILED(hr) );
		
		//Puts vertex data inside loadedData in the smallest format needed
		//(not nesesarily VertexTextureNormal)
		void* loadedData = NULL;
		void* loadedIndex = NULL;
		size_t size = 0;
		//Pass to our vertex format
		PutLoadedDataInVertexDeclarationFormat(loadedData,loadedIndex,size,code, FacesCount);

		//Free Auxiliary Arrays
		Vertexs.clear();
		Textures.clear();
		Normals.clear();
		mVertexsHT.clear();
		
		void* data = NULL;
		//Loads the Vertex Buffer
		if( FAILED(pMesh->LockVertexBuffer(NULL, &data)) )
			return;

			memcpy(data, loadedData, size*mVertexs.size());

		pMesh->UnlockVertexBuffer();

		//Loads the Index Buffer
		if( FAILED(pMesh->LockIndexBuffer(NULL, &data)) )
			return;

			if( FacesCount > 65535 )
				memcpy(data, loadedIndex, sizeof(DWORD)*mIndexs.size());
			else
				memcpy(data, loadedIndex, sizeof(WORD)*mIndexs.size());

		pMesh->UnlockIndexBuffer();

		//Free main Arrays
		mVertexs.clear();
		mIndexs.clear();

		//Mesh data ready
		m_RootMeshContainer = new D3DXMESHCONTAINER;
		m_RootMeshContainer->MeshData.pMesh = pMesh;

		return;
	}
예제 #3
0
HRESULT XFileCreator::CreateMesh(std::vector<Vertex> vertices,
                                 std::vector<Face> faces)
{
    HRESULT hr;

    DWORD numFaces = faces.size();
    DWORD numVertices = vertices.size();

    PD(L"number of vertices: ", numVertices);
    PD(L"number of faces: ", numFaces);

    D3DVERTEXELEMENT9 localVertDecl[MAX_FVF_DECL_SIZE] =
    {
        {0,  0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
        {0,  12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
        D3DDECL_END()
    };

    hr = D3DXCreateMesh(numFaces, numVertices, D3DXMESH_MANAGED | D3DXMESH_32BIT,
                        localVertDecl, mDevice, &mMesh);

    PD(hr, L"create mesh");
    if(FAILED(hr)) return hr;

    LOCAL_VERTEX *pVertices = NULL;
    hr = mMesh->LockVertexBuffer(0, (void**)&pVertices);
    PD(hr, L"lock vertex buffer");
    if(FAILED(hr)) return hr;

    for ( DWORD i = 0; i < numVertices; ++i ) {
        pVertices[i].pos = D3DXVECTOR3(vertices[i].pos.x,
                                       vertices[i].pos.y,
                                       vertices[i].pos.z);
    }

    hr = mMesh->UnlockVertexBuffer();
    PD(hr, L"unlock vertex buffer");
    if(FAILED(hr)) return hr;

    DWORD* pIndices = NULL;

    hr = mMesh->LockIndexBuffer(0, (void**)&pIndices);
    PD(hr, L"lock index buffer");
    if(FAILED(hr)) return hr;

    for ( DWORD i = 0; i < numFaces; i++ ) {
        pIndices[3 * i]     = faces[i].vertices[0];
        pIndices[3 * i + 1] = faces[i].vertices[1];
        pIndices[3 * i + 2] = faces[i].vertices[2];
    }

    hr = mMesh->UnlockIndexBuffer();
    PD(hr, L"unlock index buffer");
    if(FAILED(hr)) return hr;

    DWORD* pAdjacency = new DWORD[numFaces * 3];
    hr = mMesh->GenerateAdjacency(1e-6f, pAdjacency);
    PD(hr, L"generate adjacency");
    if(FAILED(hr)) return hr;

    hr = D3DXComputeNormals(mMesh, pAdjacency);
    PD(hr, L"compute normals");
    if(FAILED(hr)) return hr;

    delete [] pAdjacency;

    return D3D_OK;
}
예제 #4
0
PondWater::PondWater(InitInfo& initInfo)
{
	mInitInfo = initInfo;

	mWidth = (initInfo.vertCols-1)*initInfo.dx;
	mDepth = (initInfo.vertRows-1)*initInfo.dz;

	mWaveMapOffset0 = D3DXVECTOR2(0.0f, 0.0f);
	mWaveMapOffset1 = D3DXVECTOR2(0.0f, 0.0f);

	DWORD numTris  = (initInfo.vertRows-1)*(initInfo.vertCols-1)*2;
	DWORD numVerts = initInfo.vertRows*initInfo.vertCols;


	//===============================================================
	// Allocate the mesh.


	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
	UINT numElems = 0;
	HR(VertexPT::Decl->GetDeclaration(elems, &numElems));
	HR(D3DXCreateMesh(numTris, numVerts, 
		D3DXMESH_MANAGED, elems, gd3dDevice, &mMesh));


	//===============================================================
	// Write the grid vertices and triangles to the mesh.

	VertexPT* v = 0;
	HR(mMesh->LockVertexBuffer(0, (void**)&v));
	
	std::vector<D3DXVECTOR3> verts;
	std::vector<DWORD> indices;
	GenTriGrid(mInitInfo.vertRows, mInitInfo.vertCols, mInitInfo.dx, 
		mInitInfo.dz, D3DXVECTOR3(0.0f, 0.0f, 0.0f), verts, indices);

	for(int i = 0; i < mInitInfo.vertRows; ++i)
	{
		for(int j = 0; j < mInitInfo.vertCols; ++j)
		{
			DWORD index   = i * mInitInfo.vertCols + j;
			v[index].pos  = verts[index];
			v[index].tex0 = D3DXVECTOR2((float)j/mInitInfo.vertCols, 
				                        (float)i/mInitInfo.vertRows)
										* initInfo.texScale;
		}
	}
	HR(mMesh->UnlockVertexBuffer());

	//===============================================================
	// Write triangle data so we can compute normals.

	WORD* indexBuffPtr = 0;
	HR(mMesh->LockIndexBuffer(0, (void**)&indexBuffPtr));
	DWORD* attBuff = 0;
	HR(mMesh->LockAttributeBuffer(0, &attBuff));
	for(UINT i = 0; i < mMesh->GetNumFaces(); ++i)
	{
		indexBuffPtr[i*3+0] = (WORD)indices[i*3+0];
		indexBuffPtr[i*3+1] = (WORD)indices[i*3+1];
		indexBuffPtr[i*3+2] = (WORD)indices[i*3+2];

		attBuff[i] = 0; // All in subset 0.
	}
	HR(mMesh->UnlockIndexBuffer());
	HR(mMesh->UnlockAttributeBuffer());

	//===============================================================
	// Optimize for the vertex cache and build attribute table.

	DWORD* adj = new DWORD[mMesh->GetNumFaces()*3];
	HR(mMesh->GenerateAdjacency(EPSILON, adj));
	HR(mMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE|D3DXMESHOPT_ATTRSORT,
		adj, 0, 0, 0));
	delete[] adj;


	//===============================================================
	// Create textures/effect.

	HR(D3DXCreateTextureFromFile(gd3dDevice, initInfo.waveMapFilename0.c_str(), &mWaveMap0));
	HR(D3DXCreateTextureFromFile(gd3dDevice, initInfo.waveMapFilename1.c_str(), &mWaveMap1));

	D3DVIEWPORT9 vp = {0, 0, 512, 512, 0.0f, 1.0f};
	mRefractMap = new DrawableTex2D(512, 512, 0, D3DFMT_X8R8G8B8, true, D3DFMT_D24X8, vp, true);
	mReflectMap = new DrawableTex2D(512, 512, 0, D3DFMT_X8R8G8B8, true, D3DFMT_D24X8, vp, true);

	buildFX();
}
예제 #5
0
Geometry::Geometry(LPDIRECT3DDEVICE9 d3ddev, 
                   const std::string& filename,
                   LPD3DXEFFECT shader) :
    m_shape(NONE),
    m_mesh(nullptr),
    m_shader(shader),
    m_texture(nullptr)
{
    // Create a assimp mesh
    std::string errorBuffer;
    Assimpmesh mesh;
    if(!mesh.Initialise(filename, errorBuffer))
    {
        ShowMessageBox(errorBuffer);
    }

    std::vector<unsigned long> indexData;
    std::vector<MeshVertex> vertexData;
    const std::vector<Assimpmesh::SubMesh>& subMeshes = mesh.GetMeshes();

    for(unsigned int i = 0; i < subMeshes.size(); ++i)
    {
        // Fill in vertex data
        for(unsigned int j = 0; j < subMeshes[i].vertices.size(); ++j)
        {
            MeshVertex v;
            v.normal.x = subMeshes[i].vertices[j].nx;
            v.normal.y = subMeshes[i].vertices[j].ny;
            v.normal.z = subMeshes[i].vertices[j].nz;
            v.position.x = subMeshes[i].vertices[j].x;
            v.position.y = subMeshes[i].vertices[j].y;
            v.position.z = subMeshes[i].vertices[j].z;
            v.uvs.x = subMeshes[i].vertices[j].u;
            v.uvs.y = subMeshes[i].vertices[j].v;
            vertexData.push_back(v);
        }

        for(unsigned int j = 0; j < subMeshes[i].indices.size(); ++j)
        {
            indexData.push_back(subMeshes[i].indices[j]);
        }
    }

    // Mesh Vertex Declaration
    D3DVERTEXELEMENT9 VertexDecl[] =
    {
        { 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()
    };

    // Create the DirectX Mesh
    if(FAILED(D3DXCreateMesh(indexData.size()/3, vertexData.size(), 
        D3DXMESH_MANAGED | D3DXMESH_32BIT, VertexDecl, d3ddev, &m_mesh)))
    {
        ShowMessageBox("Mesh " + filename + " creation failed");
    }

    // Fill in the vertex buffer
    MeshVertex* vertexBuffer;
    if(FAILED(m_mesh->LockVertexBuffer(0, (void**)&vertexBuffer)))
    {
        ShowMessageBox(filename + " Vertex buffer lock failed");
    }
    #pragma warning(disable: 4996)
    std::copy(vertexData.begin(), vertexData.end(), vertexBuffer);
    m_mesh->UnlockVertexBuffer();

    // Fill in the index buffer
    DWORD* indexBuffer;
    if(FAILED(m_mesh->LockIndexBuffer(0, (void**)&indexBuffer)))
    {
        ShowMessageBox(filename + " Index buffer lock failed");
    }
    #pragma warning(disable: 4996)
    std::copy(indexData.begin(), indexData.end(), indexBuffer);
    m_mesh->UnlockIndexBuffer();

    CreateMeshData<MeshVertex, DWORD>(false);
}
예제 #6
0
/**
	* Creates a D3DXMESH from a FStaticMeshRenderData
	* @param Triangles The triangles to create the mesh from.
	* @param bRemoveDegenerateTriangles True if degenerate triangles should be removed
	* @param OutD3DMesh Mesh to create
	* @return Boolean representing success or failure
*/
bool ConvertRawMeshToD3DXMesh(
	IDirect3DDevice9* Device,
	FRawMesh& RawMesh,
	const bool bRemoveDegenerateTriangles,	
	TRefCountPtr<ID3DXMesh>& OutD3DMesh
	)
{
	TArray<D3DVERTEXELEMENT9> VertexElements;
	GetD3D9MeshVertexDeclarations(VertexElements);

	TArray<FUtilVertex> Vertices;
	TArray<uint16> Indices;
	TArray<uint32> Attributes;
	int32 NumWedges = RawMesh.WedgeIndices.Num();
	int32 NumTriangles = NumWedges / 3;
	int32 NumUVs = 0;
	for (; NumUVs < 8; ++NumUVs)
	{
		if (RawMesh.WedgeTexCoords[NumUVs].Num() != RawMesh.WedgeIndices.Num())
		{
			break;
		}
	}

	bool bHaveColors = RawMesh.WedgeColors.Num() == NumWedges;
	bool bHaveNormals = RawMesh.WedgeTangentZ.Num() == NumWedges;
	bool bHaveTangents = bHaveNormals && RawMesh.WedgeTangentX.Num() == NumWedges
		&& RawMesh.WedgeTangentY.Num() == NumWedges;

	for(int32 TriangleIndex = 0;TriangleIndex < NumTriangles;TriangleIndex++)
	{
		bool bTriangleIsDegenerate = false;

		if( bRemoveDegenerateTriangles )
		{
			// Detect if the triangle is degenerate.
			for(int32 EdgeIndex = 0;EdgeIndex < 3;EdgeIndex++)
			{
				const int32 Wedge0 = TriangleIndex * 3 + EdgeIndex;
				const int32 Wedge1 = TriangleIndex * 3 + ((EdgeIndex + 1) % 3);
				if((RawMesh.GetWedgePosition(Wedge0) - RawMesh.GetWedgePosition(Wedge1)).IsNearlyZero(THRESH_POINTS_ARE_SAME * 4.0f))
				{
					bTriangleIsDegenerate = true;
					break;
				}
			}
		}

		if(!bTriangleIsDegenerate)
		{
			Attributes.Add(RawMesh.FaceMaterialIndices[TriangleIndex]);
			for(int32 J=0;J<3;J++)
			{
				FUtilVertex* Vertex = new(Vertices) FUtilVertex;
				FMemory::Memzero(Vertex,sizeof(FUtilVertex));
				int32 WedgeIndex = TriangleIndex * 3 + J;
				Vertex->Position = RawMesh.GetWedgePosition(WedgeIndex);
				if (bHaveColors)
				{
					Vertex->Color = RawMesh.WedgeColors[WedgeIndex];
				}
				else
				{
					Vertex->Color = FColor::White;
				}
				//store the smoothing mask per vertex since there is only one per-face attribute that is already being used (materialIndex)
				Vertex->SmoothingMask = RawMesh.FaceSmoothingMasks[TriangleIndex];
				if (bHaveTangents)
				{
					Vertex->TangentX = RawMesh.WedgeTangentX[WedgeIndex];
					Vertex->TangentY = RawMesh.WedgeTangentY[WedgeIndex];
				}
				if (bHaveNormals)
				{
					Vertex->TangentZ = RawMesh.WedgeTangentZ[WedgeIndex];
				}
				for(int32 UVIndex = 0; UVIndex < NumUVs; UVIndex++)
				{
					Vertex->UVs[UVIndex] = RawMesh.WedgeTexCoords[UVIndex][WedgeIndex];
				}
	 
				Indices.Add(Vertices.Num() - 1);
			}
		}
	}

	// This code uses the raw triangles. Needs welding, etc.
	const int32 NumFaces = Indices.Num() / 3;
	const int32 NumVertices = NumFaces*3;

	check(Attributes.Num() == NumFaces);
	check(NumFaces * 3 == Indices.Num());

	// Create mesh for source data
	if (FAILED(D3DXCreateMesh(NumFaces,NumVertices,D3DXMESH_SYSTEMMEM,(D3DVERTEXELEMENT9 *)VertexElements.GetData(),Device,OutD3DMesh.GetInitReference()) ) )
	{
		UE_LOG(LogD3D9MeshUtils, Warning, TEXT("D3DXCreateMesh() Failed!"));
		return false;
	}

	// Fill D3DMesh mesh
	FUtilVertex* D3DVertices;
	uint16*		 D3DIndices;
	::DWORD *		 D3DAttributes;
	OutD3DMesh->LockVertexBuffer(0,(LPVOID*)&D3DVertices);
	OutD3DMesh->LockIndexBuffer(0,(LPVOID*)&D3DIndices);
	OutD3DMesh->LockAttributeBuffer(0, &D3DAttributes);

	FMemory::Memcpy(D3DVertices,Vertices.GetTypedData(),Vertices.Num() * sizeof(FUtilVertex));
	FMemory::Memcpy(D3DIndices,Indices.GetTypedData(),Indices.Num() * sizeof(uint16));
	FMemory::Memcpy(D3DAttributes,Attributes.GetTypedData(),Attributes.Num() * sizeof(uint32));

	OutD3DMesh->UnlockIndexBuffer();
	OutD3DMesh->UnlockVertexBuffer();
	OutD3DMesh->UnlockAttributeBuffer();

	return true;
}
예제 #7
0
/** Merges a set of D3DXMeshes. */
static void MergeD3DXMeshes(
	IDirect3DDevice9* Device,
	TRefCountPtr<ID3DXMesh>& OutMesh,TArray<int32>& OutBaseFaceIndex,const TArray<ID3DXMesh*>& Meshes)
{
	TArray<D3DVERTEXELEMENT9> VertexElements;
	GetD3D9MeshVertexDeclarations(VertexElements);
		
	// Count the number of faces and vertices in the input meshes.
	int32 NumFaces = 0;
	int32 NumVertices = 0;
	for(int32 MeshIndex = 0;MeshIndex < Meshes.Num();MeshIndex++)
	{
		NumFaces += Meshes[MeshIndex]->GetNumFaces();
		NumVertices += Meshes[MeshIndex]->GetNumVertices();
	}

	// Create mesh for source data
	VERIFYD3D9RESULT(D3DXCreateMesh(
		NumFaces,
		NumVertices,
		D3DXMESH_SYSTEMMEM,
		(D3DVERTEXELEMENT9*)VertexElements.GetData(),
		Device,
		OutMesh.GetInitReference()
		) );

	// Fill D3DXMesh
	FUtilVertex* ResultVertices;
	uint16*		 ResultIndices;
	::DWORD *		 ResultAttributes;
	OutMesh->LockVertexBuffer(0,(LPVOID*)&ResultVertices);
	OutMesh->LockIndexBuffer(0,(LPVOID*)&ResultIndices);
	OutMesh->LockAttributeBuffer(0, &ResultAttributes);

	int32 BaseVertexIndex = 0;
	int32 BaseFaceIndex = 0;
	for(int32 MeshIndex = 0;MeshIndex < Meshes.Num();MeshIndex++)
	{
		ID3DXMesh* Mesh = Meshes[MeshIndex];
				
		FUtilVertex* Vertices;
		uint16*		 Indices;
		::DWORD *		 Attributes;
		Mesh->LockVertexBuffer(0,(LPVOID*)&Vertices);
		Mesh->LockIndexBuffer(0,(LPVOID*)&Indices);
		Mesh->LockAttributeBuffer(0, &Attributes);

		for(uint32 FaceIndex = 0;FaceIndex < Mesh->GetNumFaces();FaceIndex++)
		{
			for(uint32 VertexIndex = 0;VertexIndex < 3;VertexIndex++)
			{
				*ResultIndices++ = BaseVertexIndex + *Indices++;
			}
		}
		OutBaseFaceIndex.Add(BaseFaceIndex);
		BaseFaceIndex += Mesh->GetNumFaces();

		FMemory::Memcpy(ResultVertices,Vertices,Mesh->GetNumVertices() * sizeof(FUtilVertex));
		ResultVertices += Mesh->GetNumVertices();
		BaseVertexIndex += Mesh->GetNumVertices();

		FMemory::Memcpy(ResultAttributes,Attributes,Mesh->GetNumFaces() * sizeof(uint32));
		ResultAttributes += Mesh->GetNumFaces();

		Mesh->UnlockIndexBuffer();
		Mesh->UnlockVertexBuffer();
		Mesh->UnlockAttributeBuffer();
	}

	OutMesh->UnlockIndexBuffer();
	OutMesh->UnlockVertexBuffer();
	OutMesh->UnlockAttributeBuffer();
}
예제 #8
0
void Terrain::buildSubGridMesh(RECT& R, VertexPNT* gridVerts)
{
	//===============================================================
	// Create the subgrid mesh.
	ID3DXMesh* subMesh = 0;
	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
	UINT numElems = 0;
	HR(VertexPNT::Decl->GetDeclaration(elems, &numElems));
	HR(D3DXCreateMesh(SubGrid::NUM_TRIS, SubGrid::NUM_VERTS, 
		D3DXMESH_MANAGED, elems, gd3dDevice, &subMesh));


	//===============================================================
	// Build Vertex Buffer.  Copy rectangle of vertices from the
	// grid into the subgrid structure.
	VertexPNT* v = 0;
	HR(subMesh->LockVertexBuffer(0, (void**)&v));
	int k = 0;
	for(int i = R.top; i <= R.bottom; ++i)
	{
		for(int j = R.left; j <= R.right; ++j)
		{
			v[k++] = gridVerts[i*mVertCols+j];
		}
	}

	//===============================================================
	// Compute the bounding box before unlocking the vertex buffer.
	AABB bndBox;
	HR(D3DXComputeBoundingBox((D3DXVECTOR3*)v, subMesh->GetNumVertices(), 
		sizeof(VertexPNT), &bndBox.minPt, &bndBox.maxPt));

	HR(subMesh->UnlockVertexBuffer());


	//===============================================================
	// Build Index and Attribute Buffer.
	// Get indices for subgrid (we don't use the verts here--the verts
	// are given by the parameter gridVerts).
	std::vector<D3DXVECTOR3> tempVerts;
	std::vector<DWORD> tempIndices;
	GenTriGrid(SubGrid::NUM_ROWS, SubGrid::NUM_COLS, mDX, mDZ, 
		D3DXVECTOR3(0.0f, 0.0f, 0.0f), tempVerts, tempIndices);

	WORD* indices  = 0;
	DWORD* attBuff = 0;
	HR(subMesh->LockIndexBuffer(0, (void**)&indices));
	HR(subMesh->LockAttributeBuffer(0, &attBuff));
	for(int i = 0; i < SubGrid::NUM_TRIS; ++i)
	{
		indices[i*3+0] = (WORD)tempIndices[i*3+0];
		indices[i*3+1] = (WORD)tempIndices[i*3+1];
		indices[i*3+2] = (WORD)tempIndices[i*3+2];

		attBuff[i] = 0; // All in subset 0.
	}
	HR(subMesh->UnlockIndexBuffer());
	HR(subMesh->UnlockAttributeBuffer());


	//===============================================================
	// Optimize for the vertex cache and build attribute table.
	DWORD* adj = new DWORD[subMesh->GetNumFaces()*3];
	HR(subMesh->GenerateAdjacency(EPSILON, adj));
	HR(subMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE|D3DXMESHOPT_ATTRSORT,
		adj, 0, 0, 0));
	delete[] adj;

	
	//===============================================================
	// Save the mesh and bounding box.
	mSubGridMeshes.push_back(subMesh);
	mSubGridBndBoxes.push_back(bndBox);
}
예제 #9
0
void Terrain::buildGeometry()
{
	//===============================================================
	// Create one large mesh for the grid in system memory.

	DWORD numTris  = (mVertRows-1)*(mVertCols-1)*2;
	DWORD numVerts = mVertRows*mVertCols;

	ID3DXMesh* mesh = 0;
	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
	UINT numElems = 0;
	HR(VertexPNT::Decl->GetDeclaration(elems, &numElems));
	HR(D3DXCreateMesh(numTris, numVerts, 
		D3DXMESH_SYSTEMMEM|D3DXMESH_32BIT, elems, gd3dDevice, &mesh));


	//===============================================================
	// Write the grid vertices and triangles to the mesh.

	VertexPNT* v = 0;
	HR(mesh->LockVertexBuffer(0, (void**)&v));
	
	std::vector<D3DXVECTOR3> verts;
	std::vector<DWORD> indices;
	GenTriGrid(mVertRows, mVertCols, mDX, mDZ, D3DXVECTOR3(0.0f, 0.0f, 0.0f), verts, indices);

	float w = mWidth;
	float d = mDepth;
	for(UINT i = 0; i < mesh->GetNumVertices(); ++i)
	{
		// We store the grid vertices in a linear array, but we can
		// convert the linear array index to an (r, c) matrix index.
		int r = i / mVertCols;
		int c = i % mVertCols;

		v[i].pos   = verts[i];
		v[i].pos.y = mHeightmap(r, c);

		v[i].tex0.x = (v[i].pos.x + (0.5f*w)) / w;
		v[i].tex0.y = (v[i].pos.z - (0.5f*d)) / -d;
	}

	// Write triangle data so we can compute normals.

	DWORD* indexBuffPtr = 0;
	HR(mesh->LockIndexBuffer(0, (void**)&indexBuffPtr));
	for(UINT i = 0; i < mesh->GetNumFaces(); ++i)
	{
		indexBuffPtr[i*3+0] = indices[i*3+0];
		indexBuffPtr[i*3+1] = indices[i*3+1];
		indexBuffPtr[i*3+2] = indices[i*3+2];
	}
	HR(mesh->UnlockIndexBuffer());

	// Compute Vertex Normals.
	HR(D3DXComputeNormals(mesh, 0));

	
	//===============================================================
	// Now break the grid up into subgrid meshes.

	// Find out the number of subgrids we'll have.  For example, if
	// m = 513, n = 257, SUBGRID_VERT_ROWS = SUBGRID_VERT_COLS = 33,
	// then subGridRows = 512/32 = 16 and sibGridCols = 256/32 = 8.
	int subGridRows = (mVertRows-1) / (SubGrid::NUM_ROWS-1);
	int subGridCols = (mVertCols-1) / (SubGrid::NUM_COLS-1);

	for(int r = 0; r < subGridRows; ++r)
	{
		for(int c = 0; c < subGridCols; ++c)
		{
			// Rectangle that indicates (via matrix indices ij) the
			// portion of global grid vertices to use for this subgrid.
			RECT R = 
			{
					c * (SubGrid::NUM_COLS-1),
					r * (SubGrid::NUM_ROWS-1),
				(c+1) * (SubGrid::NUM_COLS-1),
				(r+1) * (SubGrid::NUM_ROWS-1)
			};

			buildSubGridMesh(R, v); 
		}
	}

	HR(mesh->UnlockVertexBuffer());

	ReleaseCOM(mesh); // Done with global mesh.
}
예제 #10
0
void optimizePhysXMesh(int flag, IDirect3DDevice9* D3DDevice, float epsilon, std::vector<physx::PxVec3>& pxVertices, oiram::IndexBuffer& indexBuffer)
{
	assert(D3DDevice);

	D3DVERTEXELEMENT9 szDecl[] = {
		{0,		0,		D3DDECLTYPE_FLOAT3,		D3DDECLMETHOD_DEFAULT,	D3DDECLUSAGE_POSITION,	0},
		{0xFF,	0,		D3DDECLTYPE_UNUSED,		0,						0,						0}
	};

	// 创建D3D MESH
	LPD3DXMESH pMesh = 0;
	DWORD options = D3DXMESH_SYSTEMMEM | D3DXMESH_DYNAMIC;
	if (indexBuffer.use32BitIndices)
		options |= D3DXMESH_32BIT;
	DWORD numVertices = static_cast<DWORD>(pxVertices.size()), numFaces = numVertices / 3;
	HRESULT hr = D3DXCreateMesh(numFaces, numVertices, options, szDecl, D3DDevice, &pMesh);
	if (SUCCEEDED(hr))
	{
		LPVOID pData = nullptr;
		// 填充Index Buffer
		if (SUCCEEDED(pMesh->LockIndexBuffer(D3DLOCK_DISCARD, &pData)))
		{
			if (indexBuffer.use32BitIndices)
				memcpy(pData, indexBuffer.uiIndexBuffer.data(), indexBuffer.uiIndexBuffer.size() * sizeof(physx::PxU32));
			else
				memcpy(pData, indexBuffer.usIndexBuffer.data(), indexBuffer.usIndexBuffer.size() * sizeof(physx::PxU16));

			pMesh->UnlockIndexBuffer();
		}

		// 填充Vertex Buffer
		if (SUCCEEDED(pMesh->LockVertexBuffer(D3DLOCK_DISCARD, &pData)))
		{
			memcpy(pData, pxVertices.data(), pxVertices.size() * sizeof(physx::PxVec3));
			pMesh->UnlockVertexBuffer();
		}

		// 进行Mesh优化
		DWORD dwFaces = pMesh->GetNumFaces();
		std::vector<DWORD> szAdjacencies(dwFaces * 3);
		DWORD* pAdjacency = &szAdjacencies[0];
		pMesh->GenerateAdjacency(epsilon, pAdjacency);
		// 清理mesh
		hr = D3DXCleanMesh(D3DXCLEAN_SIMPLIFICATION, pMesh, pAdjacency, &pMesh, pAdjacency, NULL);
		if (SUCCEEDED(hr))
		{
			// 去除mesh中重复的顶点
			hr = D3DXWeldVertices(pMesh, D3DXWELDEPSILONS_WELDALL, NULL, pAdjacency, pAdjacency, NULL, NULL);
			if (SUCCEEDED(hr))
			{
				// 将优化后的数据写回mesh data
				DWORD numIndices = pMesh->GetNumFaces() * 3;
				indexBuffer.use32BitIndices = numIndices > 65535;
				if (indexBuffer.use32BitIndices)
					indexBuffer.uiIndexBuffer.resize(numIndices);
				else
					indexBuffer.usIndexBuffer.resize(numIndices);

				// 取出Index Buffer
				if (SUCCEEDED(pMesh->LockIndexBuffer(D3DLOCK_READONLY | D3DLOCK_DISCARD, &pData)))
				{
					if (indexBuffer.use32BitIndices)
						memcpy(indexBuffer.uiIndexBuffer.data(), pData, indexBuffer.uiIndexBuffer.size() * sizeof(physx::PxU32));
					else
						memcpy(indexBuffer.usIndexBuffer.data(), pData, indexBuffer.usIndexBuffer.size() * sizeof(physx::PxU16));

					pMesh->UnlockIndexBuffer();
				}

				// 取出Vertex Buffer
				DWORD dwVertices = pMesh->GetNumVertices();
				pxVertices.resize(dwVertices);

				if (SUCCEEDED(pMesh->LockVertexBuffer(D3DLOCK_READONLY | D3DLOCK_DISCARD, &pData)))
				{
					memcpy(pxVertices.data(), pData, pxVertices.size() * sizeof(physx::PxVec3));
					pMesh->UnlockVertexBuffer();
				}
			}
		}

		pMesh->Release();
	}
}
예제 #11
0
void Model::CreateFromSDKMeshFile(ID3D11Device* device, LPCWSTR fileName)
{
    _ASSERT(FileExists(fileName));

    // Use the SDKMesh class to load in the data
    SDKMesh sdkMesh;
    sdkMesh.Create(fileName);

    wstring directory = GetDirectoryFromFileName(fileName);

    // Make materials
    UINT numMaterials = sdkMesh.GetNumMaterials();
    for (UINT i = 0; i < numMaterials; ++i)
    {
        MeshMaterial material;
        SDKMESH_MATERIAL* mat = sdkMesh.GetMaterial(i);
        memcpy(&material.AmbientAlbedo, &mat->Ambient, sizeof(D3DXVECTOR4));
        memcpy(&material.DiffuseAlbedo, &mat->Diffuse, sizeof(D3DXVECTOR4));
        memcpy(&material.SpecularAlbedo, &mat->Specular, sizeof(D3DXVECTOR4));
        memcpy(&material.Emissive, &mat->Emissive, sizeof(D3DXVECTOR4));
        material.Alpha = mat->Diffuse.w;
        material.SpecularPower = mat->Power;
        material.DiffuseMapName = AnsiToWString(mat->DiffuseTexture);
        material.NormalMapName = AnsiToWString(mat->NormalTexture);

        LoadMaterialResources(material, directory, device);

        meshMaterials.push_back(material);
    }

    // Make a D3D9 device
    IDirect3DDevice9Ptr d3d9Device = CreateD3D9Device();

    UINT numMeshes = sdkMesh.GetNumMeshes();
    for (UINT meshIdx = 0; meshIdx < numMeshes; ++meshIdx)
    {
        // Figure out the index type
        UINT ops = D3DXMESH_MANAGED;
        UINT indexSize = 2;
        Mesh::IndexType indexType = Mesh::Index16Bit;
        if (sdkMesh.GetIndexType(meshIdx) == IT_32BIT)
        {
            ops |= D3DXMESH_32BIT;
            indexSize = 4;
            indexType = Mesh::Index32Bit;
        }

        // Make a D3DX mesh
        ID3DXMesh* d3dxMesh = NULL;
        UINT numPrims = static_cast<UINT>(sdkMesh.GetNumIndices(meshIdx) / 3);
        UINT numVerts = static_cast<UINT>(sdkMesh.GetNumVertices(meshIdx, 0));
        UINT vbIndex = sdkMesh.GetMesh(meshIdx)->VertexBuffers[0];
        UINT ibIndex = sdkMesh.GetMesh(meshIdx)->IndexBuffer;
        const D3DVERTEXELEMENT9* vbElements = sdkMesh.VBElements(vbIndex);
        DXCall(D3DXCreateMesh(numPrims, numVerts, ops, vbElements, d3d9Device, &d3dxMesh));
        IUnknownReleaser<ID3DXMesh> meshReleaser(d3dxMesh);

        // Copy in vertex data
        BYTE* verts = NULL;
        BYTE* srcVerts = reinterpret_cast<BYTE*>(sdkMesh.GetRawVerticesAt(vbIndex));
        UINT vbStride = sdkMesh.GetVertexStride(meshIdx, 0);
        UINT declStride = D3DXGetDeclVertexSize(vbElements, 0);
        DXCall(d3dxMesh->LockVertexBuffer(0, reinterpret_cast<void**>(&verts)));
        for (UINT vertIdx = 0; vertIdx < numVerts; ++vertIdx)
        {
            memcpy(verts, srcVerts, declStride);
            verts += declStride;
            srcVerts += vbStride;
        }
        DXCall(d3dxMesh->UnlockVertexBuffer());

        // Copy in index data
        void* indices = NULL;
        void* srcIndices = sdkMesh.GetRawIndicesAt(ibIndex);
        DXCall(d3dxMesh->LockIndexBuffer(0, &indices));
        memcpy(indices, srcIndices, numPrims * 3 * indexSize);
        DXCall(d3dxMesh->UnlockIndexBuffer());

        // Set up the attribute table
        DWORD* attributeBuffer = NULL;
        DXCall(d3dxMesh->LockAttributeBuffer(0, &attributeBuffer));

        UINT numSubsets = sdkMesh.GetNumSubsets(meshIdx);
        D3DXATTRIBUTERANGE* attributes = new D3DXATTRIBUTERANGE[numSubsets];
        ArrayDeleter<D3DXATTRIBUTERANGE> attributeDeleter(attributes);
        for (UINT i = 0; i < numSubsets; ++i)
        {
            SDKMESH_SUBSET* subset = sdkMesh.GetSubset(meshIdx, i);
            attributes[i].AttribId = subset->MaterialID;
            attributes[i].FaceStart = static_cast<DWORD>(subset->IndexStart / 3);
            attributes[i].FaceCount = static_cast<DWORD>(subset->IndexCount / 3);
            attributes[i].VertexStart = static_cast<DWORD>(subset->VertexStart);
            // attributes[i].VertexCount = static_cast<DWORD>(subset->VertexCount);
            attributes[i].VertexCount = numVerts;

            for (UINT faceIdx = attributes[i].FaceStart; faceIdx < attributes[i].FaceStart + attributes[i].FaceCount; ++faceIdx)
                attributeBuffer[faceIdx] = subset->MaterialID;
        }

        DXCall(d3dxMesh->UnlockAttributeBuffer());

        d3dxMesh->SetAttributeTable(attributes, numSubsets);

        // Generate initial adjacency
        vector<DWORD> initialAdjacency;
        initialAdjacency.resize(d3dxMesh->GetNumFaces() * 3);
        DXCall(d3dxMesh->GenerateAdjacency(0.0001f, &initialAdjacency[0]));

        // Make the mesh
        Mesh mesh;
        mesh.CreateFromD3DXMesh(directory, device, d3d9Device, d3dxMesh, false, false, &initialAdjacency[0], indexType);
        meshes.push_back(mesh);
    }
}
예제 #12
0
void PropsDemo::buildGrass()
{
	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
	UINT numElems = 0;
	HR(GrassVertex::Decl->GetDeclaration(elems, &numElems));

	HR(D3DXCreateMesh(NUM_GRASS_BLOCKS*2, NUM_GRASS_BLOCKS*4, D3DXMESH_MANAGED, 
		elems, gd3dDevice, &mGrassMesh));

	GrassVertex* v = 0;
	WORD* k = 0;
	HR(mGrassMesh->LockVertexBuffer(0, (void**)&v));
	HR(mGrassMesh->LockIndexBuffer(0, (void**)&k));

	int indexOffset = 0;

	// Scale down the region in which we generate grass.
	int w = (int)(mTerrain->getWidth() * 0.15f);
	int d = (int)(mTerrain->getDepth() * 0.15f);

	// Randomly generate a grass block (three intersecting quads) around the 
	// terrain in the height range [35, 50] (similar to the trees).
	for(int i = 0; i < NUM_GRASS_BLOCKS; ++i)
	{
		//============================================
		// Construct vertices.

		// Generate random position in region.  Note that we also shift
		// this region to place it in the world.
		float x = (float)((rand() % w) - (w*0.5f)) - 30.0f;
		float z = (float)((rand() % d) - (d*0.5f)) - 20.0f;
		float y = mTerrain->getHeight(x, z); 

		// Only generate grass blocks in this height range.  If the height
		// is outside this range, generate a new random position and 
		// try again.
		if(y < 37.0f || y > 40.0f)
		{
			--i; // We are trying again, so decrement back the index.
			continue;
		}

		float sx = GetRandomFloat(0.75f, 1.25f); 
		float sy = GetRandomFloat(0.75f, 1.25f);
		float sz = GetRandomFloat(0.75f, 1.25f);
		D3DXVECTOR3 pos(x, y, z);
		D3DXVECTOR3 scale(sx, sy, sz);

		buildGrassFin(v, k, indexOffset, pos, scale);
		v += 4;
		k += 6;
	}

	HR(mGrassMesh->UnlockVertexBuffer());
	HR(mGrassMesh->UnlockIndexBuffer());


	// Fill in the attribute buffer (everything in subset 0)
	DWORD* attributeBufferPtr = 0;
	HR(mGrassMesh->LockAttributeBuffer(0, &attributeBufferPtr));
	for(UINT i = 0; i < mGrassMesh->GetNumFaces(); ++i)
		attributeBufferPtr[i] = 0;
	HR(mGrassMesh->UnlockAttributeBuffer());

	DWORD* adj = new DWORD[mGrassMesh->GetNumFaces()*3];
	HR(mGrassMesh->GenerateAdjacency(EPSILON, adj));
	HR(mGrassMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT|D3DXMESHOPT_VERTEXCACHE,
		adj, 0, 0, 0));

	delete [] adj;
}