示例#1
0
//-------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: 화면크기가 변했을때 호출됨
//       확보한 메모리는 InvalidateDeviceObjects()에서 해제
//-------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
	// 이펙트
	if(m_pEffect) m_pEffect->OnResetDevice();

	// 메시
	m_pMeshBg->RestoreDeviceObjects( m_pd3dDevice );

	//---------------------------------------------------------
	// FVF로 처리하지 않은 정점선언은 직접 처리
	//---------------------------------------------------------
	if( m_pMesh && m_pMesh->GetSysMemMesh() ){
		LPD3DXMESH pMesh;

		m_pMesh->GetSysMemMesh()->CloneMesh(
			m_pMesh->GetSysMemMesh()->GetOptions(), decl,
			m_pd3dDevice, &pMesh );
		D3DXComputeNormals( pMesh, NULL );
		D3DXComputeTangent( pMesh, 0, 0, 0, TRUE, NULL );

		SAFE_RELEASE(m_pMesh->m_pLocalMesh);
		m_pMesh->m_pLocalMesh = pMesh;
	}

    // 렌더링 상태설정
    RS( D3DRS_ZENABLE,        TRUE );
	RS( D3DRS_LIGHTING, FALSE );
    
    SAMP( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    SAMP( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
    SAMP( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
    SAMP( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );

    // 뷰행렬
    D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );

    // 투영행렬
    FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );

    // 폰트
    m_pFont->RestoreDeviceObjects();

	return S_OK;
}
示例#2
0
HRESULT RacorX8::LoadXFile(const LPSTR name)
{
	HRESULT hr;
	LPD3DXMESH pMesh, pClone;

	if (FAILED(D3DXLoadMeshFromX(name, D3DXMESH_SYSTEMMEM, m_spDevice.get(), NULL, NULL, NULL, &pMesh)))
	{
		MessageBox(m_hWnd, L"D3DXLoadMeshFromX failed!", L"Error", 0);
		return E_FAIL;
	}

	hr = pMesh->CloneMeshFVF(D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE3(1), m_spDevice.get(), &pClone);
	if (FAILED(hr))
	{
		MessageBox(m_hWnd, L"CloneMeshFVF failed!", L"Error", 0);
		return E_FAIL;
	}

	hr = D3DXComputeTangent(pMesh, 0, pClone, 1, D3DX_COMP_TANGENT_NONE, TRUE, NULL);
	if (FAILED(hr))
	{
		MessageBox(m_hWnd, L"D3DXComputeTangent failed!", L"Error", 0);
		return E_FAIL;
	}

	IDirect3DIndexBuffer8* ib;
	hr = pClone->GetIndexBuffer(&ib);
	m_spIB.reset(ib, [](IDirect3DIndexBuffer8* ib){ib->Release(); });
	IDirect3DVertexBuffer8* vb;
	hr = pClone->GetVertexBuffer(&vb);
	m_spVB.reset(vb, [](IDirect3DVertexBuffer8* vb){vb->Release(); });

	m_iNumTriangles = pClone->GetNumFaces();
	m_iNumVertices = pClone->GetNumVertices();

	pMesh->Release();
	pClone->Release();
	return S_OK;
}
示例#3
0
//-------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: ȭ��ũ�Ⱑ �������� ȣ���
//       Ȯ���� �޸𸮴� InvalidateDeviceObjects()���� ����
//-------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    HRESULT hr;

	//---------------------------------------------------------
	// ����� ������ HDR ���� ������Ÿ��
	//---------------------------------------------------------
    hr = m_pd3dDevice->CreateTexture(
				m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 
                1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, 
                D3DPOOL_DEFAULT, &m_pTexScene, NULL);
    if( FAILED(hr) ) return hr;
	hr = m_pTexScene->GetSurfaceLevel( 0, &m_pSurfScene );
    if( FAILED(hr) ) return hr;

	//---------------------------------------------------------
	// ��ҹ���
	//---------------------------------------------------------
	// ��ҹ����� �⺻ũ��(4�� ���)
    m_dwCropWidth  = m_d3dsdBackBuffer.Width  - m_d3dsdBackBuffer.Width  % 4;
    m_dwCropHeight = m_d3dsdBackBuffer.Height - m_d3dsdBackBuffer.Height % 4;

    hr = m_pd3dDevice->CreateTexture(
				m_dwCropWidth / 4, m_dwCropHeight / 4, 
                1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F,
				D3DPOOL_DEFAULT, &m_pTexSceneScaled, NULL);
    if( FAILED(hr) ) return hr;
	hr = m_pTexSceneScaled->GetSurfaceLevel( 0, &m_pSurfSceneScaled );
    if( FAILED(hr) ) return hr;

	//---------------------------------------------------------
	// �ֵ�����
	//---------------------------------------------------------
    hr = m_pd3dDevice->CreateTexture(
				m_dwCropWidth / 4 + 2, m_dwCropHeight / 4 + 2, 
                1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
				D3DPOOL_DEFAULT, &m_pTexBrightPass, NULL);
    if( FAILED(hr) ) return hr;
	hr = m_pTexBrightPass->GetSurfaceLevel( 0, &m_pSurfBrightPass );
    if( FAILED(hr) ) return hr;
	// �ֺ��θ� �˰�ĥ�Ѵ�
	m_pd3dDevice->ColorFill( m_pSurfBrightPass, NULL
								, D3DCOLOR_ARGB(0, 0, 0, 0) );

	//---------------------------------------------------------
	// ������ �ʵ��� �帴�ϰ� ������ �ؽ�ó
	//---------------------------------------------------------
    hr = m_pd3dDevice->CreateTexture(
				m_dwCropWidth / 4 + 2, m_dwCropHeight / 4 + 2, 
                1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
				D3DPOOL_DEFAULT, &m_pTexStarSource, NULL);
    if( FAILED(hr) ) return hr;
	hr = m_pTexStarSource->GetSurfaceLevel( 0, &m_pSurfStarSource );
    if( FAILED(hr) ) return hr;
	// �ֺ��θ� �˰�ĥ�Ѵ�
	m_pd3dDevice->ColorFill( m_pSurfStarSource, NULL
								, D3DCOLOR_ARGB(0, 0, 0, 0) );

	//---------------------------------------------------------
	// �����ؽ�ó
	//---------------------------------------------------------
    for(int i=0; i < NUM_STAR_TEXTURES; i++ ) {
        hr = m_pd3dDevice->CreateTexture(
			    m_dwCropWidth /4, m_dwCropHeight / 4,
                1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F,
				D3DPOOL_DEFAULT, &m_apTexStar[i], NULL );
        if( FAILED(hr) ) return hr;
		hr = m_apTexStar[i]->GetSurfaceLevel( 0, &m_apSurfStar[i] );
		if( FAILED(hr) ) return hr;
    }

	// ����Ʈ
	if(m_pEffect) m_pEffect->OnResetDevice();

	// �޽�
	m_pMeshBg->RestoreDeviceObjects( m_pd3dDevice );

	//---------------------------------------------------------
	// �޽����� ó��
	//---------------------------------------------------------
	if( m_pMesh && m_pMesh->GetSysMemMesh() ){
		LPD3DXMESH pMesh;

		m_pMesh->GetSysMemMesh()->CloneMesh(
			m_pMesh->GetSysMemMesh()->GetOptions(), decl,
			m_pd3dDevice, &pMesh );
		D3DXComputeNormals( pMesh, NULL );
		D3DXComputeTangent( pMesh, 0, 0, 0, TRUE, NULL );

		SAFE_RELEASE(m_pMesh->m_pLocalMesh);
		m_pMesh->m_pLocalMesh = pMesh;
	}

    // ������ ���¼���
    RS( D3DRS_ZENABLE,        TRUE );
	RS( D3DRS_LIGHTING, FALSE );
    
	// �����
    D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &m_mView, &vFromPt, &vLookatPt, &vUpVec );

    // �������
    FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );

    // ��Ʈ
    m_pFont->RestoreDeviceObjects();

	return S_OK;
}
示例#4
0
//**関数***************************************************************************
// メッシュ初期化
//*********************************************************************************
bool CMesh::Initialize(LPCTSTR pszFName)
{
	TCHAR			szMsg[MAX_PATH + 32];
	TCHAR			szDir[_MAX_DIR];
	TCHAR			szCurrentDir[_MAX_PATH];

	LPD3DXBUFFER	pD3DXMtrlBuffer = NULL;

	// フォルダ名を抽出
	_tsplitpath(pszFName, NULL, szDir, NULL, NULL);

	// Xファイルからメッシュデータを読み込む
	HRESULT hr = D3DXLoadMeshFromX(pszFName, D3DXMESH_SYSTEMMEM, CGraphics::GetDevice(),
		NULL, &pD3DXMtrlBuffer, NULL, &m_dwNumMaterial, &m_pD3DMesh);
	if (FAILED(hr)) {
		_stprintf(szMsg, _T("Xファイル(%s)の読み込みに失敗しました。"), pszFName);
		MessageBox(NULL, szMsg, NULL, MB_OK);
		return false;
	}

	// FVF形式を補正(頂点フォーマットを変換)
	LPD3DXMESH pMeshTmp;
	DWORD dwFVF = m_pD3DMesh->GetFVF();
	if (dwFVF != FVF_BVERTEX) {
		hr = m_pD3DMesh->CloneMeshFVF(m_pD3DMesh->GetOptions(), FVF_BVERTEX,
			CGraphics::GetDevice(), &pMeshTmp);
		SAFE_RELEASE(m_pD3DMesh);
		if (FAILED(hr)) {
			SAFE_RELEASE(pD3DXMtrlBuffer);
			return false;
		}
		// 法線が無い場合は強制的に追加
		if ((dwFVF & D3DFVF_NORMAL) == 0) {
			D3DXComputeNormals(pMeshTmp, NULL);
		}
		m_pD3DMesh = pMeshTmp;
	}

	// 接ベクトルがない場合は強制的に追加
	D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE];
    D3DVERTEXELEMENT9 End = D3DDECL_END();
    int iElem;

	m_pD3DMesh->GetDeclaration(Declaration);
    BOOL bHasTangents = FALSE;
    for (iElem = 0; Declaration[iElem].Stream != End.Stream; iElem++)
    {
        if (Declaration[iElem].Usage == D3DDECLUSAGE_TANGENT)
        {
            bHasTangents = TRUE;
            break;
        }
    }

    // Update Mesh Semantics if changed
    if (!bHasTangents)
    {
        Declaration[iElem].Stream = 0;
        Declaration[iElem].Offset = (WORD)m_pD3DMesh->GetNumBytesPerVertex();
        Declaration[iElem].Type = D3DDECLTYPE_FLOAT3;
        Declaration[iElem].Method = D3DDECLMETHOD_DEFAULT;
        Declaration[iElem].Usage = D3DDECLUSAGE_TANGENT;
        Declaration[iElem].UsageIndex = 0;
        Declaration[iElem+1] = End;
        LPD3DXMESH pTempMesh;

		hr = m_pD3DMesh->CloneMesh(D3DXMESH_MANAGED, Declaration, CGraphics::GetDevice() , &pTempMesh);
        if (SUCCEEDED(hr))
        {
			SAFE_RELEASE(m_pD3DMesh);
			m_pD3DMesh = pTempMesh;
            //hr = D3DXComputeTangent(m_pMesh, 0, 0, D3DX_DEFAULT, TRUE, NULL);
			hr = D3DXComputeTangent(m_pD3DMesh , 0, 0, D3DX_DEFAULT, FALSE, NULL);
        }
    }

	// 属性テーブルを生成するための最適化
	hr = m_pD3DMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshTmp);
	if (SUCCEEDED(hr)) {
		m_pD3DMesh->Release();
		m_pD3DMesh = pMeshTmp;
	} else {
		SAFE_RELEASE(pD3DXMtrlBuffer);
		return false;
	}
	// 属性テーブル取得
	hr = m_pD3DMesh->GetAttributeTable(NULL, &m_dwAttr);
	if (FAILED(hr)) {
		SAFE_RELEASE(pD3DXMtrlBuffer);
		SAFE_RELEASE(m_pD3DMesh);
		return false;
	}
	m_pAttr = new D3DXATTRIBUTERANGE[m_dwAttr];
	hr = m_pD3DMesh->GetAttributeTable(m_pAttr, &m_dwAttr);
	// 頂点バッファ/インデックスバッファ固定
	LPVOID pVtx;
	m_pD3DMesh->LockVertexBuffer(D3DLOCK_READONLY, &pVtx);
	LPVOID pIdx;
	m_pD3DMesh->LockIndexBuffer(D3DLOCK_READONLY, &pIdx);
	// 抽出場所の確保
	m_dwVtx = m_pD3DMesh->GetNumVertices();
	m_pVtx = new BVERTEX[m_dwVtx];
	m_dwFace = m_pD3DMesh->GetNumFaces();
	m_dwIdx = m_dwFace * 3;
	m_pIdx = new WORD[m_dwIdx];
	m_pPiece = new PARTICLE[m_dwFace];
	m_pPieceVtx = new BVERTEX[m_dwIdx];
	// コピー
	CopyMemory(m_pVtx, pVtx, sizeof(BVERTEX) * m_dwVtx);
	CopyMemory(m_pIdx, pIdx, sizeof(WORD) * m_dwIdx);
	// 頂点バッファ/インデックスバッファ解放
	m_pD3DMesh->UnlockVertexBuffer();
	m_pD3DMesh->UnlockIndexBuffer();

	// カレントディレクトリを変更
	if (szDir[0]) {
		GetCurrentDirectory(_MAX_PATH, szCurrentDir);
		SetCurrentDirectory(szDir);
	}

	// マテリアル読み込み
	D3DXMATERIAL* pD3DMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
	m_pMaterial = new D3DMATERIAL9[m_dwNumMaterial];
	m_ppTexture = new LPDIRECT3DTEXTURE9[m_dwNumMaterial];
	for (DWORD i = 0; i < m_dwNumMaterial; i++) { 
		m_pMaterial[i] = pD3DMaterials[i].MatD3D;
		m_pMaterial[i].Ambient = m_pMaterial[i].Diffuse;
		m_ppTexture[i] = NULL;
		if (pD3DMaterials[i].pTextureFilename && pD3DMaterials[i].pTextureFilename[0]) {
			// テクスチャファイルを読み込む
			if (FAILED(D3DXCreateTextureFromFileA(CGraphics::GetDevice(),
				pD3DMaterials[i].pTextureFilename, &m_ppTexture[i]))) {
				_stprintf(szMsg, _T("テクスチャ(%hs)の読み込みに失敗しました。"),
					pD3DMaterials[i].pTextureFilename);
				MessageBox(NULL, szMsg, NULL, MB_OK);
			}
		}
	}

	// カレントディレクトリを元に戻す
	if (szDir[0])
		SetCurrentDirectory(szCurrentDir);

	pD3DXMtrlBuffer->Release();

	// 境界ボックス生成
	D3DXVECTOR3 vMin = m_pVtx[0].pos;
	D3DXVECTOR3 vMax = vMin;
	BVERTEX* pBVtx = m_pVtx + 1;
	for (DWORD i = 1; i < m_dwVtx; i++, pBVtx++) {
		if (vMin.x > pBVtx->pos.x)
			vMin.x = pBVtx->pos.x;
		if (vMin.y > pBVtx->pos.y)
			vMin.y = pBVtx->pos.y;
		if (vMin.z > pBVtx->pos.z)
			vMin.z = pBVtx->pos.z;
		if (vMax.x < pBVtx->pos.x)
			vMax.x = pBVtx->pos.x;
		if (vMax.y < pBVtx->pos.y)
			vMax.y = pBVtx->pos.y;
		if (vMax.z < pBVtx->pos.z)
			vMax.z = pBVtx->pos.z;
	}
	m_vHalf = (vMax - vMin) / 2.0f;
	m_vCenter = (vMax + vMin) / 2.0f;

	// 境界球の生成
	m_fRadius = 0.0f;
	float fR;
	for (DWORD i = 0; i < m_dwVtx; i++) {
		fR = D3DXVec3Length(&(m_pVtx[i].pos - m_vCenter));
		if (m_fRadius < fR)
			m_fRadius = fR;
	}

	// 境界球イメージの生成
	D3DXCreateSphere(CGraphics::GetDevice(),
		m_fRadius, 32, 16, &m_pSphere, NULL);

	// OBB生成
	float fWidth = vMax.x - vMin.x;
	float fHeight = vMax.y - vMin.y;
	float fDepth = vMax.z - vMin.z;

	m_vOBBHalf.x = fWidth / 2.0f;
	m_vOBBHalf.y = fHeight / 2.0f;
	m_vOBBHalf.z = fDepth / 2.0f;
	// OBBイメージの生成
	D3DXCreateBox(CGraphics::GetDevice() , 
		fWidth , fHeight , fDepth , &m_pBox , NULL);

	return true;
}
示例#5
0
/**
 * \brief callback called when a mesh data is encountered during the .x file load
 * \param Name - name of the Mesh (const char*)
 * \param meshData - the mesh data
 * \param materials - material array
 * \param effectInstances - effect files / settings for the mesh
 * \param numMaterials - number of materials in the mesh
 * \param adjacency - adjacency array 
 * \param pSkinInfo - skin info.
 * \param retNewMeshContainer - output pointer to assign our newly created mesh container
 * \return success code
 * \author Keith Ditchburn \date 17 July 2005
*/
HRESULT CMeshHierarchy::CreateMeshContainer(
    LPCSTR Name,
    CONST D3DXMESHDATA *meshData,
    CONST D3DXMATERIAL *materials,
    CONST D3DXEFFECTINSTANCE *effectInstances,
    DWORD numMaterials,
    CONST DWORD *adjacency,
    LPD3DXSKININFO pSkinInfo,
    LPD3DXMESHCONTAINER* retNewMeshContainer)
{    
	// Create a mesh container structure to fill and initilaise to zero values
	// Note: I use my extended version of the structure (D3DXMESHCONTAINER_EXTENDED) defined in MeshStructures.h
	D3DXMESHCONTAINER_EXTENDED *newMeshContainer=new D3DXMESHCONTAINER_EXTENDED;
	ZeroMemory(newMeshContainer, sizeof(D3DXMESHCONTAINER_EXTENDED));

	// Always a good idea to initialise return pointer before proceeding
	*retNewMeshContainer = 0;

	// The mesh name (may be 0) needs copying over
	if (Name && strlen(Name))
	{
		newMeshContainer->Name=CUtility::DuplicateCharString(Name);
		CUtility::DebugString("Added mesh: "+ToString(Name)+"\n");
	}
	else
	{
		CUtility::DebugString("Added Mesh: no name given\n");
	}

	// The mesh type (D3DXMESHTYPE_MESH, D3DXMESHTYPE_PMESH or D3DXMESHTYPE_PATCHMESH)
	if (meshData->Type!=D3DXMESHTYPE_MESH)
	{
		// This demo does not handle mesh types other than the standard
		// Other types are D3DXMESHTYPE_PMESH (progressive mesh) and D3DXMESHTYPE_PATCHMESH (patch mesh)
		DestroyMeshContainer(newMeshContainer);
		return E_FAIL;
	}

	newMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;
	
	// Adjacency data - holds information about triangle adjacency, required by the ID3DMESH object
	DWORD dwFaces = meshData->pMesh->GetNumFaces();
	newMeshContainer->pAdjacency = new DWORD[dwFaces*3];
	memcpy(newMeshContainer->pAdjacency, adjacency, sizeof(DWORD) * dwFaces*3);
	
	// Get the Direct3D device, luckily this is held in the mesh itself (Note: must release it when done with it)
	LPDIRECT3DDEVICE9 pd3dDevice = 0;
	meshData->pMesh->GetDevice(&pd3dDevice);


	D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
	meshData->pMesh->GetDeclaration(decl);

	HRESULT res;

	DWORD dwVertexStride = meshData->pMesh->GetNumBytesPerVertex ();
	DWORD dwNumDeclarations = 0;
	bool haveNormals = false;

	for (int i=0; (i < MAX_FVF_DECL_SIZE) && (decl[i].Stream != 0xFF); i++)	{
		if (decl[dwNumDeclarations].Usage == D3DDECLUSAGE_NORMAL) 
			haveNormals = true;
		if (decl[dwNumDeclarations].Usage == D3DDECLUSAGE_TANGENT) {
			dwNumDeclarations = 0;
			break;
		}
		dwNumDeclarations++;
	}

	if (dwNumDeclarations) {
		if (!haveNormals) {
			// normals	
			decl[dwNumDeclarations].Stream = 0;	
			decl[dwNumDeclarations].Offset = (WORD)dwVertexStride;	
			decl[dwNumDeclarations].Type = D3DDECLTYPE_FLOAT3;	
			decl[dwNumDeclarations].Method = D3DDECLMETHOD_DEFAULT;	
			decl[dwNumDeclarations].Usage = D3DDECLUSAGE_NORMAL;	
			decl[dwNumDeclarations].UsageIndex = 0;

			dwVertexStride += sizeof(float)*3;
			dwNumDeclarations++;

		}

		// tangent	
		decl[dwNumDeclarations].Stream = 0;	
		decl[dwNumDeclarations].Offset = (WORD)dwVertexStride;	
		decl[dwNumDeclarations].Type = D3DDECLTYPE_FLOAT3;	
		decl[dwNumDeclarations].Method = D3DDECLMETHOD_DEFAULT;	
		decl[dwNumDeclarations].Usage = D3DDECLUSAGE_TANGENT;	
		decl[dwNumDeclarations].UsageIndex = 0;

		dwNumDeclarations++;

		// ending element	
		memset (&decl[dwNumDeclarations], 0, sizeof(D3DVERTEXELEMENT9));	
		decl[dwNumDeclarations].Stream = 0xFF;	
		decl[dwNumDeclarations].Type = D3DDECLTYPE_UNUSED;
	}

	res = meshData->pMesh->CloneMesh(meshData->pMesh->GetOptions(),decl,pd3dDevice,&newMeshContainer->MeshData.pMesh); 
	assert(res == D3D_OK);

	if (!haveNormals) {
		res = D3DXComputeNormals(newMeshContainer->MeshData.pMesh,newMeshContainer->pAdjacency); // compute normals                                      
		assert(res == D3D_OK);
	}

	res = D3DXComputeTangent(newMeshContainer->MeshData.pMesh,0,0,1,TRUE,NULL); // compute tangent(u)                                       
	assert(res == D3D_OK);

	//newMeshContainer->MeshData.pMesh=meshData->pMesh;
	newMeshContainer->MeshData.pMesh->AddRef();

	// Create material and texture arrays. Note that I always want to have at least one
	newMeshContainer->NumMaterials = max(numMaterials,1);
	newMeshContainer->exMaterials = new D3DMATERIAL9[newMeshContainer->NumMaterials];
	newMeshContainer->exTextures  = new LPDIRECT3DTEXTURE9[newMeshContainer->NumMaterials];

	ZeroMemory(newMeshContainer->exTextures, sizeof(LPDIRECT3DTEXTURE9) * newMeshContainer->NumMaterials);

	if (numMaterials>0)
	{
		// Load all the textures and copy the materials over		
		for(DWORD i = 0; i < numMaterials; ++i)
		{
			newMeshContainer->exTextures[i] = 0;	
			newMeshContainer->exMaterials[i]=materials[i].MatD3D;

			if(materials[i].pTextureFilename)
			{
				std::string texturePath(materials[i].pTextureFilename);
				if (CUtility::FindFile(&texturePath))
				{
					// Use the D3DX function to load the texture
					if(FAILED(D3DXCreateTextureFromFile(pd3dDevice, texturePath.c_str(),
						&newMeshContainer->exTextures[i])))
					{
						CUtility::DebugString("Could not load texture: "+texturePath+"\n");					
					}
				}
				else
				{
					CUtility::DebugString("Could not find texture: "+ToString(materials[i].pTextureFilename)+"\n");					
				}
			}
		}
	}
	else    
	// make a default material in the case where the mesh did not provide one
    {
		ZeroMemory(&newMeshContainer->exMaterials[0], sizeof( D3DMATERIAL9 ) );
        newMeshContainer->exMaterials[0].Diffuse.r = 0.5f;
        newMeshContainer->exMaterials[0].Diffuse.g = 0.5f;
        newMeshContainer->exMaterials[0].Diffuse.b = 0.5f;
        newMeshContainer->exMaterials[0].Specular = newMeshContainer->exMaterials[0].Diffuse;
		newMeshContainer->exTextures[0]=0;
    }

	// If there is skin data associated with the mesh copy it over
	if (pSkinInfo)
	{
		// save off the SkinInfo
	    newMeshContainer->pSkinInfo = pSkinInfo;
	    pSkinInfo->AddRef();

	    // Need an array of offset matrices to move the vertices from the figure space to the bone's space
	    UINT numBones = pSkinInfo->GetNumBones();
	    newMeshContainer->exBoneOffsets = new D3DXMATRIX[numBones];

		// Create the arrays for the bones and the frame matrices
		newMeshContainer->exFrameCombinedMatrixPointer = new D3DXMATRIX*[numBones];

	    // get each of the bone offset matrices so that we don't need to get them later
	    for (UINT i = 0; i < numBones; i++)
	        newMeshContainer->exBoneOffsets[i] = *(newMeshContainer->pSkinInfo->GetBoneOffsetMatrix(i));

		CUtility::DebugString("Mesh has skinning info.\n Number of bones is: "+ToString(numBones)+"\n");
        // Note: in the Microsoft samples a GenerateSkinnedMesh function is called here in order to prepare
		// the skinned mesh data for optimial hardware acceleration. As mentioned in the notes this sample
		// does not do hardware skinning but instead uses software skinning.
	}
	else	
	{
		// No skin info so 0 all the pointers
		newMeshContainer->pSkinInfo = 0;
		newMeshContainer->exBoneOffsets = 0;
		newMeshContainer->exSkinMesh = 0;
		newMeshContainer->exFrameCombinedMatrixPointer = 0;
	}

	// When we got the device we caused an internal reference count to be incremented
	// So we now need to release it
	pd3dDevice->Release();

	// The mesh may contain a reference to an effect file
	if (effectInstances)
	{
		if (effectInstances->pEffectFilename)
			CUtility::DebugString("This .x file references an effect file. Effect files are not handled by this demo\n");
	}
	
	// Set the output mesh container pointer to our newly created one
	*retNewMeshContainer = newMeshContainer;    

	return S_OK;
}