Esempio n. 1
0
HRESULT D3DXMeshTransformation( LPD3DXMESH pMesh, const D3DXMATRIX* pMatrix
							   , VisitorForD3DXVECTOR3* pPointFilter)
{
	KG_PROCESS_ERROR(NULL != pMesh && NULL != pMatrix);

	{
		DWORD fvf = pMesh->GetFVF();
		KG_PROCESS_ERROR(fvf | D3DFVF_XYZ);

		DWORD dwNumBytePerVertex = pMesh->GetNumBytesPerVertex();
		_ASSERTE(dwNumBytePerVertex >= sizeof(D3DXVECTOR3));

		DWORD dwNumVertex = pMesh->GetNumVertices();

		BYTE* pBufferStart = NULL;
		_ASSERTE(sizeof(BYTE) == 1);
		

		if(NULL == pPointFilter)
		{
			HRESULT hr = pMesh->LockVertexBuffer(0, (LPVOID*)&pBufferStart);
			KG_COM_PROCESS_ERROR(hr);
			D3DXVec3TransformCoordArray((D3DXVECTOR3*)(pBufferStart), dwNumBytePerVertex
				, (D3DXVECTOR3*)pBufferStart, dwNumBytePerVertex, pMatrix, dwNumVertex);
			pMesh->UnlockVertexBuffer();
		}
		else
		{
			//加了Filter之后性能下降是当然的,但是这不是给实时用的,所以没有关系,控制
			//调用次数和调用时机就好了
			D3DXMeshVertexEnumer vertexEnumer;
			HRESULT hr = D3DXMeshCreateVertexEnumer(pMesh, vertexEnumer);
			KG_COM_PROCESS_ERROR(hr);
			_ASSERTE(vertexEnumer.IsValid());
			HRESULT hrForVisitor = E_FAIL;
			for (UINT i = 0; i < vertexEnumer.GetVertexCount(); ++i)
			{
				const D3DXVECTOR3& vTemp = vertexEnumer.GetPos(i);
				hrForVisitor = pPointFilter->Accept(vTemp);
				if (FAILED(hr))
				{
					continue;
				}

				D3DXVECTOR3 vTransformed;
				D3DXVec3TransformCoord(&vTransformed, &vTemp, pMatrix);
				vertexEnumer.SetPos(i, vTransformed);
			}
		}

		
	}		

	return S_OK;
Exit0:
	return E_FAIL;
}
Esempio n. 2
0
LPD3DXMESH SkyBox::CreateMappedSphere(float fRad, UINT slices, UINT stacks)
{
	// create the sphere
	LPD3DXMESH mesh;
	if (FAILED(D3DXCreateSphere(GameManager::GetDevice( ), fRad, slices, stacks, &mesh, NULL)))
		return NULL;

	// create a copy of the mesh with texture coordinates,
	// since the D3DX function doesn't include them
	LPD3DXMESH texMesh;
	if (FAILED(mesh->CloneMeshFVF(D3DXMESH_SYSTEMMEM, FVF_PositionNormalTexture::FVF, GameManager::GetDevice( ), &texMesh)))
		return mesh;	// failed, return un-textured mesh
	
	mesh->Release( );		// finished with the original mesh, release it


	// lock the vertex buffer
	FVF_PositionNormalTexture* pVerts;
	//if (SUCCEEDED(texMesh->LockVertexBuffer(0, (BYTE **)&pVerts)))
	if (SUCCEEDED(texMesh->LockVertexBuffer(0, (LPVOID*)&pVerts)))
	{
		int numVerts = texMesh->GetNumVertices( );		// get vertex count

		// loop through the vertices
		for (int i = 0; i < numVerts; i++)
		{
			// calculate texture coordinates
			pVerts->tex.x = asinf(pVerts->normal.x) / D3DX_PI + 0.5f;
			pVerts->tex.y = asinf(pVerts->normal.y) / D3DX_PI + 0.5f;

			//pVerts->tex.x = 0.5f - (atan2f(pVerts->normal.z, pVerts->normal.x) / (2 * D3DX_PI));
			//pVerts->tex.y = 0.5f - asinf(pVerts->normal.y) / (D3DX_PI);
			
			//pVerts->tex.y = pVerts->normal.y * 0.5 + 0.5;

			//if (pVerts->tex.x <(FLOAT)0.9) pVerts->tex.x = (FLOAT)0.0;


			//pVerts->tex.x = pVerts->pos.x / sqrtf((pVerts->pos.x * pVerts->pos.x) + (pVerts->pos.y * pVerts->pos.x) + (pVerts->pos.z * pVerts->pos.z));
			//pVerts->tex.y = pVerts->pos.y / sqrtf((pVerts->pos.x * pVerts->pos.x) + (pVerts->pos.y * pVerts->pos.x) + (pVerts->pos.z * pVerts->pos.z));

			//float theta = asinf(pVerts->normal.z);
			//float phi = atan2(pVerts->normal.y, pVerts->normal.x);
			//
			//pVerts->tex = D3DXVECTOR2(phi / 2 / 3.14159265, theta /  3.14159265);

			// go to next vertex
			pVerts++; 

		}
	
		texMesh->UnlockVertexBuffer( );		// unlock the vertex buffer
	}

	// return pointer to caller
	return texMesh;
}
Esempio n. 3
0
LPD3DXMESH CWall::convertMesh(IDirect3DDevice9* pDevice, LPD3DXMESH& mesh){

	D3DVERTEXELEMENT9 decl[] =
	{
		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
		{ 0, sizeof(D3DXVECTOR3), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 },
		{ 0, sizeof(D3DXVECTOR3) * 2, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
		D3DDECL_END()//will be declared on 
	};

	LPD3DXMESH newMesh = nullptr;
	VERTEX* pVerts;
	HRESULT result = mesh->CloneMesh(D3DXMESH_SYSTEMMEM, decl, pDevice, &newMesh);

	if (FAILED(result)) return nullptr;
	float u = 0;
	float v = 0;
	bool reverse = false;
	if (SUCCEEDED(newMesh->LockVertexBuffer(0, (LPVOID*)&pVerts))){
		int numVerts = newMesh->GetNumVertices();
		for (int i = 0; i < numVerts; i++){
			pVerts->tu = u;
			pVerts->tv = v;
		
			if (u == 0 && v==0){
				if (reverse)
					u++;
				else
					v++;
				
			}
			else if (v == 1 && u == 0){
				u++;
			
			}
			else if (v == 0 && u == 1){
				v++;
			
			}
			else{
				if (reverse)
					reverse = false;
				else reverse = true;
				u = 0;
				v = 0;
			}
			pVerts++;
		}
		newMesh->UnlockVertexBuffer();
		//temporary uv generator
		return newMesh;
	}
	else{
		return nullptr;
	}
}
LPD3DXMESH Renderer::CreateD3DXTextMesh( const char* pString, bool bCentered )
{
	HRESULT hr;
	LPD3DXMESH pMeshNew = NULL;

	HDC hdc = CreateCompatibleDC( NULL );
	if( hdc == NULL )
		return NULL;

	HFONT newfont=CreateFont(10,         //Height
		0,          //Width
		0,          //Escapement
		0,          //Orientation
		FW_NORMAL,  //Weight
		false,      //Italic
		false,      //Underline
		false,      //Strikeout
		DEFAULT_CHARSET,//Charset 
		OUT_DEFAULT_PRECIS,  //Output Precision
		CLIP_DEFAULT_PRECIS, //Clipping Precision
		DEFAULT_QUALITY,     //Quality
		DEFAULT_PITCH|FF_DONTCARE, //Pitch and Family
		"Arial");



	HFONT hFontOld;
	hFontOld = ( HFONT )SelectObject( hdc, newfont );
	hr = D3DXCreateText( m_pD3DDevice, hdc, pString, 0.001f, 0.2f, &pMeshNew, NULL, NULL );
	SelectObject( hdc, hFontOld );
	DeleteDC( hdc );

	if( SUCCEEDED( hr ) )
	{
		if( bCentered )
		{
			// Center text
			D3DXVECTOR3 vMin, vMax;

			PosNormalVertex* pVertices;
			pMeshNew->LockVertexBuffer( 0, reinterpret_cast<VOID**>(&pVertices));
			D3DXComputeBoundingBox( (D3DXVECTOR3*)pVertices, pMeshNew->GetNumVertices(), sizeof ( PosNormalVertex ), &vMin, &vMax );

			D3DXVECTOR3 vOffset;
			D3DXVec3Subtract( &vOffset, &vMax, &vMin );
			D3DXVec3Scale( &vOffset, &vOffset, 0.5f );
			for ( unsigned int i = 0; i < pMeshNew->GetNumVertices(); i++)
			{
				D3DXVec3Subtract( &pVertices[i].Coord, &pVertices[i].Coord, &vOffset );
			}
			pMeshNew->UnlockVertexBuffer();
		}
	}

	return pMeshNew;
}
Esempio n. 5
0
bool Floor::ComputeBoundingBox()
{
	if( m_computedBoundingBox) return true;
	BYTE* pVertices = NULL;
	LPD3DXMESH mesh = m_mesh->GetD3DMesh();
	HRESULT hr = mesh->LockVertexBuffer(D3DLOCK_READONLY, (LPVOID*)&pVertices);
	if(FAILED(hr))
		return false;
	D3DXComputeBoundingBox((D3DXVECTOR3*)pVertices, mesh->GetNumVertices(), mesh->GetNumBytesPerVertex(), &m_bottomLeft, &m_topRight);
	mesh->UnlockVertexBuffer();
	m_computedBoundingBox = true;
	return true;
}
Esempio n. 6
0
//------------------------------------------------------
//		DirectXメッシュの作成
//------------------------------------------------------
LPD3DXMESH	iex3DObj::CreateMesh( LPIEMFILE lpIem )
{
	LPD3DXMESH	lpMesh;
	u8			*pVertex, *pFace;
	u32			*pData;
	
	if( lpIem->version < 4 )
	{
		u32	Declaration = D3DFVF_MESHVERTEX;
		//	メッシュ作成
		D3DXCreateMeshFVF( lpIem->NumFace, lpIem->NumVertex, D3DXMESH_MANAGED, Declaration, tdnSystem::GetDevice(), &lpMesh );
		//	頂点設定
		lpMesh->LockVertexBuffer( 0, (void**)&pVertex );
		CopyMemory( pVertex, lpIem->lpVertex, sizeof(MESHVERTEX)*lpIem->NumVertex );
	} else {
		u32	Declaration = D3DFVF_MESHVERTEX2;
		//	メッシュ作成
		D3DXCreateMeshFVF( lpIem->NumFace, lpIem->NumVertex, D3DXMESH_MANAGED, Declaration, tdnSystem::GetDevice(), &lpMesh );
		//	頂点設定
		lpMesh->LockVertexBuffer( 0, (void**)&pVertex );
		CopyMemory( pVertex, lpIem->lpVertex, sizeof(MESHVERTEX2)*lpIem->NumVertex );
	}

	lpMesh->UnlockVertexBuffer();


	//	面設定
	lpMesh->LockIndexBuffer( 0, (void**)&pFace );
	CopyMemory( pFace, lpIem->lpFace, sizeof(u16)*lpIem->NumFace*3 );
	lpMesh->UnlockIndexBuffer();

	//	属性設定
	lpMesh->LockAttributeBuffer( 0, &pData );
	CopyMemory( pData, lpIem->lpAtr, sizeof(u32)*lpIem->NumFace );
	lpMesh->UnlockAttributeBuffer();

	return lpMesh;
}
Esempio n. 7
0
void cMyASELoader::LoadMesh(){
#ifdef _DEBUG
	_ASSERT(m_bLoaded && "Data Not Loaded");
#endif
	int check = 0;
	for (size_t i = 0; i < m_vecASENode.size(); i++){
		if (m_vecASENode[i].nRef != INT_MAX){
			m_vecsubSet.push_back(m_vecASENode[i].nRef);
			LPD3DXMESH pMesh = NULL;
			HRESULT hr = D3DXCreateMeshFVF(m_vecASENode[i].vecVertex.size() / 3,
				m_vecASENode[i].vecVertex.size(),
				D3DXMESH_MANAGED,
				ST_PNT_VERTEX::FVF,
				g_pD3DDevice,
				&pMesh);

			ST_PNT_VERTEX* pV = NULL;
			pMesh->LockVertexBuffer(0, (LPVOID*)&pV);
			memcpy(pV, &m_vecASENode[i].vecVertex[0], m_vecASENode[i].vecVertex.size() * sizeof(ST_PNT_VERTEX));
			pMesh->UnlockVertexBuffer();

			WORD* pI = NULL;
			pMesh->LockIndexBuffer(0, (LPVOID*)&pI);
			for (size_t j = 0; j < pMesh->GetNumVertices(); ++j)
			{
				pI[j] = j;
			}
			pMesh->UnlockIndexBuffer();

			DWORD* pA = NULL;
			pMesh->LockAttributeBuffer(0, &pA);
			for (size_t j = 0; j < pMesh->GetNumFaces(); j++){
				pA[j] = m_vecASENode[i].nRef;
			}
			pMesh->UnlockAttributeBuffer();

			std::vector<DWORD> vecAdjBuffer(m_vecASENode[i].vecVertex.size());
			pMesh->GenerateAdjacency(0.0f, &vecAdjBuffer[0]);

			pMesh->OptimizeInplace(
				D3DXMESHOPT_ATTRSORT |
				D3DXMESHOPT_COMPACT |
				D3DXMESHOPT_VERTEXCACHE,
				&vecAdjBuffer[0], 0, 0, 0);

			m_vecMeshs.push_back(pMesh);
		}
	}
	m_bMeshed = true;
}
Esempio n. 8
0
PRIVATE inline void _MDLCenterMesh(float trans[eMaxPt], LPD3DXMESH mesh)
{
	gfxVtx *pVtx;

	if(SUCCEEDED(mesh->LockVertexBuffer(0, (BYTE**)&pVtx)))
	{
		for(int i = 0; i < mesh->GetNumVertices(); i++)
		{
			pVtx[i].x -= trans[eX];
			pVtx[i].y -= trans[eY];
			pVtx[i].z -= trans[eZ];
		}

		mesh->UnlockVertexBuffer();
	}
}
Esempio n. 9
0
HRESULT AiPathReader::CreateMesh(LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH &pMesh) {
    //Todo: ID3DXMesh::SetAttributeTable  (set materials how they are defined in the face struct)
    DWORD dwFVF = (D3DFVF_XYZ | D3DFVF_NORMAL);
    struct D3DVERTEX {
        D3DXVECTOR3 p;
        D3DXVECTOR3 n;
    };
    HRESULT r = D3DXCreateMeshFVF(3 * nodes.size(), 3 * nodes.size(), D3DXMESH_MANAGED, dwFVF, pD3DDevice, &pMesh);
    if(FAILED(r)) {
        return r;
    }
    D3DVERTEX *vertexBuffer;
    WORD *indexBuffer = nullptr;
    unsigned long *pAdjacency = new unsigned long[nodes.size() * 3];
    pMesh->LockIndexBuffer(0, reinterpret_cast<void **>(&indexBuffer));
    pMesh->LockVertexBuffer(0, reinterpret_cast<void **>(&vertexBuffer));
    for(int i = 0; i < nodes.size(); i++) {
        auto face = nodes[i];
        for(int j = 0; j < 3; j++) {
            D3DVERTEX &vert = vertexBuffer[3 * i + j];
            vert.p.x = face.triangle[j].x;
            vert.p.y = face.triangle[j].y;
            vert.p.z = face.triangle[j].z;
            indexBuffer[3 * i + j] = 3 * i + j;
            pAdjacency[3 * i + j] = (face.adjacency[j] == 0xffff) ? 0xffffffffUL : face.adjacency[j];
        }
    }
    //D3DXWeldVertices(pMesh, D3DXWELDEPSILONS_WELDALL, nullptr, pAdjacency, nullptr, nullptr, nullptr);
    //pMesh->OptimizeInplace(D3DXMESHOPT_COMPACT | D3DXMESHOPT_IGNOREVERTS | D3DXMESHOPT_STRIPREORDER, newAdjacency, pAdjacency, nullptr, nullptr);
    delete[] pAdjacency;
    HRESULT hr = D3DXComputeNormals(pMesh, nullptr);
    D3DXMATERIAL *m_pMaterials = nullptr;
    DWORD         m_dwNumMaterials = 0;
    hr = D3DXSaveMeshToX("NavMesh.x", pMesh, nullptr, m_pMaterials, nullptr, m_dwNumMaterials, D3DXF_FILEFORMAT_BINARY);
    pMesh->UnlockVertexBuffer();
    pMesh->UnlockIndexBuffer();
    return S_OK;
}
Esempio n. 10
0
HRESULT D3DXMeshCreateVertexEnumer( LPD3DXMESH pMesh, D3DXMeshVertexEnumer& enumer )
{
	_ASSERTE(! enumer.IsValid());
	ZeroMemory(&enumer, sizeof(D3DXMeshVertexEnumer));//因为外部传入的enumer是可能重用的,这里绝对要重新清空一次

	_ASSERTE(NULL != pMesh);
	KG_PROCESS_ERROR(NULL != pMesh);
	{
		BOOL bIsAcceptableMesh = pMesh->GetFVF() & D3DFVF_XYZ;

		KG_PROCESS_ERROR(bIsAcceptableMesh && _T("不支持没有XYZ标志的Mesh,那样不能保证每个节点开头是顶点"));

		HRESULT hr = pMesh->LockVertexBuffer(0, reinterpret_cast<LPVOID*>(&enumer.m_pBuffer));
		KG_COM_PROCESS_ERROR(hr);
		_ASSERTE(1 == sizeof(BYTE));
		enumer.m_pMesh = pMesh;
		enumer.m_pMesh->AddRef();
		enumer.m_dwNumBytePerVertex = pMesh->GetNumBytesPerVertex();
		enumer.m_dwNumVertexCount = pMesh->GetNumVertices();
		return S_OK;
	}
Exit0:
	return E_FAIL;
}
Esempio n. 11
0
//メッシュコンテナ描画
void Dx_Graphics3D::DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainer, LPD3DXFRAME pFrame)
{
	DxMeshContainer *mesh_container = (DxMeshContainer*)pMeshContainer;
	DxFrame *frame = (DxFrame*)pFrame;

	//
	D3DMATERIAL9 mat;
	LPDIRECT3DTEXTURE9 pTex=NULL;
	//D3DXMESHDATA内のメッシュデータを抽出
	LPD3DXMESH lpMesh = mesh_container->MeshData.pMesh;

	//スキニング情報がない場合
	if(pMeshContainer->pSkinInfo==NULL)
	{
		//デバイスにフレームのワールド行列を設置
		this->device->SetTransform( D3DTS_WORLD, &frame->CombinedTransformationMatrix);

		//メッシュ描画
		for (DWORD i=0;i<mesh_container->NumMaterials;i++)
		{
			//マテリアル情報の取得
			mat = mesh_container->pMaterials[i].MatD3D;
			//テクスチャ情報の取得
			pTex = mesh_container->ppTextures[i];

			//メッシュサブセットを描画
			this->DrawSubset(lpMesh,i,&mat,pTex);
		}
	}
	//スキニング情報がある場合
	else
	{
		D3DXMATRIX matId;
		PBYTE			pVerticesSrc;
		PBYTE			pVerticesDest;

		//ボーン数を取得
		DWORD NumBones = pMeshContainer->pSkinInfo->GetNumBones();

		for( DWORD i = 0; i < NumBones; i++ ){
			D3DXMatrixMultiply(
				&mesh_container->pBoneMatrices[i],
				&mesh_container->pBoneOffsetMatrices[i], 
				mesh_container->ppBoneMatrixPtrs[i]
			);
		}

		//ワールド行列をクリア
		D3DXMatrixIdentity(&matId);
		this->device->SetTransform(D3DTS_WORLD, &matId);

		//頂点バッファをロック
		mesh_container->lpMesh->LockVertexBuffer( D3DLOCK_READONLY, (LPVOID*)&pVerticesSrc);
		lpMesh->LockVertexBuffer( 0, (LPVOID*)&pVerticesDest);

		//スキンメッシュ作成
		mesh_container->pSkinInfo->UpdateSkinnedMesh( mesh_container->pBoneMatrices, NULL, pVerticesSrc, pVerticesDest);

		//頂点バッファのロックを解除
		mesh_container->lpMesh->UnlockVertexBuffer();
		lpMesh->UnlockVertexBuffer();

		//メッシュ描画
		for(UINT i = 0;i<mesh_container->NumAttributeGroups;i++)
		{
			//メッシュサブセットの属性IDを取得
			unsigned AttribId = mesh_container->pAttributeTable[i].AttribId;
			//マテリアル情報を取得
			mat = mesh_container->pMaterials[AttribId].MatD3D;
			//テクスチャ情報を取得
			pTex = mesh_container->ppTextures[AttribId];

			//メッシュのサブセットを描画
			this->DrawSubset(lpMesh,AttribId,&mat,pTex);
		}
	}
}
/**
* 
* PRECONDITION: parameter EFacePosition _eSide must be either FACE_TOP, or FACE_BOTTOM. 
* 
* @author Rebeccah Cox 
* @param EFacePosition _eSide - the side the flag is on, either top or bottom.
* @param int32 _iX - the position along the X axis.
* @param int32 _iY - the position along the Z axis (looks like the y axis when 
* 						looking at the flag plate). 
* @param ETeam _eTeam - team the flagplate belongs to.
* @param uint32 _uiTextureID
* @param uint32 _uiModelID
* @return bool - returns true if the initialisation was successful.
*/
bool
CFlagPlate::Initialise(EFacePosition _eSide, int32 _iX, int32 _iY, ETeam _eTeam, uint32 _uiModelID, uint32 _uiTextureID)
{
	// Set the position and side member variables in CTile.
	m_eFace = _eSide;
	m_iX = _iX;
	m_iY = _iY;

	m_vec3Position = g_atUpRightDirectionVecs[_eSide].vec3Up * 22.5f;

	m_vec3Position += g_atUpRightDirectionVecs[_eSide].vec3Right * ((_iX * 3.0f) - 21.0f);

	m_vec3Position -= g_atUpRightDirectionVecs[_eSide].vec3Direction * ((_iY * 3.0f) - 21.0f);

	// Set the world matrix using the vectors.
	m_matWorld._11 = g_atUpRightDirectionVecs[_eSide].vec3Right.x;
	m_matWorld._21 = g_atUpRightDirectionVecs[_eSide].vec3Up.x;
	m_matWorld._31 = g_atUpRightDirectionVecs[_eSide].vec3Direction.x;

	m_matWorld._12 = g_atUpRightDirectionVecs[_eSide].vec3Right.y;
	m_matWorld._22 = g_atUpRightDirectionVecs[_eSide].vec3Up.y;
	m_matWorld._32 = g_atUpRightDirectionVecs[_eSide].vec3Direction.y;

	m_matWorld._13 = g_atUpRightDirectionVecs[_eSide].vec3Right.z; 
	m_matWorld._23 = g_atUpRightDirectionVecs[_eSide].vec3Up.z; 
	m_matWorld._33 = g_atUpRightDirectionVecs[_eSide].vec3Direction.z;

	m_matWorld._41 = m_vec3Position.x;
	m_matWorld._42 = m_vec3Position.y;
	m_matWorld._43 = m_vec3Position.z;

	m_bTraversable = true;

	m_iModelID = _uiModelID;
	m_iTextureID = _uiTextureID;

	/*// Set the model ID
	if(BAD_ID == _uiModelID)
	{
		m_iModelID = CModelManager::GetInstance().CreateModel("../../models/tile_flagplate.x");
	}

	// Set the texture ID
	if(BAD_ID == _uiTextureID)
	{
		if(TEAM_GREEN == _eTeam)
		{
			m_iTextureID = CTextureManager::GetInstance().CreateTexture("../../textures/tile_flagTile_green.png");
		}
		else
		{
			m_iTextureID = CTextureManager::GetInstance().CreateTexture("../../textures/tile_flagTile_purple.png");
		}
	}*/

	D3DXVECTOR3* pFirstVertex = 0;

	LPD3DXMESH pMesh = CModelManager::GetInstance().GetModel(m_iModelID)->GetModel();

	pMesh->LockVertexBuffer(0, (void**)&pFirstVertex);

	D3DXComputeBoundingBox(pFirstVertex, 
							pMesh->GetNumVertices(),
							pMesh->GetNumBytesPerVertex(), 
							&m_tOBB.m_vec3Min, &m_tOBB.m_vec3Max);

	pMesh->UnlockVertexBuffer();

	CEntity::Initialise();

	return (true);
}
Esempio n. 13
0
int main(int argc, char* argv[])
{
	if (argc < 3)
	{
		puts("Usage: MeshConv meshfile rdffile");
		return 1;
	}

	// Initialize DirectDraw
	pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if (pD3D == NULL)
	{
		puts("Cannot init D3D");
		return 1;
	}

	MeshMender mender;
	std::vector<MeshMender::Vertex> MendVerts;
	std::vector<unsigned int> MendIndices;
	std::vector<unsigned int> mappingNewToOld;

	HRESULT hr;
	D3DDISPLAYMODE dispMode;
	D3DPRESENT_PARAMETERS presentParams;

	pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispMode);

	ZeroMemory(&presentParams, sizeof(presentParams));
	presentParams.Windowed = TRUE;
	presentParams.hDeviceWindow = GetConsoleWindow();
	presentParams.SwapEffect = D3DSWAPEFFECT_COPY;
	presentParams.BackBufferWidth = 8;
	presentParams.BackBufferHeight = 8;
	presentParams.BackBufferFormat = dispMode.Format;

	hr = pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParams, &pD3DDevice);
	if (FAILED(hr))
	{
		printf("Cannot init D3D device: %08x\n", hr);
		pD3D->Release();
		return 1;
	}

	printf("Loading mesh %s: ", argv[1]);

	LPD3DXBUFFER pAdjacency, pMaterials, pEffects;
	DWORD n;
	LPD3DXMESH pLoadMesh;
	hr = D3DXLoadMeshFromX(argv[1], D3DXMESH_SYSTEMMEM, pD3DDevice, &pAdjacency, &pMaterials, &pEffects, &n, &pLoadMesh);
	if (FAILED(hr))
	{
		printf("ERROR: %08x\n", hr);
		goto mesherror;
	}
	pEffects->Release();
	pMaterials->Release();
	printf("%d faces, %d verts\n", pLoadMesh->GetNumFaces(), pLoadMesh->GetNumVertices());

	LPD3DXMESH pMesh;
	if (pLoadMesh->GetFVF() != MESHFVF)
	{
		hr = pLoadMesh->CloneMeshFVF(D3DXMESH_SYSTEMMEM, MESHFVF, pD3DDevice, &pMesh);
		pLoadMesh->Release();
		if (FAILED(hr))
		{
			printf("CloneMesh error: %08x\n", hr);
			goto mesherror;
		}
	}
	else
		pMesh = pLoadMesh;

	printf("Welding verts: ");

	DWORD* pAdj = new DWORD[pAdjacency->GetBufferSize() / 4];

	D3DXWELDEPSILONS Eps;
	memset(&Eps, 0, sizeof(Eps));
	hr = D3DXWeldVertices(pMesh, D3DXWELDEPSILONS_WELDPARTIALMATCHES, &Eps, (DWORD*)pAdjacency->GetBufferPointer(), pAdj, NULL, NULL);
	if (FAILED(hr))
	{
		printf("ERROR: %08x\n", hr);
		goto mesherror;
	}
	
	hr = pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, pAdj, (DWORD*)pAdjacency->GetBufferPointer(), NULL, NULL);
	if (FAILED(hr))
	{
		printf("ERROR: %08x\n", hr);
		goto mesherror;
	}
	
	pAdjacency->Release();
	delete [] pAdj;

	printf("%d faces, %d verts\n", pMesh->GetNumFaces(), pMesh->GetNumVertices());

	printf("Mending mesh: ");

	DWORD NumVerts = pMesh->GetNumVertices();
	DWORD NumFaces = pMesh->GetNumFaces();

	MESHVERT* MeshVert;
	pMesh->LockVertexBuffer(0, (LPVOID*)&MeshVert);

	//fill up Mend vectors with your mesh's data
	MendVerts.reserve(NumVerts);
	for(DWORD i = 0; i < NumVerts; ++i)
	{
		MeshMender::Vertex v;
		v.pos = MeshVert[i].pos;
		v.s = MeshVert[i].s;
		v.t = MeshVert[i].t;
		v.normal = MeshVert[i].norm;
		MendVerts.push_back(v);
	}
	pMesh->UnlockVertexBuffer();

	WORD* MeshIdx;
	pMesh->LockIndexBuffer(0, (LPVOID*)&MeshIdx);

	MendIndices.reserve(NumFaces * 3);
	for(DWORD i = 0; i < NumFaces * 3; ++i)
	{
		MendIndices.push_back(MeshIdx[i]);
	}
	pMesh->UnlockIndexBuffer();

	pMesh->Release();
	pMesh = 0;

	//pass it in to Mend mender to do it's stuff
	mender.Mend(MendVerts, MendIndices, mappingNewToOld, 0.9f, 0.9f, 0.9f, 1.0f, MeshMender::DONT_CALCULATE_NORMALS, MeshMender::RESPECT_SPLITS);
	
	mappingNewToOld.clear();

	printf("%d faces, %d verts\n", MendIndices.size() / 3, MendVerts.size());

	printf("Saving data: ");

	FILE* fp = fopen("meshdata.bin", "wb");
	n = MendIndices.size() / 3;
	fwrite(&n, 4, 1, fp);
	n = MendVerts.size();
	fwrite(&n, 4, 1, fp);
	fclose(fp);

	// Load existing file
	HANDLE hFile = CreateFile(argv[2], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("ERROR: %08x\n", GetLastError());
		goto mesherror;
	}
	DWORD Size = GetFileSize(hFile, 0);
	char* FileData = (char*)VirtualAlloc(0, 64*1024*1024, MEM_RESERVE, PAGE_NOACCESS);
	VirtualAlloc(FileData, Size, MEM_COMMIT, PAGE_READWRITE);
	ReadFile(hFile, FileData, Size, &n, 0);
	FileData[n] = 0;
	Size = n;

	char *p, *q;
	// Find vertex data
	p = strstr(FileData, "VertexBuffer");
	if (!p)
	{
		printf("ERROR: Invalid output file\n");
		goto mesherror;
	}
	p = strchr(p, '{');
	q = p+1;
	int depth = 1;
	do {
		if (*q == '}')
			--depth;
		else if (*q == '{')
			++depth;
		++q;
	} while (depth > 0);

	// move post-vertex data to temp buffer
	Size = (FileData + Size) - q;
	char* TempData = (char*)VirtualAlloc(0, Size, MEM_COMMIT, PAGE_READWRITE);
	memcpy(TempData, q, Size);

	// write vertex data
	strcpy(p, "{\r\n    VertexFormat {D3DVSDT_FLOAT3 D3DVSDT_NORMPACKED3 D3DVSDT_FLOAT2 D3DVSDT_NORMPACKED3 D3DVSDT_NORMPACKED3}\r\n    VertexData\r\n    {\r\n");
	p += strlen(p);

	for (std::vector<MeshMender::Vertex>::iterator i = MendVerts.begin(); i != MendVerts.end(); ++i)
	{
		VirtualAlloc(p, 500, MEM_COMMIT, PAGE_READWRITE);
		p += sprintf(p, "        %12f %12f %12f  %12f %12f %12f  %12f %12f  %12f %12f %12f  %12f %12f %12f\r\n",
			i->pos.x, i->pos.y, i->pos.z, i->normal.x, i->normal.y, i->normal.z,
			i->s, i->t,
			i->tangent.x, i->tangent.y, i->tangent.z, i->binormal.x, i->binormal.y, i->binormal.z);
	}

	strcpy(p, "    }\r\n}");
	p += strlen(p);

	VirtualAlloc(p, Size, MEM_COMMIT, PAGE_READWRITE);
	memcpy(p, TempData, Size);
	Size += p - FileData;
	VirtualFree(TempData, 0, MEM_RELEASE);

	// Find index data
	p = strstr(FileData, "IndexBuffer");
	if (!p)
	{
		printf("ERROR: Invalid output file\n");
		goto mesherror;
	}
	p = strchr(p, '{');
	q = p+1;
	depth = 1;
	do {
		if (*q == '}')
			--depth;
		else if (*q == '{')
			++depth;
		++q;
	} while (depth > 0);

	// move post-index data to temp buffer
	Size = (FileData + Size) - q;
	TempData = (char*)VirtualAlloc(0, Size, MEM_COMMIT, PAGE_READWRITE);
	memcpy(TempData, q, Size);

	// write index data
	strcpy(p, "{\r\n    IndexData\r\n    {\r\n        ");
	p += strlen(p);

	n = 0;
	for (std::vector<unsigned>::iterator i = MendIndices.begin(); i != MendIndices.end(); ++i)
	{
		VirtualAlloc(p, 20, MEM_COMMIT, PAGE_READWRITE);
		p += sprintf(p, " %5hu", *i);
		if (n++ == 2)
		{
			p += sprintf(p, "\r\n       ");
			n = 0;
		}
	}

	strcpy(p-3, "}\r\n}");
	p += strlen(p);

	VirtualAlloc(p, Size, MEM_COMMIT, PAGE_READWRITE);
	memcpy(p, TempData, Size);
	Size += p - FileData;
	VirtualFree(TempData, 0, MEM_RELEASE);

	SetFilePointer(hFile, 0, 0, FILE_BEGIN);
	WriteFile(hFile, FileData, Size, &n, 0);
	SetEndOfFile(hFile);

	CloseHandle(hFile);
	VirtualFree(FileData, 0, MEM_RELEASE);

	printf("Done\n");

	pD3D->Release();
	pD3DDevice->Release();

	return 0;

mesherror:
	pD3D->Release();
	pD3DDevice->Release();
	
	return 1;
}
Esempio n. 14
0
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;
	}
HRESULT InitGeometry( )
{
	if (FAILED(D3DXCreateBox(g_pD3DDevice, 1.f, 1.f, 1.f, &g_pMesh, NULL)))
	{
		return E_FAIL;
	}

	D3DXVECTOR3 *vertices;
	
	
	g_pMesh->LockVertexBuffer( D3DLOCK_READONLY, (void**) &vertices );
	D3DXComputeBoundingBox( vertices, g_pMesh->GetNumVertices(), g_pMesh->GetNumBytesPerVertex(), &g_MinPoint, &g_MaxPoint );
	g_pMesh->UnlockVertexBuffer();

	
	D3DXMATRIX matScale, matTrans, matRotateZ, matWorld;

	g_Box[0].BoxScaling = 1.5f;
	g_Box[0].CenterPos = D3DXVECTOR3( 0.f, 0.f, 0.f );
	g_Box[0].BoxRotateZ = 0.f;
	g_Box[0].AxisDir[0] = D3DXVECTOR3( 1, 0, 0 );
	g_Box[0].AxisDir[1] = D3DXVECTOR3( 0, 1, 0 );
	g_Box[0].AxisDir[2] = D3DXVECTOR3( 0, 0, 1 );

	for ( int i = 0; i < 3; ++i )
	{
		g_Box[0].AxisLen[i] = 0.5f;

		D3DXVec3TransformNormal( &(g_Box[0].AxisDir[i]), &(g_Box[0].AxisDir[i]), &matRotateZ );
		D3DXVec3Normalize( &( g_Box[0].AxisDir[i] ), &( g_Box[0].AxisDir[i] ) );
		g_Box[0].AxisLen[i] = g_Box[0].AxisLen[i] * g_Box[0].BoxScaling;
	}
	D3DXMatrixTranslation( &matTrans, g_Box[0].CenterPos.x, g_Box[0].CenterPos.y, g_Box[0].CenterPos.z );
	D3DXMatrixScaling( &matScale, g_Box[0].BoxScaling, g_Box[0].BoxScaling, g_Box[0].BoxScaling );
	D3DXMatrixRotationZ( &matRotateZ, g_Box[0].BoxRotateZ );

	matWorld = matRotateZ* matScale * matTrans;
	D3DXVec3TransformCoord( &g_Box[0].MinPoint, &g_MinPoint, &matWorld );
	D3DXVec3TransformCoord( &g_Box[0].MaxPoint, &g_MaxPoint, &matWorld );

	
	g_Box[1].BoxScaling = 2.f;
	g_Box[1].CenterPos = D3DXVECTOR3( 3.f, 3.f, 0.f );
	g_Box[1].BoxRotateZ = 0.f;
	g_Box[1].AxisDir[0] = D3DXVECTOR3( 1, 0, 0 );
	g_Box[1].AxisDir[1] = D3DXVECTOR3( 0, 1, 0 );
	g_Box[1].AxisDir[2] = D3DXVECTOR3( 0, 0, 1 );

	for ( int i = 0; i < 3; ++i )
	{
		g_Box[1].AxisLen[i] = 0.5f;

		D3DXVec3TransformNormal( &( g_Box[0].AxisDir[i] ), &( g_Box[1].AxisDir[i] ), &matRotateZ );
		D3DXVec3Normalize( &( g_Box[1].AxisDir[i] ), &( g_Box[1].AxisDir[i] ) );
		g_Box[1].AxisLen[i] = g_Box[1].AxisLen[i] * g_Box[1].BoxScaling;
	}

	D3DXMatrixTranslation( &matTrans, g_Box[1].CenterPos.x, g_Box[1].CenterPos.y, g_Box[1].CenterPos.z );
	D3DXMatrixScaling( &matScale, g_Box[1].BoxScaling, g_Box[1].BoxScaling, g_Box[1].BoxScaling );
	D3DXMatrixRotationZ( &matRotateZ, g_Box[1].BoxRotateZ );

	matWorld = matRotateZ* matScale * matTrans;
	D3DXVec3TransformCoord( &g_Box[1].MinPoint, &g_MinPoint, &matWorld );
	D3DXVec3TransformCoord( &g_Box[1].MaxPoint, &g_MaxPoint, &matWorld );


	return S_OK;
}
Esempio n. 16
0
HRESULT InitScene()
{
	HRESULT hr;
	
	D3DVERTEXELEMENT9 elem[] =
	{
		{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
		{ 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
		D3DDECL_END()
	};

	SetWindowText(hwnd, TITLE);

	MYVALID(D3DXLoadMeshFromX("../media/meshes/box.X", D3DXMESH_MANAGED, device, NULL, NULL, NULL, NULL, &box));
	MYVALID(D3DXLoadMeshFromX("../media/meshes/skullocc3.X", D3DXMESH_MANAGED, device, NULL, NULL, NULL, NULL, &skull));
	MYVALID(D3DXCreateTextureFromFileA(device, "../media/textures/marble.dds", &texture1));
	MYVALID(D3DXCreateTextureFromFileA(device, "../media/textures/wood2.jpg", &texture2));
	MYVALID(D3DXCreateTextureFromFileA(device, "../media/textures/crate.jpg", &texture3));
	MYVALID(D3DXCreateTextureFromFileA(device, "../media/textures/pcfnoise.bmp", &noise));

	MYVALID(device->CreateTexture(SHADOWMAP_SIZE, SHADOWMAP_SIZE, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &shadowmap, NULL));
	MYVALID(device->CreateTexture(SHADOWMAP_SIZE, SHADOWMAP_SIZE, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &blurRGBA32F, NULL));
	MYVALID(device->CreateTexture(SHADOWMAP_SIZE, SHADOWMAP_SIZE, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &sincoeffs, NULL));
	MYVALID(device->CreateTexture(SHADOWMAP_SIZE, SHADOWMAP_SIZE, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &coscoeffs, NULL));
	MYVALID(device->CreateTexture(SHADOWMAP_SIZE, SHADOWMAP_SIZE, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &blurARGB8, NULL));
	
	MYVALID(device->CreateTexture(800, 512, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &text, NULL));
	MYVALID(device->CreateVertexDeclaration(elem, &vertexdecl));

	MYVALID(DXCreateEffect("../media/shaders/exponentialshadow.fx", device, &exponential));
	MYVALID(DXCreateEffect("../media/shaders/convolutionshadow.fx", device, &convolution));
	MYVALID(DXCreateEffect("../media/shaders/varianceshadow.fx", device, &variance));
	MYVALID(DXCreateEffect("../media/shaders/expvarianceshadow.fx", device, &expvariance));
	MYVALID(DXCreateEffect("../media/shaders/boxblur5x5.fx", device, &boxblur5x5));
	MYVALID(DXCreateEffect("../media/shaders/pcfshadow5x5.fx", device, &pcf5x5));
	MYVALID(DXCreateEffect("../media/shaders/pcss.fx", device, &pcss));
	MYVALID(DXCreateEffect("../media/shaders/irregularpcf.fx", device, &pcfirreg));

	DXRenderText(
		"Use the mouse to rotate the camera and the light\n\n0 - Unfiltered\n1 - PCF (5x5)\n2 - Irregular PCF\n3 - Variance\n"
		"4 - Convolution\n5 - Exponential\n6 - Exponential variance\n7 - PCSS", text, 800, 512);
	
	cameraangle = D3DXVECTOR2(0.78f, 0.78f);
	lightangle = D3DXVECTOR2(3.2f, 0.85f);

	DXAABox			boxbb;
	DXAABox			skullbb;
	DXAABox			tmpbb;
	D3DXMATRIX		tmp1, tmp2, tmp3;
	D3DXVECTOR3*	vdata;

	box->LockVertexBuffer(D3DLOCK_READONLY, (void**)&vdata);
	D3DXComputeBoundingBox(vdata, box->GetNumVertices(), box->GetNumBytesPerVertex(), &boxbb.Min, &boxbb.Max);
	box->UnlockVertexBuffer();

	skull->LockVertexBuffer(D3DLOCK_READONLY, (void**)&vdata);
	D3DXComputeBoundingBox(vdata, skull->GetNumVertices(), skull->GetNumBytesPerVertex(), &skullbb.Min, &skullbb.Max);
	skull->UnlockVertexBuffer();

	for( int i = 0; i < numobjects; ++i )
	{
		SceneObject& obj = objects[i];

		D3DXMatrixScaling(&tmp1, obj.scale.x, obj.scale.y, obj.scale.z);
		D3DXMatrixRotationYawPitchRoll(&tmp2, obj.angles.x, obj.angles.y, obj.angles.z);
		D3DXMatrixTranslation(&tmp3, obj.position.x, obj.position.y, obj.position.z);

		D3DXMatrixMultiply(&obj.world, &tmp1, &tmp2);
		D3DXMatrixMultiply(&obj.world, &obj.world, &tmp3);

		if( obj.type == SKULL )
			tmpbb = skullbb;
		else
			tmpbb = boxbb;

		tmpbb.TransformAxisAligned(obj.world);

		scenebb.Add(tmpbb.Min);
		scenebb.Add(tmpbb.Max);
	}

	return S_OK;
}
Esempio n. 17
0
void CShowPoints9::SetMesh(LPD3DXMESH pNewMesh, LPD3DXSKININFO pNewSkin)
{
    HRESULT hr = S_OK;

    NumPoints = 0;
    
    UnskinnedVB.resize(0);
    SAFE_RELEASE(SkinnedVB);
    SAFE_RELEASE(Skin);

    if(pNewMesh == NULL)
        return;

    IDirect3DDevice9* device = DXUTGetD3D9Device();

    {//EFFECT
     V( device->CreateVertexDeclaration( Elements, &Declaration ) );

     ID3DXBuffer* pErrors = NULL;
     V( SASCreateEffectFromResource(
             device, 
             NULL, MAKEINTRESOURCE(IDR_SHOWLINES9FX), MAKEINTRESOURCE(RT_RCDATA),
             NULL, 
             NULL, 
             0,
             NULL, 
             &Effect, 
             &pErrors));
    if(pErrors)
         DXVGetApp().OutputA( (const char*)pErrors->GetBufferPointer() );
    SAFE_RELEASE(pErrors);

    }//EFFECT



    D3DVERTEXELEMENT9 declIn[ MAX_FVF_DECL_SIZE ];
    V( pNewMesh->GetDeclaration(declIn) );

    int iPos= -1;
    int iNorm= -1;
    for( int i = 0 ; 
        declIn[i].Stream != 255 && i < MAX_FVF_DECL_SIZE;
        i++)
    {
        if(declIn[i].Usage == D3DDECLUSAGE_POSITION && declIn[i].UsageIndex == 0)
            iPos = i;
        if(declIn[i].Usage == D3DDECLUSAGE_NORMAL && declIn[i].UsageIndex == 0)
            iNorm = i;
    }

    if(iPos == -1 || iNorm == -1)
        return;

    if( (( declIn[iPos].Type & (D3DDECLTYPE_FLOAT3|D3DDECLTYPE_FLOAT4)) == 0  ) ||
        (( declIn[iNorm].Type & (D3DDECLTYPE_FLOAT3|D3DDECLTYPE_FLOAT4)) == 0  ) )
        return;

    NumPoints = pNewMesh->GetNumVertices();

    int MeshStride = pNewMesh->GetNumBytesPerVertex();


    if(pNewSkin)
    {
        V( pNewSkin->Clone( &Skin ) ); 
        V( Skin->SetDeclaration(Elements) );
    }


    //GET VERTEX DATA

    BYTE* pSrcVB= NULL;
    V(  pNewMesh->LockVertexBuffer( D3DLOCK_READONLY, (LPVOID*)&pSrcVB ) );
    UnskinnedVB.resize(pNewMesh->GetNumVertices());
    for( DWORD iVert = 0; iVert < pNewMesh->GetNumVertices(); iVert++)
    {
        Vertex& v0 = UnskinnedVB[iVert];

        v0.Position = *(D3DXVECTOR3*) (pSrcVB+(MeshStride*iVert)+declIn[iPos].Offset);
    }
    V( pNewMesh->UnlockVertexBuffer() );

    V( device->CreateVertexBuffer( NumPoints*Stride , D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &SkinnedVB, NULL) );
    //Fill in with initial values so unskinned meshes do not have to do this every render.
    pSrcVB=(BYTE*)(void*)&UnskinnedVB.front();
    BYTE* pDstVB=NULL;
    V( SkinnedVB->Lock(0, 0, (void**)&pDstVB, 0 ) );
    {
        memcpy( pDstVB, pSrcVB, Stride*pNewMesh->GetNumVertices() );
    }
    V( SkinnedVB->Unlock() );
}
Esempio n. 18
0
//------------------------------------------------------------------------------------------------
// Name:  XMesh
// Desc:  Constructs the subset geometry for a D3DXMesh
//------------------------------------------------------------------------------------------------
bool XMesh::buildGeometryFromD3DXMesh(LPD3DXMESH d3dxMesh, SubsetGeometry* subsetGeometry, DWORD subsets)
{
    // Check parameters
    if (APP_ERROR(!d3dxMesh || !subsetGeometry)("Invalid parameter to XMesh::buildGeometryFromD3DXMesh"))
        return false;

    // Add a reference to the mesh to counteract freeing it at the end
    d3dxMesh->AddRef();

    // Get the device
    LPDIRECT3DDEVICE9 pd3dDevice = NULL;
    d3dxMesh->GetDevice(&pd3dDevice);

    // If this mesh isn't already in the correct format, have D3D do the grunt work of
    // converting it.
    bool generate_normals = false; // Whether or not normals need to be generated for this mesh
    if ((d3dxMesh->GetFVF() != D3DFVF_GEOMETRYVERTEX) ||
        (D3DFMT_GEOMETRYINDEX == D3DFMT_INDEX32) && ((d3dxMesh->GetOptions() & D3DXMESH_32BIT) == 0))
    {
        // Holds the mesh when its converted to the correct format
        LPD3DXMESH pTemd3dxMesh = NULL;

        // Duplicate the loaded mesh into the format
        if (APP_ERROR(d3dxMesh->CloneMeshFVF(
                            D3DXMESH_SYSTEMMEM | ((D3DFMT_GEOMETRYINDEX == D3DFMT_INDEX32) ? D3DXMESH_32BIT : 0),
                            D3DFVF_GEOMETRYVERTEX, pd3dDevice, &pTemd3dxMesh))
                     ("XMesh couldn't convert the source geometry format")) {
            d3dxMesh->Release();
            pd3dDevice->Release();
			      return false;
        }

        // Generate normals if they didn't exist
        generate_normals = ((d3dxMesh->GetFVF()&D3DFVF_NORMAL)!=D3DFVF_NORMAL &&
                            (D3DFMT_GEOMETRYINDEX&D3DFVF_NORMAL)!=D3DFVF_NORMAL);

        // Use this mesh instead
        d3dxMesh->Release();
        d3dxMesh = pTemd3dxMesh;
    }

    // The mesh must have its attributes sorted before it can be converted to single strips
    {
        // Allocate an adjacency buffer
        DWORD faces = d3dxMesh->GetNumFaces();
        DWORD* pAdjacency = new DWORD[faces * 3];
		    bool failed = false;

        if (APP_ERROR(FAILED(d3dxMesh->GenerateAdjacency(ADJACENCY_EPSILON, pAdjacency)))("Unable to generate the mesh adjacency"))
          failed = true;

        { // Clean up "bowties" in the mesh that prevent lighting from being calculated correctly
          LPD3DXMESH cleaned_mesh = NULL;
          DWORD* cleaned_adjacency = new DWORD[faces * 3];
          LPD3DXBUFFER errors_and_warnings = NULL;
          if (!failed && APP_ERROR(FAILED(D3DXCleanMesh(D3DXCLEAN_BOWTIES,
                                                        d3dxMesh,
                                                        pAdjacency,
                                                        &cleaned_mesh,
                                                        cleaned_adjacency,
                                                        &errors_and_warnings)))
                                  ("Failed to clean mesh")) {
            failed = true;
            if (errors_and_warnings) {
              DEBUG_ERROR("Mesh cleaning error:  %s", (const char*)errors_and_warnings->GetBufferPointer());
            }
          }

          SAFE_RELEASE(errors_and_warnings);

          // If we successfully cleaned the mesh, use the new mesh and new set of
          // adjacencies.  Otherwise, just delete anything that was allocated and
          // keep the original.
          if (failed) {
            SAFE_DELETE_ARRAY(cleaned_adjacency);
            SAFE_RELEASE(cleaned_mesh);
          } else {
            SAFE_DELETE_ARRAY(pAdjacency);
            SAFE_RELEASE(d3dxMesh)
            pAdjacency = cleaned_adjacency;
            d3dxMesh = cleaned_mesh;
          }
        }

        // Compute mesh normals, if necessary
        if (!failed && generate_normals && APP_ERROR(FAILED(D3DXComputeNormals(d3dxMesh, pAdjacency)))("Couldn't generate mesh normals")) {
          failed = true;
        }

        // Optimize the mesh
        if (!failed && APP_ERROR(FAILED(d3dxMesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT,
                                                                  pAdjacency,
                                                                  NULL,
                                                                  NULL,
                                                                  NULL)))
                                 ("Couldn't optimize mesh attributes")) {
			    failed = true;
		    }

        // Get rid of the temporary adjacency buffer
        SAFE_DELETE_ARRAY(pAdjacency);

        // Return if there was an error
        if (failed) {
          SAFE_RELEASE(d3dxMesh);
          SAFE_RELEASE(pd3dDevice);
          return false;
        }
    }

    // Lock the vertex buffer
    GeometryVertex* pXVertices = NULL;
    if (APP_ERROR(d3dxMesh->LockVertexBuffer(D3DLOCK_READONLY, (VOID**)&pXVertices))("Couldn't lock source vertex buffer"))
    {
		// Erase this mesh
        d3dxMesh->Release();
        pd3dDevice->Release();

		// Failure
		return false;
    }

    // Iterate through all of the materials and copy vertex/index data, and assign material
    // information for the mesh.
    for (DWORD subset = 0; subset < subsets; subset++)
    {
        // Use D3DX to convert this subset into a nicely indexed form
        DWORD numStripIndices;
        LPDIRECT3DINDEXBUFFER9 pSubsetIB;
        if (APP_ERROR(D3DXConvertMeshSubsetToSingleStrip(d3dxMesh, subset, D3DXMESH_SYSTEMMEM, &pSubsetIB, &numStripIndices))("Couldn't convert mesh subset into indexable strip"))
        {
            // Erase any geometry we made
            DeallocateGeometry(subsetGeometry);

            // Get rid of the mesh
            d3dxMesh->UnlockVertexBuffer();
            d3dxMesh->Release();

            // Free our device
            pd3dDevice->Release();

            // Return the error
            return false;
        }

        D3DINDEXBUFFER_DESC desc;
        GeometryIndex* pXIndices = NULL;

        // Check the format of the indices and lock the strip index buffer
        if (APP_ERROR(pSubsetIB->GetDesc(&desc))("Couldn't get .X mesh IB desc") || (desc.Format != D3DFMT_GEOMETRYINDEX) ||
            APP_ERROR(pSubsetIB->Lock(0, 0, (VOID**)&pXIndices, D3DLOCK_READONLY))("Unable to lock the .X index buffer"))
        {
            // Erase any geometry we made
            DeallocateGeometry(subsetGeometry);

            // Get rid of the mesh
            pSubsetIB->Release();
            d3dxMesh->UnlockVertexBuffer();
            d3dxMesh->Release();

            // Free our device
            pd3dDevice->Release();

            // Error!
            return false;
        }

        // This table pairs an index from the .X file to an index in the buffer that
        // holds the vertices for this subset
        XIndicesTable xIndicesTable;

        // For each of the indices in the strip, puts its vertex ID into the indices
        // table.  Use the counter to determine which vertex this is.
        {
            GeometryIndex vertexCounter = 0;
            for (DWORD e = 0; e < numStripIndices; ++e)
            {
                // Insert the entry [x-mesh index, subset index] into the table
                XIndicesTableInsertResult result = xIndicesTable.insert(XIndicesEntry(pXIndices[e], vertexCounter));

                // If the result was successful (this isn't a duplicated X-mesh index) increment the vertex counter
                if (result.second)
                    vertexCounter++;
            }
        }

        // Grab the number of vertices this geometry uses
        DWORD numVertices = (DWORD)xIndicesTable.size();

        // This buffer holds all of the triangles in this subset
        TriangleList triangles;

        // This list keeps track of locations in the strip where the winding order changes.  This is necessary
        // because this next part will remove degenerate triangles from the list.
        std::set<size_t> windingChanges;

        // Generate the list of triangles from the strip provided
        for (DWORD t = 0; t < numStripIndices - 2; ++t)
        {
            // Build the triangle that will be added to the buffer
            // CHANGED July 25, 2008:  the winding order is wrong here
            //Triangle tri = { pXIndices[t + 0], pXIndices[t + 1], pXIndices[t + 2] };
            Triangle tri = { pXIndices[t + 0], pXIndices[t + 2], pXIndices[t + 1] };



            // Convert the triangle into subset-indices by using the lookup table
            // we generated before.
            tri.index[0] = xIndicesTable.find(tri.index[0])->second;
            tri.index[1] = xIndicesTable.find(tri.index[1])->second;
            tri.index[2] = xIndicesTable.find(tri.index[2])->second;

            // Check to make sure this triangle isn't degenerate.  If it is, we can just skip
            // this triangle entirely to simplify the geometry.
            if (tri.index[0] == tri.index[1] || tri.index[1] == tri.index[2] || tri.index[0] == tri.index[2])
            {
                // Try to find the winding in the list
                std::set<size_t>::iterator currentWinding = windingChanges.find(triangles.size());

                // Add this to the winding change list, or remove the change if it's already there
                if (currentWinding != windingChanges.end())
                    windingChanges.erase(currentWinding);
                else
                    windingChanges.insert(triangles.size());

                // Don't insert a triangle here
                continue;
            }

            // Add this triangle to the list
            triangles.push_back(tri);
        }

        // Calculate the number of indices we need for the buffer
        DWORD numGeometryIndices = (DWORD)(triangles.size() * 3);

        // Allocate the destination geometry
        Geometry* pGeometry = NULL;
        if (APP_ERROR(AllocateGeometry(numVertices, numGeometryIndices, &pGeometry))("Couldn't allocate geometry"))
        {
            // Erase any geometry we made
            DeallocateGeometry(subsetGeometry);

            // Get rid of the mesh
            pSubsetIB->Unlock();
            pSubsetIB->Release();
            d3dxMesh->UnlockVertexBuffer();
            d3dxMesh->Release();

            // Free our device
            pd3dDevice->Release();

            // Error!
            return false;
        }

        // Copy the vertices needed for this subset into the buffer
        GeometryVertex* pVertices = pGeometry->pVertices;
        for (XIndicesIterator i = xIndicesTable.begin(); i != xIndicesTable.end(); ++i)
        {
            GeometryVertex* pCurrentVertex = &pVertices[i->second];
            *pCurrentVertex = pXVertices[i->first];

            // Modify the vertex location to make this a unit mesh sitting on the X-Z plane
            pCurrentVertex->x = pCurrentVertex->x;
            pCurrentVertex->y = pCurrentVertex->y;
            pCurrentVertex->z = pCurrentVertex->z;

            //pVertices[i->second].color = D3DCOLOR_XRGB(255,255,255);
            // todo: enable color?
        }

        // Copy triangles into the indices buffer
        DWORD index = 0;
        GeometryIndex* pIndices = pGeometry->pIndices;
        DWORD windingOrder = 0;
        for (TriangleIterator t = triangles.begin(); t != triangles.end(); ++t)
        {
            // Find this index in the winding list
            if (windingChanges.find(index / 3) != windingChanges.end())
                windingOrder = 1 - windingOrder;

            // Alternate the winding order so that everything shows up correctly
            if ((index / 3) % 2 == windingOrder)
            {
                pIndices[index + 0] = t->index[0];
                pIndices[index + 1] = t->index[1];
                pIndices[index + 2] = t->index[2];
            }
            else
            {
                pIndices[index + 0] = t->index[1];
                pIndices[index + 1] = t->index[0];
                pIndices[index + 2] = t->index[2];
            }

            // Increment the index counter
            index += 3;
        }

        // Unlock and delete strip index buffer
        pSubsetIB->Unlock();
        pSubsetIB->Release();

        // Store the buffers in the main array
        std::pair<SubsetGeometry::iterator,bool> result =
            subsetGeometry->insert(SubsetGeometry::value_type(subset, pGeometry));

        if (APP_ERROR(!result.second)("Couldn't insert subset geometry into main array for .X mesh"))
        {
            // Get rid of this geometry
            DeallocateGeometry(pGeometry);
            DeallocateGeometry(subsetGeometry);

            // Erase the mesh
            d3dxMesh->UnlockVertexBuffer();
            d3dxMesh->Release();

            // Free our device
            pd3dDevice->Release();

            // Return error
            return false;
        }

        //DEBUG_MSG("Subset %i has %i vertices %i indices (%i polygons)\n", subset, numVertices, numGeometryIndices, numGeometryIndices / 3);
    }

    // Done with the DirectX mesh.  This will not erase the outside mesh.
    d3dxMesh->UnlockVertexBuffer();
    d3dxMesh->Release();

    // Free the device reference
    pd3dDevice->Release();

    // Success
    return true;
}
Esempio n. 19
0
	void CreateBox( const float &w, const float &h, const float &d, const bool &centerWidth, const bool &centerHeight, const bool &centerDepth, LPD3DXMESH &mesh )
	{
		float offsetX = 0, offsetY = 0, offsetZ = 0;
		if( centerWidth )
			offsetX = -w / 2.f;
		if( centerHeight )
			offsetY = -h / 2.f;
		if( centerDepth )
			offsetZ = -d / 2.f;

		std::vector<DWORD> vIB;
		std::vector<VERTEX3> vVB;
		std::vector<DWORD> vAB;
		DWORD offset = 0;

		// fill in the front face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the front face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, 0.f, -1.f, 1.f, 1.f ) );

		vAB.push_back( 0 );
		vAB.push_back( 0 );

		offset += 4;

		// fill in the back face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the back face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 1.f, 1.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, 0.f, 0.f, 1.f, 1.f, 0.f ) );

		vAB.push_back( 1 );
		vAB.push_back( 1 );

		offset += 4;

		// fill in the top face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		//fill in the top face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 1.f, 0.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, 0.f, 1.f, 0.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 0.f, 1.f, 0.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 0.f, 1.f, 0.f, 1.f, 1.f ) );

		vAB.push_back( 2 );
		vAB.push_back( 2 );

		offset += 4;

		// fill in the bottom face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the bottom face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, -1.f, 0.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 0.f, -1.f, 0.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 0.f, -1.f, 0.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, 0.f, -1.f, 0.f, 1.f, 1.f ) );

		vAB.push_back( 3 );
		vAB.push_back( 3 );

		offset += 4;

		// fill in the left face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the left face vertex data
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, d + offsetZ, -1.f, 0.f, 0.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, d + offsetZ, -1.f, 0.f, 0.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, h + offsetY, 0.f + offsetZ, -1.f, 0.f, 0.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( 0.f + offsetX, 0.f + offsetY, 0.f + offsetZ, -1.f, 0.f, 0.f, 1.f, 1.f ) );

		vAB.push_back( 4 );
		vAB.push_back( 4 );

		offset += 4;

		// fill in the right face index data
		vIB.push_back( 0 + offset );
		vIB.push_back( 1 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 0 + offset );
		vIB.push_back( 2 + offset );
		vIB.push_back( 3 + offset );

		// fill in the right face vertex data
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, 0.f + offsetZ, 1.f, 0.f, 0.f, 0.f, 1.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, 0.f + offsetZ, 1.f, 0.f, 0.f, 0.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, h + offsetY, d + offsetZ, 1.f, 0.f, 0.f, 1.f, 0.f ) );
		vVB.push_back( VERTEX3( w + offsetX, 0.f + offsetY, d + offsetZ, 1.f, 0.f, 0.f, 1.f, 1.f ) );

		vAB.push_back( 5 );
		vAB.push_back( 5 );

		offset += 4;

		D3DXCreateMeshFVF( offset / 2, offset, D3DXMESH_MANAGED | D3DXMESH_32BIT, VERTEX3::FVF, g_pEngine->core->lpd3dd9, &mesh );

		VERTEX3 *pVB = nullptr;
		mesh->LockVertexBuffer( D3DLOCK_DISCARD, reinterpret_cast< void** >( &pVB ) );
		copy( vVB.begin(), vVB.end(), pVB );
		mesh->UnlockVertexBuffer();

		DWORD *pIB = nullptr;
		mesh->LockIndexBuffer( D3DLOCK_DISCARD, reinterpret_cast< void** >( &pIB ) );
		copy( vIB.begin(), vIB.end(), pIB );
		mesh->UnlockIndexBuffer();

		DWORD *pAB = nullptr;
		mesh->LockAttributeBuffer( D3DLOCK_DISCARD, &pAB );
		copy( vAB.begin(), vAB.end(), pAB );
		mesh->UnlockAttributeBuffer();

		std::vector<DWORD> adjacencyBuffer( mesh->GetNumFaces() * 3 );
		mesh->GenerateAdjacency( 0.f, &adjacencyBuffer[ 0 ] );
		mesh->OptimizeInplace( D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, &adjacencyBuffer[ 0 ], nullptr, nullptr, nullptr );
	}
Esempio n. 20
0
HRESULT KModelWater::LoadMesh(LPSTR pFileName)
{
	HRESULT hr = S_OK;

	m_dwNumPoly_X = 63;     //长方形网格的长,网格数
	m_dwNumPoly_Z = 63;     //长方形网格的宽,网格数

	LPD3DXMESH pMesh = m_pWaterUp;
	LPD3DXMESH pDMesh = m_pWaterDn;

	DWORD m_dNumPloy     = m_dwNumPoly_X * m_dwNumPoly_Z;
	DWORD m_dNumFaces    = m_dNumPloy * 2;
	DWORD m_dNumVertices = (m_dwNumPoly_X+1)*(m_dwNumPoly_Z+1);

	SAFE_RELEASE(pMesh);	
	SAFE_RELEASE(pDMesh);
	WORD *pwIndices;

	//建立水面网格 
	if(FAILED(hr = g_pd3dDevice->CreateIndexBuffer(m_dNumFaces * 3 * sizeof(WORD), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 
		D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pibIndices, NULL)))
	{
		return hr;
	}

	if (FAILED(hr = D3DXCreateMeshFVF(m_dNumFaces,m_dNumVertices,D3DXMESH_MANAGED|D3DXMESH_32BIT,
		D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_NORMAL|D3DFVF_TEX1,g_pd3dDevice,&pMesh)))
	{
		return hr;
	}	
	if (FAILED(hr = D3DXCreateMeshFVF(m_dNumFaces,m_dNumVertices,D3DXMESH_MANAGED|D3DXMESH_32BIT,
		D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_NORMAL|D3DFVF_TEX1,g_pd3dDevice,&pDMesh)))
	{
		return hr;
	}




	VFormat::FACES_NORMAL_TEXTURE1 * pVers = NULL;
	DWORD* pIndex = NULL;
	DWORD * pAttrib = NULL;	

	VFormat::FACES_NORMAL_TEXTURE1 * pDVers = NULL;
	DWORD* pDIndex = NULL;
	DWORD * pDAttrib = NULL;	
	if(FAILED(hr = m_pibIndices->Lock(0, m_dNumFaces *3 * sizeof(WORD), (void**) &pwIndices, D3DLOCK_DISCARD)))
		return E_FAIL;
	if (FAILED(pMesh->LockVertexBuffer(0,(void**)&pVers)))
		return E_FAIL;
	if (FAILED(pMesh->LockIndexBuffer (0,(void**)&pIndex)))
		return E_FAIL;
	if (FAILED(pMesh->LockAttributeBuffer(0,(DWORD**)&pAttrib)))
		return E_FAIL;

	if (FAILED(pDMesh->LockVertexBuffer(0,(void**)&pDVers)))
		return E_FAIL;
	if (FAILED(pDMesh->LockIndexBuffer (0,(void**)&pDIndex)))
		return E_FAIL;
	if (FAILED(pDMesh->LockAttributeBuffer(0,(DWORD**)&pDAttrib)))
		return E_FAIL;

	DWORD i = 0;
	float _X = 1.0f/m_dwNumPoly_X;
	float _Z = 1.0f/m_dwNumPoly_Z;

	float m_fPolyWidth  = 200;
	float m_fPolyHeight = 200;

	for(DWORD X =0;X<=m_dwNumPoly_X;X++)
	{
		for(DWORD Y =0;Y<=m_dwNumPoly_Z;Y++)
		{
			float PX = X * m_fPolyWidth;
			float PZ = Y * m_fPolyHeight;

			D3DXVECTOR2 Pos(PX,PZ);

			pVers[i].p = D3DXVECTOR3(PX,200,PZ);

			pVers[i].Normal = D3DXVECTOR3(0,1,0);

			pVers[i].tu1 = (X * _X);
			pVers[i].tv1 = (1 - Y *_Z);
			pDVers[i].p = D3DXVECTOR3(PX,0,PZ);
			pDVers[i].Normal = D3DXVECTOR3(0,1,0);
			pDVers[i].tu1 = (X * _X);
			pDVers[i].tv1 = (1 - Y *_Z);
			i++;
		}
	}

	DWORD  Weight = m_dwNumPoly_X + 1;

	for(X =0;X<m_dwNumPoly_X;X++)
	{
		for(DWORD Y =0;Y<m_dwNumPoly_Z;Y++)
		{
			DWORD PloyIndex = Y*m_dwNumPoly_X +X;

			DWORD PolyMaterialID = 0;

			DWORD Vertex_A = X    *Weight+ Y;
			DWORD Vertex_B = (X+1)*Weight+ Y;
			DWORD Vertex_C = (X+1)*Weight+(Y+1);
			DWORD Vertex_D = X    *Weight+(Y+1);

			DWORD Faces_A1 = (PloyIndex*2)*3;
			DWORD Faces_B1 = Faces_A1 + 1;
			DWORD Faces_C1 = Faces_B1 + 1;

			pIndex[Faces_A1] = Vertex_A;
			pIndex[Faces_B1] = Vertex_B;
			pIndex[Faces_C1] = Vertex_D;
			pAttrib[PloyIndex*2] = PolyMaterialID;
			pDIndex[Faces_A1] = Vertex_A;
			pDIndex[Faces_B1] = Vertex_B;
			pDIndex[Faces_C1] = Vertex_D;
			pDAttrib[PloyIndex*2] = PolyMaterialID;

			pwIndices[Faces_A1] = WORD(Vertex_A);
			pwIndices[Faces_B1] = WORD(Vertex_B);
			pwIndices[Faces_C1] = WORD(Vertex_D);

			DWORD Faces_A2 = (PloyIndex*2+1)*3;
			DWORD Faces_B2 = Faces_A2 + 1;
			DWORD Faces_C2 = Faces_B2 + 1;

			pIndex[Faces_A2] = Vertex_D;
			pIndex[Faces_B2] = Vertex_B;
			pIndex[Faces_C2] = Vertex_C;
			pAttrib[PloyIndex*2+1] = PolyMaterialID;
			pDIndex[Faces_A2] = Vertex_D;
			pDIndex[Faces_B2] = Vertex_B;
			pDIndex[Faces_C2] = Vertex_C;
			pDAttrib[PloyIndex*2+1] = PolyMaterialID;

			pwIndices[Faces_A2] = WORD(Vertex_D);
			pwIndices[Faces_B2] = WORD(Vertex_B);
			pwIndices[Faces_C2] = WORD(Vertex_C);

		}
	}	

	D3DXComputeBoundingBox((D3DXVECTOR3*)pVers,m_dNumVertices,sizeof(VFormat::FACES_NORMAL_TEXTURE1),
		&m_BBox_A,&m_BBox_B);
	D3DXComputeBoundingBox((D3DXVECTOR3*)pDVers,m_dNumVertices,sizeof(VFormat::FACES_NORMAL_TEXTURE1),
		&m_BBox_A,&m_BBox_B);

	if (FAILED(pMesh->UnlockVertexBuffer()))
		return E_FAIL;
	if (FAILED(pMesh->UnlockIndexBuffer()))
		return E_FAIL;
	if (FAILED(pMesh->UnlockAttributeBuffer()))
		return E_FAIL;

	if (FAILED(pDMesh->UnlockVertexBuffer()))
		return E_FAIL;
	if (FAILED(pDMesh->UnlockIndexBuffer()))
		return E_FAIL;
	if (FAILED(pDMesh->UnlockAttributeBuffer()))
		return E_FAIL;
	if (FAILED(m_pibIndices->Unlock()))
		return E_FAIL;
	m_pWaterUp = pMesh;		
	m_pWaterDn = pDMesh;	


	//水面网格的材质
	m_dNumMaterial = 1;
	m_lpMaterial = new MATERIAL[m_dNumMaterial];
	ZeroMemory(m_lpMaterial,sizeof(MATERIAL)*m_dNumMaterial);

	DWORD Def_Option = MATERIAL_OPTION_ZBUFFER_TRUE|
		MATERIAL_OPTION_FILL_SOLID|
		MATERIAL_OPTION_SHADE_GOURAUD|
		MATERIAL_OPTION_CULL_NONE|
		MATERIAL_OPTION_SPECULARENABLE;

	for(DWORD i=0;i<m_dNumMaterial;i++)
	{
		m_lpMaterial[i].m_sMaterial9.Diffuse.r = 0.7f ;
		m_lpMaterial[i].m_sMaterial9.Diffuse.g = 0.7f ;
		m_lpMaterial[i].m_sMaterial9.Diffuse.b = 0.7f ;
		m_lpMaterial[i].m_sMaterial9.Diffuse.a = 1.0f ;
		m_lpMaterial[i].m_sMaterial9.Ambient = m_lpMaterial[i].m_sMaterial9.Diffuse;
		m_lpMaterial[i].m_sMaterial9.Specular = m_lpMaterial[i].m_sMaterial9.Diffuse;
		m_lpMaterial[i].m_sMaterial9.Power = 15;
		m_lpMaterial[i].m_dOption = Def_Option;
	} 

	TCHAR Name[256];
	wsprintf(Name,"%s\\Water.Mtl",g_Def_ModelDirectory);
	LoadMaterial(Name);  


	//天空盒的纹理
	wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"Textures\\LobbyCube.dds");
	if( FAILED( hr = D3DXCreateCubeTextureFromFile( g_pd3dDevice,Name, &m_pSkyCubeTex ) ) )
		return hr; 
	//水面的纹理
	wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"Textures\\Water.bmp");
	if( FAILED( hr = D3DXCreateTextureFromFileEx(g_pd3dDevice, Name, D3DX_DEFAULT, D3DX_DEFAULT, 
		D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, 
		D3DX_DEFAULT, 0, NULL, NULL, &m_pWaterTex) ))
		return hr;
	/*
	// Effect
	wsprintf(Name,"%s\\%s",g_Def_AppDirectory,"water.fx");
	if(FAILED(hr = D3DXCreateEffectFromFile(g_pd3dDevice, Name, NULL, NULL, 0, NULL, &m_pEffect, NULL)))
	return hr;
	m_pEffect->OnResetDevice();
	m_pEffect->SetTexture("tFLR", m_pWaterTex);
	m_pEffect->SetTexture("tENV", m_pSkyCubeTex);
	*/

	//创建水面bump纹理
	if( FAILED( InitBumpMap() ) )
		return E_FAIL;
	//	m_pEffect->SetTexture("tBump", m_pBumpMapTexture);
	WSea.Initialize(m_dwNumPoly_X,m_dwNumPoly_Z);
	Water.Initialize(m_pWaterUp,m_dwNumPoly_X,m_dwNumPoly_Z);   //初始化水纹
	Water.Drop();                                               //产生水纹  
	Ripple.Initialize(m_pWaterUp,m_dwNumPoly_X,m_dwNumPoly_Z);  //初始化涟漪纹


	return S_OK;

}
Esempio n. 21
0
//-----------------------------------------------------------------------------
// Name: RestorePolygonMesh()
// Desc: Initialize device dependent objects.
// Params:
// pd3dDevice
//	[in] Pointer to an IDirect3DDevice9 interface, representing the device associated with the created polygon mesh. 
// Length
//	[in] Length of each side. 
// Sides
//	[in] Number of sides for the polygon. Value must be greater than or equal to 3. 
// ppMesh
//	[out] Address of a pointer to the output shape, an ID3DXMesh interface. 
//-----------------------------------------------------------------------------
HRESULT CD3DMesh::RestorePolygonMesh(LPDIRECT3DDEVICE9 pd3dDevice,FLOAT Length, UINT Sides, LPD3DXMESH *ppMesh)
{
	HRESULT hr;
	// create the floor geometry
    LPD3DXMESH pMesh;
    hr = D3DXCreatePolygon( pd3dDevice, Length, Sides, & pMesh, NULL );
    if( FAILED( hr ) )
        return hr;

    hr = pMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1, pd3dDevice, ppMesh );
    pMesh->Release();
    if( FAILED( hr ) )
        return hr;

    LPD3DXMESH pMeshFloor = *ppMesh;				// rename variable
    
	DWORD dwNumVx = pMeshFloor->GetNumVertices();

    struct Vx
    {
        D3DXVECTOR3 vPos;
        D3DXVECTOR3 vNorm;
        float fTex[ 2 ];
    };

    // Initialize its texture coordinates
	const int FLOOR_TILECOUNT = 2;
	Vx * pVx;
    hr = pMeshFloor->LockVertexBuffer( 0, (VOID **) & pVx );
    if( FAILED( hr ) )
        return hr;

    for( DWORD i = 0; i < dwNumVx; ++ i )
    {
        if( fabs( pVx->vPos.x ) < 0.01 )
        {
            if( pVx->vPos.y > 0 )
            {
                pVx->fTex[ 0 ] = 0.0f;
                pVx->fTex[ 1 ] = 0.0f;
            } else
            if( pVx->vPos.y < 0.0f )
            {
                pVx->fTex[ 0 ] = 1.0f * FLOOR_TILECOUNT;
                pVx->fTex[ 1 ] = 1.0f * FLOOR_TILECOUNT;
            } else
            {
                pVx->fTex[ 0 ] = 0.5f * FLOOR_TILECOUNT;
                pVx->fTex[ 1 ] = 0.5f * FLOOR_TILECOUNT;
            }
        } else
        if( pVx->vPos.x > 0.0f )
        {
            pVx->fTex[ 0 ] = 1.0f * FLOOR_TILECOUNT;
            pVx->fTex[ 1 ] = 0.0f;
        } else
        {
            pVx->fTex[ 0 ] = 0.0f;
            pVx->fTex[ 1 ] = 1.0f * FLOOR_TILECOUNT;
        }

        ++ pVx;
    }

    pMeshFloor->UnlockVertexBuffer();
	return S_OK;
}
Esempio n. 22
0
void Sombra::ConstruirSombra(LPD3DXMESH pMesh, D3DXVECTOR3 vLight)
{
    // Note: the MeshVertex format depends on the FVF of the mesh
	struct MeshVertex { D3DXVECTOR3 p, n;
                            DWORD diffuse;
                         float tu,tv;   };

    MeshVertex *pVertices;
    WORD       *pIndices;

    // Lock the geometry buffers
    pMesh->LockVertexBuffer( 0L, (LPVOID*)&pVertices );
    pMesh->LockIndexBuffer( 0L, (LPVOID*)&pIndices );
    DWORD dwNumFaces    = pMesh->GetNumFaces();

    // Allocate a temporary edge list
    WORD *pEdges = new WORD[dwNumFaces*6];

    if( pEdges == NULL )
    {
        pMesh->UnlockVertexBuffer();
        pMesh->UnlockIndexBuffer();
        return ;
    }
	
    DWORD dwNumEdges = 0;

    // For each face
    for( DWORD i = 0; i < dwNumFaces; ++i )
    {
        WORD wFace0 = pIndices[3*i+0];
        WORD wFace1 = pIndices[3*i+1];
        WORD wFace2 = pIndices[3*i+2];

        D3DXVECTOR3 v0 = pVertices[wFace0].p;
        D3DXVECTOR3 v1 = pVertices[wFace1].p;
        D3DXVECTOR3 v2 = pVertices[wFace2].p;

        // Transform vertices or transform light?
        D3DXVECTOR3 vCross1(v2-v1);
        D3DXVECTOR3 vCross2(v1-v0);
        D3DXVECTOR3 vNormal;
        D3DXVec3Cross( &vNormal, &vCross1, &vCross2 );

        if( D3DXVec3Dot( &vNormal, &vLight ) >= 0.0f )
        {
            InsertarSegmento( pEdges, dwNumEdges, wFace0, wFace1 );
            InsertarSegmento( pEdges, dwNumEdges, wFace1, wFace2 );
            InsertarSegmento( pEdges, dwNumEdges, wFace2, wFace0 );
        }
    }

    // Se construyen las caras de la sombra extrudando los segmentos en la dirección
    // de la luz y una longitud 10 veces la del vector luz.
    for( i = 0; i < dwNumEdges; ++i )
    {
        D3DXVECTOR3 v1 = pVertices[pEdges[2*i+0]].p;
        D3DXVECTOR3 v2 = pVertices[pEdges[2*i+1]].p;
        D3DXVECTOR3 v3 = v1 - vLight/10;
        D3DXVECTOR3 v4 = v2 - vLight/10;

        // Add a quad (two triangles) to the vertex list
        m_pVertices[m_dwNumVertices++] = v1;
        m_pVertices[m_dwNumVertices++] = v2;
        m_pVertices[m_dwNumVertices++] = v3;

        m_pVertices[m_dwNumVertices++] = v2;
        m_pVertices[m_dwNumVertices++] = v4;
        m_pVertices[m_dwNumVertices++] = v3;
    }

    // Delete the temporary edge list
    delete[] pEdges;

    // Unlock the geometry buffers
    pMesh->UnlockVertexBuffer();
    pMesh->UnlockIndexBuffer();

   
    
}
VOID Update()
{
	DWORD currentTime = GetTickCount();
	static DWORD preTime;
	g_ElapsedTime = currentTime - preTime;
	preTime = currentTime;

	if ( GetAsyncKeyState( VK_LEFT ) )
	{
		g_Box[0].CenterPos.x -= g_ElapsedTime*0.002f;
	}
	if ( GetAsyncKeyState( VK_RIGHT ) )
	{
		g_Box[0].CenterPos.x += g_ElapsedTime*0.002f;
	}
	if ( GetAsyncKeyState( VK_UP ) )
	{
		g_Box[0].CenterPos.y += g_ElapsedTime*0.002f;
	}
	if ( GetAsyncKeyState( VK_DOWN ) )
	{
		g_Box[0].CenterPos.y -= g_ElapsedTime*0.002f;
	}
	if ( GetAsyncKeyState( VK_LBUTTON ) )
	{
		if (g_ElapsedTime > 20)
		{
			g_Method = !g_Method;
		}
		
	}
	if ( GetAsyncKeyState( VK_HOME ) )
	{
		g_Box[1].BoxRotateZ -= 0.2f;
	}
	if ( GetAsyncKeyState( VK_END ) )
	{
		g_Box[1].BoxRotateZ += 0.2f;
	}

	D3DXVECTOR3 *vertices;

	g_pMesh->LockVertexBuffer( D3DLOCK_READONLY, (void**) &vertices );
	D3DXComputeBoundingBox( vertices, g_pMesh->GetNumVertices(), g_pMesh->GetNumBytesPerVertex(), &g_MinPoint, &g_MaxPoint );
	g_pMesh->UnlockVertexBuffer();

	D3DXMATRIX matScale, matTrans, matRotateZ, matWorld;
	D3DXMatrixTranslation( &matTrans, g_Box[0].CenterPos.x, g_Box[0].CenterPos.y, g_Box[0].CenterPos.z );
	D3DXMatrixScaling( &matScale, g_Box[0].BoxScaling, g_Box[0].BoxScaling, g_Box[0].BoxScaling );
	D3DXMatrixRotationZ( &matRotateZ, g_Box[0].BoxRotateZ );

	matWorld = matRotateZ* matScale * matTrans;
	D3DXVec3TransformCoord( &g_Box[0].MinPoint, &g_MinPoint, &matWorld );
	D3DXVec3TransformCoord( &g_Box[0].MaxPoint, &g_MaxPoint, &matWorld );
	
	if (!g_Method)
	{
		g_CheckFlag = CheckAABBIntersection( &g_Box[0].MinPoint, &g_Box[0].MaxPoint, &g_Box[1].MinPoint, &g_Box[1].MaxPoint );
	}
	else
	{
		g_CheckFlag = CheckOBBIntersection( &g_Box[0], &g_Box[1] );
	}
	
}
Esempio n. 24
0
//*************************************************************************************************************
void GenerateEdges(edgeset& out, LPD3DXMESH mesh)
{
	D3DXVECTOR3	p1, p2, p3;
	D3DXVECTOR3	a, b, n;
	Edge		e;
	BYTE*		vdata		= 0;
	WORD*		idata		= 0;
	size_t		ind;
	DWORD		numindices	= mesh->GetNumFaces() * 3;
	DWORD		stride		= mesh->GetNumBytesPerVertex();
	WORD		i1, i2, i3;
	bool		is32bit		= (mesh->GetOptions() & D3DXMESH_32BIT);

	out.clear();

	if( is32bit )
	{
		MYERROR("GenerateEdges(): 4 byte indices not implemented yet");
		return;
	}

	// generate edge info
	mesh->LockIndexBuffer(D3DLOCK_READONLY, (LPVOID*)&idata);
	mesh->LockVertexBuffer(D3DLOCK_READONLY, (LPVOID*)&vdata);

	out.reserve(512);

	for( DWORD i = 0; i < numindices; i += 3 )
	{
		if( out.capacity() <= out.size() )
			out.reserve(out.size() + 1024);

		i1 = idata[i + 0];
		i2 = idata[i + 1];
		i3 = idata[i + 2];

		p1 = *((D3DXVECTOR3*)(vdata + i1 * stride));
		p2 = *((D3DXVECTOR3*)(vdata + i2 * stride));
		p3 = *((D3DXVECTOR3*)(vdata + i3 * stride));

		a = p2 - p1;
		b = p3 - p1;

		D3DXVec3Cross(&n, &a, &b);
		D3DXVec3Normalize(&n, &n);

		if( i1 < i2 )
		{
			e.i1 = i1;
			e.i2 = i2;
			e.v1 = p1;
			e.v2 = p2;
			e.n1 = n;

			if( !out.insert(e) )
				std::cout << "Crack in mesh (first triangle)\n";
		}

		if( i2 < i3 )
		{
			e.i1 = i2;
			e.i2 = i3;
			e.v1 = p2;
			e.v2 = p3;
			e.n1 = n;

			if( !out.insert(e) )
				std::cout << "Crack in mesh (first triangle)\n";
		}

		if( i3 < i1 )
		{
			e.i1 = i3;
			e.i2 = i1;
			e.v1 = p3;
			e.v2 = p1;
			e.n1 = n;

			if( !out.insert(e) )
				std::cout << "Crack in mesh (first triangle)\n";
		}
	}

	// find second triangle for each edge
	for( DWORD i = 0; i < numindices; i += 3 )
	{
		i1 = idata[i + 0];
		i2 = idata[i + 1];
		i3 = idata[i + 2];

		p1 = *((D3DXVECTOR3*)(vdata + i1 * stride));
		p2 = *((D3DXVECTOR3*)(vdata + i2 * stride));
		p3 = *((D3DXVECTOR3*)(vdata + i3 * stride));

		a = p2 - p1;
		b = p3 - p1;

		D3DXVec3Cross(&n, &a, &b);
		D3DXVec3Normalize(&n, &n);

		if( i1 > i2 )
		{
			e.i1 = i2;
			e.i2 = i1;

			ind = out.find(e);

			if( ind == edgeset::npos )
			{
				std::cout << "Lone triangle\n";
				continue;
			}

			if( out[ind].other == 0xffffffff )
			{
				out[ind].other = i / 3;
				out[ind].n2 = n;
			}
			else
				std::cout << "Crack in mesh (second triangle)\n";
		}

		if( i2 > i3 )
		{
			e.i1 = i3;
			e.i2 = i2;

			ind = out.find(e);

			if( ind == edgeset::npos )
			{
				std::cout << "Lone triangle\n";
				continue;
			}

			if( out[ind].other == 0xffffffff )
			{
				out[ind].other = i / 3;
				out[ind].n2 = n;
			}
			else
				std::cout << "Crack in mesh (second triangle)\n";
		}

		if( i3 > i1 )
		{
			e.i1 = i1;
			e.i2 = i3;

			ind = out.find(e);

			if( ind == edgeset::npos )
			{
				std::cout << "Lone triangle\n";
				continue;
			}

			if( out[ind].other == 0xffffffff )
			{
				out[ind].other = i / 3;
				out[ind].n2 = n;
			}
			else
				std::cout << "Crack in mesh (second triangle)\n";
		}
	}

	mesh->UnlockIndexBuffer();
	mesh->UnlockVertexBuffer();
}
Esempio n. 25
0
HRESULT KG3DMesh::CreateBspFile()
{
    HRESULT hrResult = E_FAIL;
    HRESULT hrRetCode = E_FAIL;
    int nRetCode = false;
    TCHAR szBSPPathName[MAX_PATH];
    void *pvVerticesBuffer = NULL;
    WORD* pIndexBuffer    = NULL;
    D3DXVECTOR3 *pPos = NULL;
    DWORD *pdwFaceIndex = NULL;
    DWORD dwStride = 0;
    DWORD i = 0;
    DWORD dwNumFaces = 0;
    DWORD dwNumVertices = 0;
    DWORD dwStartTime = timeGetTime();
    LPD3DXMESH piMesh = m_ppMeshes[SMBT_NORMAL];
    KG3DBsp *pBSP = NULL;

    KGLOG_PROCESS_ERROR(piMesh);

    dwStride      = piMesh->GetNumBytesPerVertex();
    dwNumVertices = piMesh->GetNumVertices();
    dwNumFaces    = piMesh->GetNumFaces();

    KG_PROCESS_SUCCESS(dwNumFaces < 256);

    pPos = new D3DXVECTOR3[dwNumVertices];
    KG_ASSERT_EXIT(pPos);

    pdwFaceIndex = new DWORD[dwNumFaces * 3];
    KG_ASSERT_EXIT(pdwFaceIndex);

    hrRetCode = piMesh->LockVertexBuffer(D3DLOCK_READONLY, (void **)&pvVerticesBuffer);
    KGLOG_COM_PROCESS_ERROR(hrRetCode);

    hrRetCode = piMesh->LockIndexBuffer(D3DLOCK_READONLY, (void **)&pIndexBuffer);
    KGLOG_COM_PROCESS_ERROR(hrRetCode);

    for (i = 0; i < dwNumVertices; ++i)
    {
        pPos[i] = *(D3DXVECTOR3 *)(((BYTE *)pvVerticesBuffer) + dwStride * i);
    }
    for (i = 0; i < dwNumFaces * 3; ++i)
    {
        pdwFaceIndex[i] = pIndexBuffer[i];
    }

    // -------------------------- create BSP --------------------------

    hrRetCode = ChangePathExtName(m_scName.c_str(), "bsp", sizeof(szBSPPathName), szBSPPathName);
    KGLOG_COM_PROCESS_ERROR(hrRetCode);

    pBSP = new KG3DBsp;
    KGLOG_PROCESS_ERROR(pBSP);

    hrRetCode = pBSP->CreateFromMesh(dwNumVertices, dwNumFaces, pPos, pdwFaceIndex);
    KGLOG_COM_PROCESS_ERROR(hrRetCode);

    hrRetCode = pBSP->SaveToFile(szBSPPathName);
    KGLOG_COM_PROCESS_ERROR(hrRetCode);

    DWORD dwCost = timeGetTime() - dwStartTime;
    if(dwCost > 500)
    {
        KGLogPrintf(
            KGLOG_WARNING, "BSP %d %d Face %s",
            dwCost, dwNumFaces, szBSPPathName
        );
    }

    KG_DELETE(m_lpBsp); // recreate
    m_lpBsp = pBSP;
    pBSP = NULL;
Exit1:
    hrResult = S_OK;
Exit0:
    KG_DELETE(pBSP);
    if (pIndexBuffer)
    {
        piMesh->UnlockIndexBuffer();
        pIndexBuffer = NULL;
    }
    if (pvVerticesBuffer)
    {
        piMesh->UnlockVertexBuffer();
        pvVerticesBuffer = NULL;
    }
    KG_DELETE_ARRAY(pdwFaceIndex);
    KG_DELETE_ARRAY(pPos);

    if(FAILED(hrResult))
    {
        KGLogPrintf(KGLOG_ERR, "%s 创建失败", szBSPPathName);
    }
    return hrResult;
}
Esempio n. 26
0
	bool GraphicalPlane::GenerateBoard(const std::string& path, const int &width, const int &height, const TextureSP &texture)
	{
		// キーネーム設定
		std::stringstream nameBuffer("");
		// ファイルパス→生成番号→幅高さの順で追加
		nameBuffer << path << ++_createCount << width << height;
		std::string name = nameBuffer.str();
		// メッシュインスタンスの生成
		_mesh = Mesh::CreateEmpty(name);
		// サイズを記録
		_size.x = (float)width ;
		_size.y = (float)height ;
		//_size.z = 0 ;
		// テクスチャ指定がある場合そのサイズを取得
		if(texture != NULL)
		{
			while(UINT(_textureSize.x) < _texture->GetImageInfo().Width)
			{
				_textureSize.x *= 2;
			}
			while(UINT(_textureSize.y) < _texture->GetImageInfo().Height)
			{
				_textureSize.y *= 2;
			}
		}
		// シェーダー設定
		_shader = ShaderNormal::Create();
		// メッシュを生成する
		LPD3DXMESH mesh;
		if (FAILED(D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, Vertex::FVF, GraphicsManager::_device, &mesh)))
			return false;

		//頂点データの作成
		Vertex* vertex;
		mesh->LockVertexBuffer(0, (void**)&vertex);
		for (int y = 0 ; y < 2 ; y++) {
			for (int x = 0 ; x < 2 ; x++) {
				float x1 = (float)(x * width - ((float)width / 2));
				float y1 = (float)(y * height - ((float)height / 2));
				int index = y * 2 + x;
				vertex[index]._position.x = x1;
				vertex[index]._position.y = y1;
				vertex[index]._position.z = 0;
				vertex[index]._normal.x = 0;
				vertex[index]._normal.y = 0;
				vertex[index]._normal.z = 1;
				if( texture == NULL )
				{
					vertex[index]._uv.x = (float)x * 1.0f;
					vertex[index]._uv.y = 1.0f - ((float)y * 1.0f);
				}
			}
		}
		if(texture)
		{
			vertex[0]._uv.x = (float)_rects[_number].left / _texture->GetImageInfo().Width;
			vertex[0]._uv.y = (float)_rects[_number].bottom / _texture->GetImageInfo().Height;
			vertex[1]._uv.x = (float)_rects[_number].right / _texture->GetImageInfo().Width;
			vertex[1]._uv.y = (float)_rects[_number].bottom / _texture->GetImageInfo().Height;
			vertex[2]._uv.x = (float)_rects[_number].left / _texture->GetImageInfo().Width;
			vertex[2]._uv.y = (float)_rects[_number].top / _texture->GetImageInfo().Height;
			vertex[3]._uv.x = (float)_rects[_number].right / _texture->GetImageInfo().Width;
			vertex[3]._uv.y = (float)_rects[_number].top / _texture->GetImageInfo().Height;
		}
		mesh->UnlockVertexBuffer();
		//インデックスデータの作成
		WORD *index;
		mesh->LockIndexBuffer(0, (void **)&index);
		index[0] = 0;
		index[1] = 2;
		index[2] = 1;
		index[3] = 1;
		index[4] = 2;
		index[5] = 3;
		mesh->UnlockIndexBuffer();
	    _mesh->SetMesh(mesh);

		return true;
	}
//-----------------------------------------------------------------------------
// Name: buildShadowVolume()
// Desc: Takes a mesh as input, and uses it to build a shadow volume. The
//       technique used considers each triangle of the mesh, and adds it's
//       edges to a temporary list. The edge list is maintained, such that
//       only silohuette edges are kept. Finally, the silohuette edges are
//       extruded to make the shadow volume vertex list.
//-----------------------------------------------------------------------------
HRESULT CShadowVolume::BuildShadowVolume(LPD3DXMESH pMesh, D3DXVECTOR3 vLight)
{
    // pMesh的顶点结构
    struct MeshVertex {
        D3DXVECTOR3 p;
        D3DXVECTOR3 n;
        float u, v;
    };

    MeshVertex *pVertices;
    WORD       *pIndices;

    // 锁缓存
    pMesh->LockVertexBuffer(0L, (LPVOID*)&pVertices);
    pMesh->LockIndexBuffer(0L, (LPVOID*)&pIndices);
    DWORD dwNumFaces = pMesh->GetNumFaces();

    // 分配一个临时的索引数组
    WORD *pEdges = new WORD[dwNumFaces * 6];

    if (pEdges == NULL)
    {
        pMesh->UnlockVertexBuffer();
        pMesh->UnlockIndexBuffer();
        return E_OUTOFMEMORY;
    }

    DWORD dwNumEdges = 0;

    // 对每个片面进行计算
    for (DWORD i = 0; i < dwNumFaces; ++i)
    {
        WORD wFace0 = pIndices[3 * i + 0];
        WORD wFace1 = pIndices[3 * i + 1];
        WORD wFace2 = pIndices[3 * i + 2];

        // 一个面的三个顶点坐标
        D3DXVECTOR3 v0 = pVertices[wFace0].p;
        D3DXVECTOR3 v1 = pVertices[wFace1].p;
        D3DXVECTOR3 v2 = pVertices[wFace2].p;

        // 计算法线是否向光
        D3DXVECTOR3 vCross1(v2 - v1);
        D3DXVECTOR3 vCross2(v1 - v0);
        D3DXVECTOR3 vNormal;
        D3DXVec3Cross(&vNormal, &vCross1, &vCross2);

        if (D3DXVec3Dot(&vNormal, &vLight) >= 0.0f)
        {
            AddEdge(pEdges, dwNumEdges, wFace0, wFace1);
            AddEdge(pEdges, dwNumEdges, wFace1, wFace2);
            AddEdge(pEdges, dwNumEdges, wFace2, wFace0);
        }
    }

    // pEdges中仅剩pMesh的边缘顶点,对每条边的两个顶点按光照的方向进行延伸
    // 最终构建一个完整的阴影体
    for (DWORD i = 0; i < dwNumEdges; ++i)
    {
        D3DXVECTOR3 v1 = pVertices[pEdges[2 * i + 0]].p;
        D3DXVECTOR3 v2 = pVertices[pEdges[2 * i + 1]].p;
        D3DXVECTOR3 v3 = v1 + vLight * 200;
        D3DXVECTOR3 v4 = v2 + vLight * 200;

        // 封边操作
        m_pVertices[m_dwNumVertices++] = v1;
        m_pVertices[m_dwNumVertices++] = v2;
        m_pVertices[m_dwNumVertices++] = v3;

        m_pVertices[m_dwNumVertices++] = v2;
        m_pVertices[m_dwNumVertices++] = v4;
        m_pVertices[m_dwNumVertices++] = v3;
    }

    // Delete the temporary edge list
    delete[] pEdges;

    // Unlock the geometry buffers
    pMesh->UnlockVertexBuffer();
    pMesh->UnlockIndexBuffer();

    return S_OK;
}
Esempio n. 28
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();
	}
}
//------------------------------------------------------------------------------------------------
// Name:  CreateTerrainMesh
// Desc:  
//------------------------------------------------------------------------------------------------
bool CreateTerrainMesh(LPDIRECT3DDEVICE9 d3dDevice, LPD3DXMESH* terrainMesh)
{
    // Calculate the number of faces and vertices required
    const unsigned int faces = (TMS_COUNT + 3) * 2;
    const unsigned int vertices = (TMS_COUNT + 3) * 4;

    // The internal terrain mesh
    LPD3DXMESH internalTerrainMesh;

    // Create the mesh
    HRESULT hr = D3DXCreateMeshFVF(faces, vertices, D3DXMESH_MANAGED, D3DFVF_GEOMETRYVERTEX, d3dDevice, &internalTerrainMesh);
    if (APP_ERROR(FAILED(hr))("Unable to create the terrain mesh"))
        return false;

    // Lock the mesh buffers
    GeometryVertex* lockedVertices = 0;
    WORD* lockedIndices = 0;
    DWORD* lockedAttributes = 0;
    if (APP_ERROR(FAILED(internalTerrainMesh->LockAttributeBuffer(0, &lockedAttributes)) ||
                   FAILED(internalTerrainMesh->LockVertexBuffer(0, (VOID**)&lockedVertices)) ||
                   FAILED(internalTerrainMesh->LockIndexBuffer(0, (VOID**)&lockedIndices)))("Unable to lock terrain mesh"))
    {
        // Deallocate the mesh
        SAFE_RELEASE(internalTerrainMesh);

        // Exit the method
        return false;
    }

    // Vertices that will be rotated 4x about Y at
    // 90-degree intervals to produce the wall mesh
    GeometryVertex wallSide[] = {
        { -0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { -0.5f, -1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // The flat square with unit size
    GeometryVertex flat[] = {
        { -0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the high-corner meshes,
    // with the high corner in the north-west
    GeometryVertex highCorner[] = {
        { -0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the low-corner meshes,
    // with the low corner in the north-west
    GeometryVertex lowCorner[] = {
        { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the high-side meshes,
    // with the high side to the north
    GeometryVertex highSide[] = {
        { -0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the low-corner meshes,
    // with the low corner in the north-west
    GeometryVertex raisedLowCorner[] = {
        { -0.5f,  0.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f, +1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f, +1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f, +1.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // Geometry template for the low-side meshes,
    // with the low side to the north
    GeometryVertex lowSide[] = {
        { -0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        { +0.5f, -1.0f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
        { -0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
        { +0.5f,  0.0f, +0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
    };

    // The subset that is currently being written
    unsigned int currentSubset = TMS_WALL_SIDES;

    // Copy the wall first--it does not have any texture rotations
    lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 0.0f * D3DX_PI / 2.0f);
    lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 1.0f * D3DX_PI / 2.0f);
    lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 2.0f * D3DX_PI / 2.0f);
    lockedVertices = CopyYRotatedGeometry(lockedVertices, wallSide, 4, 3.0f * D3DX_PI / 2.0f);

    // Copy four sets of squares
    lockedIndices = PrintSquareIndices(lockedIndices, 0, 4);
    lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 4);

    // Move to the next subset
    currentSubset++;

    // Write the flat mesh first, since it only has texture rotations
    for (unsigned int textureDirection = 0; textureDirection < 4; ++textureDirection, ++currentSubset)
    {
        SetTerrainTexcoords(flat, textureDirection);
        lockedVertices = CopyYRotatedGeometry(lockedVertices, flat, 4, 0.0f);
        lockedIndices = PrintSquareIndices(lockedIndices, 4 + currentSubset - 1, 1);
        lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 1);
    }

    // Repeat for all combinations of texture direction and rotation for the remaining types
    for (int type = 0; type < 5; ++type)
    {
        GeometryVertex* sourceGeometry;
        switch(type)
        {
            case 0: sourceGeometry = highCorner; break;
            case 1: sourceGeometry = lowCorner;  break;
            case 2: sourceGeometry = highSide;   break;
            case 3: sourceGeometry = raisedLowCorner; break;
            case 4: sourceGeometry = lowSide;    break;
        }

        // Repeat for all rotations
        for (int rotation = 0; rotation < 4; ++rotation)
        {
            // Calculate the rotation angle
            float rotationAngle = D3DX_PI / 2.0f * rotation;

            // Repeat for all texture directions
            for (unsigned int textureDirection = 0; textureDirection < 4; ++textureDirection, ++currentSubset)
            {
                // Reverse the rotation of the texture by the rotation of the element so that we get
                // consistent texture directions (i.e. north is texture-up on all tiles)
                SetTerrainTexcoords(sourceGeometry, (textureDirection - rotation + 4) % 4);
                lockedVertices = CopyYRotatedGeometry(lockedVertices, sourceGeometry, 4, rotationAngle);
                lockedIndices = PrintSquareIndices(lockedIndices, 4 + currentSubset - 1, 1);
                lockedAttributes = PrintAttributes(lockedAttributes, currentSubset, 1);
            }
        }
    }

    // Unlock the buffers
    internalTerrainMesh->UnlockVertexBuffer();
    internalTerrainMesh->UnlockIndexBuffer();
    internalTerrainMesh->UnlockAttributeBuffer();

    // Normalize
    //CONFIRM(SUCCEEDED(D3DXComputeNormals(internalTerrainMesh, NULL)));

    // Assign the output mesh
    *terrainMesh = internalTerrainMesh;

    // Success
    return true;
}
Esempio n. 30
0
HRESULT InitMesh()
{
	// Create mesh
	HRESULT hr = D3DXCreateMeshFVF(
		NumTriangles, 
		NumVertex, 
		D3DXMESH_MANAGED | D3DXMESH_32BIT,
		Vertex_FVF, 
		g_pd3dDevice,
		&g_pMesh);
	if (FAILED(hr))
	{
		return E_FAIL;
	}

	// Define the 8 vertex of the cube
	D3DXVECTOR3 vertex[] =
	{
		D3DXVECTOR3(-0.5f, -0.5f, -0.5f),
		D3DXVECTOR3( 0.5f, -0.5f, -0.5f),
		D3DXVECTOR3( 0.5f,  0.5f, -0.5f),
		D3DXVECTOR3(-0.5f,  0.5f, -0.5f),

		D3DXVECTOR3(-0.5f, -0.5f,  0.5f),
		D3DXVECTOR3( 0.5f, -0.5f,  0.5f),
		D3DXVECTOR3( 0.5f,  0.5f,  0.5f),
		D3DXVECTOR3(-0.5f,  0.5f,  0.5f),
	};

	// Lock vertex buffer and copy data
	void* pVertices = NULL;
	g_pMesh->LockVertexBuffer(0, &pVertices);
	memcpy(pVertices, vertex, sizeof(vertex));
	g_pMesh->UnlockVertexBuffer();

	// Define 36 index of the cube
	DWORD index[] = 
	{
		// Front face
		0, 3, 1,
		3, 2, 1,

		// Back face
		5, 6, 2,
		6, 7, 2,

		// Left face
		4, 7, 0,
		7, 3, 0,

		// Right face
		1, 2, 5,
		2, 6, 5,

		// Top face
		3, 7, 2,
		7, 6, 2,

		// Bottom face
		4, 0, 5,
		0, 1, 5,
	};
	
	// Lock index buffer and copy data
	DWORD* pIndices = NULL;
	g_pMesh->LockIndexBuffer(0, (void**)&pIndices);
	memcpy(pIndices, index, sizeof(index));
	g_pMesh->UnlockIndexBuffer();

	// Compute normals
	D3DXComputeNormals(g_pMesh, 0);

	return D3D_OK;
}