Exemplo n.º 1
0
//-----------------------------------------------------------------------------
// Name:
// Desc:
//-----------------------------------------------------------------------------
HRESULT CD3DMesh::SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF )
{
    LPD3DXMESH pTempSysMemMesh = NULL;
    LPD3DXMESH pTempLocalMesh  = NULL;

    if( m_pSysMemMesh )
    {
        if( FAILED( m_pSysMemMesh->CloneMeshFVF( D3DXMESH_SYSTEMMEM, dwFVF,
                                                 pd3dDevice, &pTempSysMemMesh ) ) )
            return E_FAIL;
    }
    if( m_pLocalMesh )
    {
        if( FAILED( m_pLocalMesh->CloneMeshFVF( 0L, dwFVF, pd3dDevice,
                                                &pTempLocalMesh ) ) )
        {
            SAFE_RELEASE( pTempSysMemMesh );
            return E_FAIL;
        }
    }

    SAFE_RELEASE( m_pSysMemMesh );
    SAFE_RELEASE( m_pLocalMesh );

    if( pTempSysMemMesh ) m_pSysMemMesh = pTempSysMemMesh;
    if( pTempLocalMesh )  m_pLocalMesh  = pTempLocalMesh;

    // Compute normals in case the meshes have them
    if( m_pSysMemMesh )
        D3DXComputeNormals( m_pSysMemMesh, NULL );
    if( m_pLocalMesh )
        D3DXComputeNormals( m_pLocalMesh, NULL );

    return S_OK;
}
Exemplo n.º 2
0
HRESULT LoadMesh(IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh)
{
    ID3DXMesh* pMesh = NULL;
    WCHAR str[MAX_PATH];
    HRESULT hr;

    V_RETURN(DXUTFindDXSDKMediaFileCch(str, MAX_PATH, strFileName));

    V_RETURN(D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh));

    DWORD* rgdwAdjacency = NULL;

    if(!(pMesh->GetFVF() & D3DFVF_NORMAL))
    {
        ID3DXMesh* pTempMesh;
        V(pMesh->CloneMeshFVF(pMesh->GetOptions(),
                                pMesh->GetFVF() | D3DFVF_NORMAL,
                                pd3dDevice, &pTempMesh));
        V(D3DXComputeNormals(pTempMesh, NULL));

        SAFE_RELEASE(pMesh);
        pMesh = pTempMesh;
    }
   
    rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
    if(rgdwAdjacency == NULL)
        return E_OUTOFMEMORY;
    V(pMesh->GenerateAdjacency(1e-6f, rgdwAdjacency));
    V(pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL));
    delete []rgdwAdjacency;

    *ppMesh = pMesh;

    return S_OK;
}
Exemplo n.º 3
0
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF )
{
    LPD3DXMESH pTempMesh = NULL;

    if( m_pMesh )
    {
        if( FAILED( m_pMesh->CloneMeshFVF( m_pMesh->GetOptions(), dwFVF,
                                           pd3dDevice, &pTempMesh ) ) )
        {
            SAFE_RELEASE( pTempMesh );
            return E_FAIL;
        }

        DWORD dwOldFVF = 0;
        dwOldFVF = m_pMesh->GetFVF();
        SAFE_RELEASE( m_pMesh );
        m_pMesh = pTempMesh;

        // Compute normals if they are being requested and
        // the old mesh does not have them.
        if( !(dwOldFVF & D3DFVF_NORMAL) && dwFVF & D3DFVF_NORMAL )
        {
            D3DXComputeNormals( m_pMesh, NULL );
        }
    }

    return S_OK;
}
Exemplo n.º 4
0
//初期化。
void Model::Init(LPDIRECT3DDEVICE9 pd3dDevice, const char* fileName)
{
	Release();
	//Xファイルをロード。
	LPD3DXBUFFER pD3DXMtrlBuffer;
	//Xファイルのロード。
	D3DXLoadMeshFromX(fileName, D3DXMESH_SYSTEMMEM,
		pd3dDevice, NULL,
		&pD3DXMtrlBuffer, NULL, &numMaterial,
		&mesh);
	//法線が存在するか調べる。
	if ((mesh->GetFVF() & D3DFVF_NORMAL) == 0) {
		//法線がないので作成する。
		ID3DXMesh* pTempMesh = NULL;

		mesh->CloneMeshFVF(mesh->GetOptions(),
			mesh->GetFVF() | D3DFVF_NORMAL, g_pd3dDevice, &pTempMesh);

		D3DXComputeNormals(pTempMesh, NULL);
		mesh->Release();
		mesh = pTempMesh;

	}

	// マテリアルバッファを取得。
	D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();

	//テクスチャをロード。
	textures = new LPDIRECT3DTEXTURE9[numMaterial];
	for (DWORD i = 0; i < numMaterial; i++)
	{
		textures[i] = NULL;
		//テクスチャを作成する。
		D3DXCreateTextureFromFileA(pd3dDevice,
			d3dxMaterials[i].pTextureFilename,
			&textures[i]);
	}
	// マテリアルバッファを解放。
	pD3DXMtrlBuffer->Release();

	//シェーダーをコンパイル。
	LPD3DXBUFFER  compileErrorBuffer = NULL;
	//シェーダーをコンパイル。
	HRESULT hr = D3DXCreateEffectFromFile(
		pd3dDevice,
		"basic.fx",
		NULL,
		NULL,
		D3DXSHADER_SKIPVALIDATION,
		NULL,
		&effect,
		&compileErrorBuffer
		);
	if (hr != S_OK) {
		MessageBox(NULL, (char*)(compileErrorBuffer->GetBufferPointer()), "error", MB_OK);
		std::abort();
	}
}
Exemplo n.º 5
0
//
// MeshNode::VOnRestore				-  3rd Edition, Chapter 14, page 506
//
// This function loads the Mesh and ensures the Mesh has normals; it also optimizes the 
// Mesh for the graphics card's vertex cache, which improves performance by organizing 
// the internal triangle list for less cache misses.
//
HRESULT D3DMeshNode9::VOnRestore(Scene *pScene)
{
	if (m_XFileName.empty())
	{
		SetRadius(CalcBoundingSphere());
		return D3DSceneNode9::VOnRestore(pScene);
	}

	// Change post press - release the Mesh only if we have a valid Mesh file name to load.
	// Otherwise we likely created it on our own, and needs to be kept.
	SAFE_RELEASE(m_pMesh);

    WCHAR str[MAX_PATH];
    HRESULT hr;

    // Load the Mesh with D3DX and get back a ID3DXMesh*.  For this
    // sample we'll ignore the X file's embedded materials since we know 
    // exactly the model we're loading.  See the Mesh samples such as
    // "OptimizedMesh" for a more generic Mesh loading example.
	V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, m_XFileName.c_str() ) );

    V_RETURN( D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, DXUTGetD3D9Device(), NULL, NULL, NULL, NULL, &m_pMesh) );

    DWORD *rgdwAdjacency = NULL;

    // Make sure there are normals which are required for lighting
    if( !(m_pMesh->GetFVF() & D3DFVF_NORMAL) )
    {
        ID3DXMesh* pTempMesh;
        V( m_pMesh->CloneMeshFVF( m_pMesh->GetOptions(), 
                                  m_pMesh->GetFVF() | D3DFVF_NORMAL, 
                                  DXUTGetD3D9Device(), &pTempMesh ) );
        V( D3DXComputeNormals( pTempMesh, NULL ) );

        SAFE_RELEASE( m_pMesh );
        m_pMesh = pTempMesh;
    }

    // Optimize the Mesh for this graphics card's vertex cache 
    // so when rendering the Mesh's triangle list the vertices will 
    // cache hit more often so it won't have to re-execute the vertex shader 
    // on those vertices so it will improve perf.     

    rgdwAdjacency = GCC_NEW DWORD[m_pMesh->GetNumFaces() * 3];
    if( rgdwAdjacency == NULL )
        return E_OUTOFMEMORY;
    V( m_pMesh->ConvertPointRepsToAdjacency(NULL, rgdwAdjacency) );
    V( m_pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
    
	SAFE_DELETE_ARRAY(rgdwAdjacency);

	SetRadius(CalcBoundingSphere());

    return D3DSceneNode9::VOnRestore(pScene);
}
Exemplo n.º 6
0
//-----------------------------------------------------------------------------
// Name: CD3DMesh::SetVertexDecl
// Desc: Convert the mesh to the format specified by the given vertex
//       declarations.
//-----------------------------------------------------------------------------
HRESULT CD3DMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, D3DVERTEXELEMENT9 *pDecl )
{
    LPD3DXMESH pTempSysMemMesh = NULL;
    LPD3DXMESH pTempLocalMesh  = NULL;

    if( m_pSysMemMesh )
    {
        if( FAILED( m_pSysMemMesh->CloneMesh( D3DXMESH_SYSTEMMEM, pDecl,
                                              pd3dDevice, &pTempSysMemMesh ) ) )
            return E_FAIL;
    }

    if( m_pLocalMesh )
    {
        if( FAILED( m_pLocalMesh->CloneMesh( 0L, pDecl, pd3dDevice,
                                             &pTempLocalMesh ) ) )
        {
            SAFE_RELEASE( pTempSysMemMesh );
            return E_FAIL;
        }
    }

    SAFE_RELEASE( m_pSysMemMesh );
    SAFE_RELEASE( m_pLocalMesh );

    if( pTempSysMemMesh )
    {
        m_pSysMemMesh = pTempSysMemMesh;
        // Compute normals in case the meshes have them
        D3DXComputeNormals( m_pSysMemMesh, NULL );
    }

    if( pTempLocalMesh )
    {
        m_pLocalMesh = pTempLocalMesh;
        // Compute normals in case the meshes have them
        D3DXComputeNormals( m_pLocalMesh, NULL );
    }

    return S_OK;
}
Exemplo n.º 7
0
ID3DXMesh* Mesh::GenerateNormals(ID3DXMesh* mesh, IDirect3DDevice9* d3d9Device)
{
    // see if we have texture coordinates
    D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
    DXCall(mesh->GetDeclaration(decl));
    bool foundTexCoord = false;
    for (UINT i = 0; i < MAX_FVF_DECL_SIZE; ++i)
    {
        if (decl[i].Stream == 0xFF)
            break;
        else if(decl[i].Usage == D3DDECLUSAGE_TEXCOORD && decl[i].UsageIndex == 0)
        {
            foundTexCoord = true;
            break;
        }
    }

    // Clone the mesh with a new declaration
    D3DVERTEXELEMENT9 tcDecl[] =
    {
        { 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
        { 0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,   0 },
        { 0, 24, D3DDECLTYPE_FLOAT2,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
        D3DDECL_END()
    };

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

    D3DVERTEXELEMENT9* newDecl;
    if (foundTexCoord)
        newDecl = tcDecl;
    else
        newDecl = noTCDecl;

    ID3DXMesh* clonedMesh = NULL;

    UINT options = D3DXMESH_MANAGED;
    if (indexType == Index32Bit)
        options |= D3DXMESH_32BIT;
    DXCall(mesh->CloneMesh(options, newDecl, d3d9Device, &clonedMesh));
    mesh->Release();

    // Generate the normals
    DXCall(D3DXComputeNormals(clonedMesh, &adjacency[0]));

    return clonedMesh;
}
Exemplo n.º 8
0
void MeshX::BuildSkinnedMesh()
{
	ID3DXMesh* oldMesh = allocMeshHierarchy.GetMeshList().front()->MeshData.pMesh;

	//compute normal
	D3DVERTEXELEMENT9 elements[MAX_FVF_DECL_SIZE];
	oldMesh->GetDeclaration(elements);

	ID3DXMesh* tempMesh = 0;
	ID3DXMesh* tempOpMesh = 0;
	oldMesh->CloneMesh(D3DXMESH_SYSTEMMEM, elements, pDevice, &tempMesh);
	 
	if( !HasNormals(tempMesh) )
		D3DXComputeNormals(tempMesh, 0);

	//optimize the mesh
	DWORD* adj = new DWORD[tempMesh->GetNumFaces()*3];
	ID3DXBuffer* remap = 0;
	tempMesh->GenerateAdjacency(0.00001f, adj);
	tempMesh->Optimize(D3DXMESH_SYSTEMMEM | D3DXMESHOPT_VERTEXCACHE | 
		D3DXMESHOPT_ATTRSORT, adj, 0, 0, &remap, &tempOpMesh);

	SafeRelease(tempMesh);

	// In the .X file (specifically the array DWORD vertexIndices[nWeights]
	// data member of the SkinWeights template) each bone has an array of
	// indices which identify the vertices of the mesh that the bone influences.
	// Because we have just rearranged the vertices (from optimizing), the vertex 
	// indices of a bone are obviously incorrect (i.e., they index to vertices the bone
	// does not influence since we moved vertices around).  In order to update a bone's 
	// vertex indices to the vertices the bone _does_ influence, we simply need to specify
	// where we remapped the vertices to, so that the vertex indices can be updated to 
	// match.  This is done with the ID3DXSkinInfo::Remap method.
	skinInfo->Remap(tempOpMesh->GetNumVertices(), 
		(DWORD*)remap->GetBufferPointer());
	SafeRelease(remap); // Done with remap info.

	DWORD        numBoneComboEntries = 0;
	ID3DXBuffer* boneComboTable      = 0;
	DWORD maxVertInfluences;
	skinInfo->ConvertToIndexedBlendedMesh(tempOpMesh, 0,  
		128, 0, 0, 0, 0, &maxVertInfluences,
		&numBoneComboEntries, &boneComboTable, &this->mesh);

	SafeRelease(tempOpMesh);
	SafeRelease(boneComboTable);
	delete[] adj;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
0
HRESULT Mesh::AdjustMeshDecl()
{
  HRESULT hr;
  
  LPD3DXMESH pInMesh = mMesh;
  LPD3DXMESH pOutMesh = NULL;

  D3DVERTEXELEMENT9 vertDecl[ MAX_FVF_DECL_SIZE ] =
  {
  {0,  0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
  {0,  12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
  {0,  24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},

	// exact SH-coefficients
  {0, 32, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 0},
	{0, 48, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 1},
  {0, 64, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 2},
  {0, 80, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 3},
  {0, 96, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 4},
  {0, 112, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 5},
  {0, 128, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 6},
	{0, 144, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 7},
	{0, 160, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDWEIGHT, 8},
	  
	{0, 176, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 2},
	{0, 188, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 3},
	D3DDECL_END()
  };
  
  hr = pInMesh->CloneMesh( pInMesh->GetOptions(), vertDecl, mDevice, &pOutMesh );
  PD( hr, L"clone mesh" );
  if( FAILED(hr) ) return hr;

  if( !DoesMeshHaveUsage( D3DDECLUSAGE_NORMAL ) )
  {
    hr = D3DXComputeNormals( pOutMesh, NULL );
    PD( hr, L"compute normals" );
    if( FAILED(hr) ) return hr;
  }

  ReleaseCOM( pInMesh )

  mMesh = pOutMesh;

  return D3D_OK;
}
Exemplo n.º 11
0
	Mymesh(LPDIRECT3DDEVICE9 pD3DDevice, LPSTR pFilename)
	{
		LPD3DXBUFFER materialsBuffer = NULL;
		LPD3DXMESH mesh = NULL;

		pd3d = pD3DDevice;

		// second null is D3DXEFFECTINSTANCE.
		if (FAILED(D3DXLoadMeshFromX(pFilename, D3DXMESH_SYSTEMMEM, pd3d, NULL,
			&materialsBuffer, NULL, &dwNumMaterials, &mesh))) 
		{
			// null everything
			pMesh = NULL;
			pMeshMaterials = NULL;
			pMeshTextures = NULL;

			return;
		}

		D3DXMATERIAL* matMaterials = (D3DXMATERIAL*)materialsBuffer->GetBufferPointer();

		pMeshMaterials = new D3DMATERIAL9[dwNumMaterials];
		pMeshTextures = new LPDIRECT3DTEXTURE9[dwNumMaterials];

		for (DWORD i = 0; i < dwNumMaterials; i++) 
		{
			pMeshMaterials[i] = matMaterials[i].MatD3D;

			// ambient color
			pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;

			if (FAILED(D3DXCreateTextureFromFile(pd3d, 
				matMaterials[i].pTextureFilename, 
				&pMeshTextures[i])))
			{
				pMeshTextures[i] = NULL;
			}
		}
		SafeRelease(materialsBuffer);

		mesh->CloneMeshFVF(D3DXMESH_MANAGED, MESH_D3DFVF_CUSTOMVERTEX, pd3d, &pMesh);
		SafeRelease(mesh);

		D3DXComputeNormals(pMesh,0);
	}
Exemplo n.º 12
0
//--------------------------------------------------------------------------------------
// This function loads the mesh and ensures the mesh has normals; it also optimizes the 
// mesh for the graphics card's vertex cache, which improves performance by organizing 
// the internal triangle list for less cache misses.
//--------------------------------------------------------------------------------------
HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh )
{
    ID3DXMesh* pMesh = NULL;
    WCHAR str[MAX_PATH];
    HRESULT hr;

    // Load the mesh with D3DX and get back a ID3DXMesh*.  For this
    // sample we'll ignore the X file's embedded materials since we know 
    // exactly the model we're loading.  See the mesh samples such as
    // "OptimizedMesh" for a more generic mesh loading example.
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) );
    V_RETURN( D3DXLoadMeshFromX( str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh ) );

    DWORD* rgdwAdjacency = NULL;

    // Make sure there are normals which are required for lighting
    if( !( pMesh->GetFVF() & D3DFVF_NORMAL ) )
    {
        ID3DXMesh* pTempMesh;
        V( pMesh->CloneMeshFVF( pMesh->GetOptions(),
                                pMesh->GetFVF() | D3DFVF_NORMAL,
                                pd3dDevice, &pTempMesh ) );
        V( D3DXComputeNormals( pTempMesh, NULL ) );

        SAFE_RELEASE( pMesh );
        pMesh = pTempMesh;
    }

    // Optimize the mesh for this graphics card's vertex cache 
    // so when rendering the mesh's triangle list the vertices will 
    // cache hit more often so it won't have to re-execute the vertex shader 
    // on those vertices so it will improve perf.     
    rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
    if( rgdwAdjacency == NULL )
        return E_OUTOFMEMORY;
    V( pMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency ) );
    V( pMesh->OptimizeInplace( D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL ) );
    delete []rgdwAdjacency;

    *ppMesh = pMesh;

    return S_OK;
}
//--------------------------------------------------------------------------------------
//메쉬 불러오는 함수
//--------------------------------------------------------------------------------------
HRESULT LoadMesh( IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh )
{
    ID3DXMesh* pMesh = NULL;
    WCHAR str[MAX_PATH];
    HRESULT hr;

    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, strFileName ) );
    V_RETURN( D3DXLoadMeshFromX( str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh ) );

    DWORD* rgdwAdjacency = NULL;

    // mesh에 노말벡터 생성하는 코드
    if( !( pMesh->GetFVF() & D3DFVF_NORMAL ) )
    {
        ID3DXMesh* pTempMesh;
        V( pMesh->CloneMeshFVF( pMesh->GetOptions(),
                                pMesh->GetFVF() | D3DFVF_NORMAL,
                                pd3dDevice, &pTempMesh ) );
        V( D3DXComputeNormals( pTempMesh, NULL ) );

        SAFE_RELEASE( pMesh );
        pMesh = pTempMesh;
    }

	//성능 향상을 도모하고자 인접 정보를 기록
	//각 mesh(삼각형) 정보 테이블을 가지는 형태
	//해당 정보는 pMesh가 가지고 있음
	//각 mesh 정보는 인접할 수 있는 점의 최대 개수가 3개 이내임을 활용해 효율적으로 vertex 운영
    rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
    if( rgdwAdjacency == NULL )
        return E_OUTOFMEMORY;
    V( pMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency ) );
	//버텍스 캐쉬를 활용하는 것
    V( pMesh->OptimizeInplace( D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL ) );
    delete []rgdwAdjacency;


	//callback out 변수에 최종 값 저장
    *ppMesh = pMesh;

    return S_OK;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
0
/**
 * Exports all geometry into a D3D .x file into the current working folder.
 * @param Filename	Desired filename (may include path)
 * @param bShow		Whether the D3D .x file viewer should be invoked. If shown, we'll block until it has been closed.
 */
void F3DVisualizer::Export( const TCHAR* Filename, bool bShow/*=false*/ )
{
	ID3DXMesh* Mesh;
	Mesh = NULL;
	int32 NumPrimitives = NumTriangles() + NumLines()*2;
	int32 NumVertices = NumTriangles()*3 + NumLines()*4;
	HRESULT Result = D3DXCreateMeshFVF( NumPrimitives, NumVertices, D3DXMESH_32BIT, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_SPECULAR, D3D->D3DDevice, &Mesh );
	void* VertexBuffer = NULL;
	void* IndexBuffer = NULL;
	Result = Mesh->LockVertexBuffer(D3DLOCK_DISCARD, &VertexBuffer);
	Result = Mesh->LockIndexBuffer(D3DLOCK_DISCARD, &IndexBuffer);

	D3DXVertex* Vertices = (D3DXVertex*)VertexBuffer;
	uint32* Indices = (uint32*) IndexBuffer;
	int32 NumVerticesStored = 0;
	int32 NumIndicesStored = 0;

	// Add the triangles to the vertexbuffer and indexbuffer.
	for ( int32 TriangleIndex=0; TriangleIndex < NumTriangles(); ++TriangleIndex )
	{
		const FVector4& P1 = Triangles[TriangleIndex].Vertices[0];
		const FVector4& P2 = Triangles[TriangleIndex].Vertices[1];
		const FVector4& P3 = Triangles[TriangleIndex].Vertices[2];
		const FColor& Color = Triangles[TriangleIndex].Color;
		Vertices[NumVerticesStored+0].Pos[0] = P1[0];
		Vertices[NumVerticesStored+0].Pos[1] = P1[1];
		Vertices[NumVerticesStored+0].Pos[2] = P1[2];
		Vertices[NumVerticesStored+0].Color1 = Color.DWColor();
		Vertices[NumVerticesStored+0].Color2 = 0;
		Vertices[NumVerticesStored+1].Pos[0] = P2[0];
		Vertices[NumVerticesStored+1].Pos[1] = P2[1];
		Vertices[NumVerticesStored+1].Pos[2] = P2[2];
		Vertices[NumVerticesStored+1].Color1 = Color.DWColor();
		Vertices[NumVerticesStored+1].Color2 = 0;
		Vertices[NumVerticesStored+2].Pos[0] = P3[0];
		Vertices[NumVerticesStored+2].Pos[1] = P3[1];
		Vertices[NumVerticesStored+2].Pos[2] = P3[2];
		Vertices[NumVerticesStored+2].Color1 = Color.DWColor();
		Vertices[NumVerticesStored+2].Color2 = 0;

		// Reverse triangle winding order for the .x file.
		Indices[NumIndicesStored+0] = NumVerticesStored + 0;
		Indices[NumIndicesStored+1] = NumVerticesStored + 2;
		Indices[NumIndicesStored+2] = NumVerticesStored + 1;

		NumVerticesStored += 3;
		NumIndicesStored += 3;
	}

	// Add the lines to the vertexbuffer and indexbuffer.
	for ( int32 LineIndex=0; LineIndex < NumLines(); ++LineIndex )
	{
		const FVector4& P1 = Lines[LineIndex].Vertices[0];
		const FVector4& P2 = Lines[LineIndex].Vertices[1];
		const FColor& Color = Lines[LineIndex].Color;
		Vertices[NumVerticesStored+0].Pos[0] = P1[0];
		Vertices[NumVerticesStored+0].Pos[1] = P1[1] - 5.0f;
		Vertices[NumVerticesStored+0].Pos[2] = P1[2];
		Vertices[NumVerticesStored+0].Color1 = 0;
		Vertices[NumVerticesStored+0].Color2 = Color.DWColor();
		Vertices[NumVerticesStored+1].Pos[0] = P1[0];
		Vertices[NumVerticesStored+1].Pos[1] = P1[1] + 5.0f;
		Vertices[NumVerticesStored+1].Pos[2] = P1[2];
		Vertices[NumVerticesStored+1].Color1 = 0;
		Vertices[NumVerticesStored+1].Color2 = Color.DWColor();
		Vertices[NumVerticesStored+2].Pos[0] = P2[0];
		Vertices[NumVerticesStored+2].Pos[1] = P2[1] - 5.0f;
		Vertices[NumVerticesStored+2].Pos[2] = P2[2];
		Vertices[NumVerticesStored+2].Color1 = 0;
		Vertices[NumVerticesStored+2].Color2 = Color.DWColor();
		Vertices[NumVerticesStored+3].Pos[0] = P2[0];
		Vertices[NumVerticesStored+3].Pos[1] = P2[1] + 5.0f;
		Vertices[NumVerticesStored+3].Pos[2] = P2[2];
		Vertices[NumVerticesStored+3].Color1 = 0;
		Vertices[NumVerticesStored+3].Color2 = Color.DWColor();

		Indices[NumIndicesStored+0] = NumVerticesStored+0;
		Indices[NumIndicesStored+1] = NumVerticesStored+2;
		Indices[NumIndicesStored+2] = NumVerticesStored+1;
		Indices[NumIndicesStored+3] = NumVerticesStored+2;
		Indices[NumIndicesStored+4] = NumVerticesStored+3;
		Indices[NumIndicesStored+5] = NumVerticesStored+1;

		NumVerticesStored += 4;
		NumIndicesStored += 6;
	}

	Mesh->UnlockVertexBuffer();
	Mesh->UnlockIndexBuffer();
	Result = D3DXComputeNormals( Mesh, NULL );
	D3DXMATERIAL MeshMaterial;
	MeshMaterial.MatD3D.Ambient.r = 0.1f;
	MeshMaterial.MatD3D.Ambient.g = 0.1f;
	MeshMaterial.MatD3D.Ambient.b = 0.1f;
	MeshMaterial.MatD3D.Ambient.a = 0.0f;
	MeshMaterial.MatD3D.Diffuse.r = 1.0f;
	MeshMaterial.MatD3D.Diffuse.g = 1.0f;
	MeshMaterial.MatD3D.Diffuse.b = 1.0f;
	MeshMaterial.MatD3D.Diffuse.a = 1.0f;
	MeshMaterial.MatD3D.Emissive.r = 1.0f;
	MeshMaterial.MatD3D.Emissive.g = 1.0f;
	MeshMaterial.MatD3D.Emissive.b = 1.0f;
	MeshMaterial.MatD3D.Emissive.a = 1.0f;
	MeshMaterial.MatD3D.Specular.r = 1.0f;
	MeshMaterial.MatD3D.Specular.g = 1.0f;
	MeshMaterial.MatD3D.Specular.b = 1.0f;
	MeshMaterial.MatD3D.Specular.a = 1.0f;
	MeshMaterial.MatD3D.Power = 16.0f;
	MeshMaterial.pTextureFilename = NULL;

	D3DXEFFECTINSTANCE EffectInstance;
	EffectInstance.pEffectFilename = "D3DExport.fx";
	EffectInstance.NumDefaults = 0;
	EffectInstance.pDefaults = NULL;

	// Write out the .x file.
	D3DXSaveMeshToX( Filename, Mesh, NULL, &MeshMaterial, &EffectInstance, 1, D3DXF_FILEFORMAT_BINARY );
	Mesh->Release();

	// Write out the .fx file, if it doesn't always exist.
	HANDLE ShaderFile = CreateFile( TEXT("D3DExport.fx"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
	if (ShaderFile != INVALID_HANDLE_VALUE)
	{
		::DWORD BytesWritten;
		WriteFile(ShaderFile, ShaderFxFile, (uint32)FCStringAnsi::Strlen(ShaderFxFile), &BytesWritten, NULL);
		CloseHandle( ShaderFile );
	}

	// If specified, run the default viewer for .x files and block until it's closed.
	if ( bShow )
	{
		system( TCHAR_TO_ANSI(Filename) );
	}
}
Exemplo n.º 16
0
//-----------------------------------------------------------------------------
// Desc: 在这里是调用了成员函数 GenerateGameSkinMesh(pMeshContainer);
//       是在这里加载了蒙皮信息
//-----------------------------------------------------------------------------
HRESULT DexAllocateHierarchy::CreateMeshContainer(LPCSTR Name, 
	CONST D3DXMESHDATA *pMeshData,
	CONST D3DXMATERIAL *pMaterials, 
	CONST D3DXEFFECTINSTANCE *pEffectInstances, 
	DWORD NumMaterials, 
	CONST DWORD *pAdjacency, 
	LPD3DXSKININFO pSkinInfo, 
	LPD3DXMESHCONTAINER *ppNewMeshContainer) 
{
	HRESULT hr;
	stDexMeshContainerEx *pMeshContainer = NULL;
	LPDIRECT3DDEVICE9 device = NULL;
	UINT NumFaces;
	UINT iMaterial;
	UINT iBone, cBones;

	LPD3DXMESH pMesh = NULL;

	*ppNewMeshContainer = NULL;

	// this sample does not handle patch meshes, so fail when one is found
	if (pMeshData->Type != D3DXMESHTYPE_MESH)
	{
		hr = E_FAIL;
		return hr;
	}

	// get the pMesh interface pointer out of the mesh data structure
	pMesh = pMeshData->pMesh;
	pMesh->GetDevice( &device );

	// this sample does not FVF compatible meshes, so fail when one is found
	if (pMesh->GetFVF() == 0)
	{
		hr = E_FAIL;
		return hr;
	}

	// allocate the overloaded structure to return as a D3DXMESHCONTAINER
	pMeshContainer = new stDexMeshContainerEx;
	if (pMeshContainer == NULL)
	{
		hr = E_OUTOFMEMORY;
		return hr;
	}
	memset(pMeshContainer, 0, sizeof(stDexMeshContainerEx));

	// make sure and copy the name.  All memory as input belongs to caller, interfaces can be addref'd though
	hr = AllocateName(Name, &pMeshContainer->Name);
	if (FAILED(hr))
	{
		if (pMeshContainer != NULL)
		{
			DestroyMeshContainer(pMeshContainer);
		}
		return hr;
	}

	NumFaces = pMesh->GetNumFaces();

	// if no normals are in the mesh, add them
	if (!(pMesh->GetFVF() & D3DFVF_NORMAL))
	{
		pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;

		// clone the mesh to make room for the normals
		hr = pMesh->CloneMeshFVF( pMesh->GetOptions(), 
			pMesh->GetFVF() | D3DFVF_NORMAL, 
			device, &pMeshContainer->MeshData.pMesh );
		if (FAILED(hr))
		{
			if (pMeshContainer != NULL)
			{
				DestroyMeshContainer(pMeshContainer);
			}
			return hr;
		}

		// get the new pMesh pointer back out of the mesh container to use
		// NOTE: we do not release pMesh because we do not have a reference to it yet
		pMesh = pMeshContainer->MeshData.pMesh;

		// now generate the normals for the pmesh
		D3DXComputeNormals( pMesh, NULL );
	}
	else  // if no normals, just add a reference to the mesh for the mesh container
	{
		pMeshContainer->MeshData.pMesh = pMesh;
		pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;

		pMesh->AddRef();
	}

	// allocate memory to contain the material information.  This sample uses
	//   the D3D9 materials and texture names instead of the EffectInstance style materials
	pMeshContainer->NumMaterials = max(1, NumMaterials);
	pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials];
	pMeshContainer->ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials];
	pMeshContainer->pAdjacency = new DWORD[NumFaces*3];
	if ((pMeshContainer->pAdjacency == NULL) || (pMeshContainer->pMaterials == NULL))
	{
		hr = E_OUTOFMEMORY;
		if (pMeshContainer != NULL)
		{
			DestroyMeshContainer(pMeshContainer);
		}
		return hr;
	}

	memcpy(pMeshContainer->pAdjacency, pAdjacency, sizeof(DWORD) * NumFaces*3);
	memset(pMeshContainer->ppTextures, 0, sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials);

	// if materials provided, copy them
	if (NumMaterials > 0)            
	{
		memcpy(pMeshContainer->pMaterials, pMaterials, sizeof(D3DXMATERIAL) * NumMaterials);

		for (iMaterial = 0; iMaterial < NumMaterials; iMaterial++)
		{
			if (pMeshContainer->pMaterials[iMaterial].pTextureFilename != NULL)
			{
				//TCHAR file[1000];
				//FindMediaFile(file,pMeshContainer->pMaterials[iMaterial].pTextureFilename);
				
				// 根据纹理的文件名创建纹理资源,如果创建失败,纹理指针必须赋成NULL
				// MessageNULL(file);
				//D3DXCreateTextureFromFileEx(device, file, 
				//	D3DX_DEFAULT_NONPOW2, 
				//	D3DX_DEFAULT_NONPOW2, 
				//	D3DX_FROM_FILE, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, 
				//	D3DX_FILTER_NONE, D3DX_FILTER_NONE, D3DCOLOR_XRGB(0,0,0), NULL, NULL, 
				//	&pMeshContainer->ppTextures[iMaterial]);
				string texname = "model/";  //轉到model文件夾中去找紋理
				texname += pMeshContainer->pMaterials[iMaterial].pTextureFilename;
				if( FAILED( D3DXCreateTextureFromFile( device, texname.c_str(),
					&pMeshContainer->ppTextures[iMaterial] ) ) )
				{
					getLog()->BeginLog();
					getLog()->Log(log_allert, "load model texture %s failed! \n", texname.c_str());
					pMeshContainer->ppTextures[iMaterial] = NULL;
					getLog()->EndLog();
				}

				// don't remember a pointer into the dynamic memory, just forget the name after loading
				pMeshContainer->pMaterials[iMaterial].pTextureFilename = NULL;
			}
		}
	}
	else // if no materials provided, use a default one
	{
		pMeshContainer->pMaterials[0].pTextureFilename = NULL;
		memset(&pMeshContainer->pMaterials[0].MatD3D, 0, sizeof(D3DMATERIAL9));
		pMeshContainer->pMaterials[0].MatD3D.Diffuse.r = 0.5f;
		pMeshContainer->pMaterials[0].MatD3D.Diffuse.g = 0.5f;
		pMeshContainer->pMaterials[0].MatD3D.Diffuse.b = 0.5f;
		pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse;
	}

	// if there is skinning information, save off the required data and then setup for HW skinning
	if (pSkinInfo != NULL)
	{
		// first save off the SkinInfo and original mesh data
		pMeshContainer->pSkinInfo = pSkinInfo;
		pSkinInfo->AddRef();

		pMeshContainer->pOrigMesh = pMesh;
		pMesh->AddRef();

		// Will need an array of offset matrices to move the vertices from the figure space to the bone's space
		cBones = pSkinInfo->GetNumBones();
		pMeshContainer->pBoneOffsetMatrices = new D3DXMATRIX[cBones];
		if (pMeshContainer->pBoneOffsetMatrices == NULL)
		{
			hr = E_OUTOFMEMORY;
			if (pMeshContainer != NULL)
			{
				DestroyMeshContainer(pMeshContainer);
			}
			return hr;
		}

		// get each of the bone offset matrices so that we don't need to get them later
		for (iBone = 0; iBone < cBones; iBone++)
		{
			pMeshContainer->pBoneOffsetMatrices[iBone] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(iBone));
		}

		// GenerateGameSkinMesh will take the general skinning information and transform it to a HW friendly version
		hr = GenerateGameSkinMesh(device, pMeshContainer );
		if (FAILED(hr))
		{       
			if (pMeshContainer != NULL)
			{
				DestroyMeshContainer(pMeshContainer);
			}
			return hr;
		}
	}

	*ppNewMeshContainer = pMeshContainer;
	pMeshContainer = NULL;

	// call Destroy function to properly clean up the memory allocated 
	if (pMeshContainer != NULL)
	{
		DestroyMeshContainer(pMeshContainer);
	}
	return hr;
}
Exemplo n.º 17
0
Mesh::Mesh(const std::string & strNombre,LPDIRECT3DDEVICE9 pd3dDevice)
{

    m_strNombre=strNombre;

   // Carga el objeto del archivo especificado.
    if( FAILED( D3DXLoadMeshFromX( strNombre.c_str(), D3DXMESH_SYSTEMMEM, 
            pd3dDevice, NULL, &pD3DXMtrlBuffer, NULL,
			&g_dwNumMaterials, &g_pMesh ) ) )
    {
                MessageBox(NULL, "No se puede encontrar el archivo .x",
			           "Error al cargar Mesh", MB_OK);
                
           
     }
    

    // Se extraen los materiales y texturas del objeto.
    D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
    g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];
    g_pMeshTextures  = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];

    for( DWORD i=0; i<g_dwNumMaterials; i++ )
    {
        // Copia el material.
        g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;

        // Establece el color difuso del material.
        g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;

        g_pMeshTextures[i] = NULL;
        if( d3dxMaterials[i].pTextureFilename != NULL && 
            lstrlen(d3dxMaterials[i].pTextureFilename) > 0 )
        {
            // Se crea la  textura
            if( FAILED(D3DXCreateTextureFromFile( pd3dDevice, 
                                                d3dxMaterials[i].pTextureFilename, 
                                                &g_pMeshTextures[i] ) ) )
            {
               
                MessageBox(NULL, "No se puede hallar el archivo de textura.",
                    "Error al cargar textura", MB_OK);
               
            }
        }
    }

    // Se libera el buffer.
    pD3DXMtrlBuffer->Release();

    // Clonar el mesh para insertarle en el FVF las normales y poder calcularlas
    // para su uso en la iluminacion.
    LPD3DXMESH  lpTempMesh = NULL;

    
    

    g_pMesh->CloneMeshFVF(0,  D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE |D3DFVF_TEX1 , 
                           pd3dDevice, &lpTempMesh);
   
    
      

    D3DXComputeNormals( lpTempMesh,NULL);

    g_pMesh=lpTempMesh;

}
Exemplo n.º 18
0
HRESULT XFileCreator::CreateMesh(std::vector<Vertex> vertices,
                                 std::vector<Face> faces)
{
    HRESULT hr;

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

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

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

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

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

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

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

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

    DWORD* pIndices = NULL;

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

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

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

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

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

    delete [] pAdjacency;

    return D3D_OK;
}
Exemplo n.º 19
0
HRESULT PATCH::CreateMesh(HEIGHTMAP &hm, RECT source, IDirect3DDevice9* Dev, int index)
{
	if(m_pMesh != NULL)
	{
		m_pMesh->Release();
		m_pMesh = NULL;
	}

	try
	{
		m_pDevice = Dev;

		int width = source.right - source.left;
		int height = source.bottom - source.top;
		int nrVert = (width + 1) * (height + 1);
		int nrTri = width * height * 2;

		if(FAILED(D3DXCreateMeshFVF(nrTri, nrVert, D3DXMESH_MANAGED, TERRAINVertex::FVF, m_pDevice, &m_pMesh)))
		{
			debug.Print("Couldn't create mesh for PATCH");
			return E_FAIL;
		}

		//Create vertices
		TERRAINVertex* ver = 0;
		m_pMesh->LockVertexBuffer(0,(void**)&ver);
		for(int z=source.top, z0 = 0;z<=source.bottom;z++, z0++)
			for(int x=source.left, x0 = 0;x<=source.right;x++, x0++)
			{
				//Calculate vertex color
				float prc = hm.m_pHeightMap[x + z * hm.m_size.x] / hm.m_maxHeight;
				int red =   (int)(255 * prc);
				int green = (int)(255 * (1.0f - prc));

				D3DCOLOR col;

				if(index % 2 == 0)		//Invert color depending on what patch it is...
					col = D3DCOLOR_ARGB(255, red, green, 0);
				else col = D3DCOLOR_ARGB(255, green, red, 0);

				//Extract height (and position) from heightmap
				D3DXVECTOR3 pos = D3DXVECTOR3((float)x, hm.m_pHeightMap[x + z * hm.m_size.x], (float)-z);

				//Set new vertex
				ver[z0 * (width + 1) + x0] = TERRAINVertex(pos, col);
			}
		m_pMesh->UnlockVertexBuffer();

		//Calculate Indices
		WORD* ind = 0;
		m_pMesh->LockIndexBuffer(0,(void**)&ind);	
		int index = 0;

		for(int z=source.top, z0 = 0;z<source.bottom;z++, z0++)
			for(int x=source.left, x0 = 0;x<source.right;x++, x0++)
			{
				//Triangle 1
				ind[index++] =   z0   * (width + 1) + x0;
				ind[index++] =   z0   * (width + 1) + x0 + 1;
				ind[index++] = (z0+1) * (width + 1) + x0;		

				//Triangle 2
				ind[index++] = (z0+1) * (width + 1) + x0;
				ind[index++] =   z0   * (width + 1) + x0 + 1;
				ind[index++] = (z0+1) * (width + 1) + x0 + 1;
			}

		m_pMesh->UnlockIndexBuffer();

		//Set Attributes
		DWORD *att = 0;
		m_pMesh->LockAttributeBuffer(0,&att);
		memset(att, 0, sizeof(DWORD)*nrTri);
		m_pMesh->UnlockAttributeBuffer();

		//Compute normals
		D3DXComputeNormals(m_pMesh, NULL);
	}
	catch(...)
	{
		debug.Print("Error in PATCH::CreateMesh()");
		return E_FAIL;
	}

	return S_OK;
}
Exemplo n.º 20
0
HRESULT KG3DMeshBone::_CreateMesh()
{
    HRESULT hResult  = E_FAIL;
    HRESULT hRetCode = E_FAIL;

    DWORD dwNumFaces    = (DWORD)m_vecSubMeshInfo.size() * 8;
    DWORD dwNumVertices = (DWORD)m_vecSubMeshInfo.size() * 6;

    VFormat::FACES_NORMAL_DIFFUSE_TEXTURE0* pVBuffer = NULL;
    WORD*  pIBuffer = NULL;
    DWORD* pABuffer = NULL;

    hRetCode = D3DXCreateMeshFVF(
        dwNumFaces,
        dwNumVertices,
        D3DXMESH_MANAGED,
        D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE,
        g_pd3dDevice,
        &m_pSysMesh
    );
    KG_COM_PROCESS_ERROR(hRetCode);

    // vertex
    hRetCode = m_pSysMesh->LockVertexBuffer(0, (void**)&pVBuffer);
    KG_COM_PROCESS_ERROR(hRetCode);

    for (DWORD i = 0; i < m_vecSubMeshInfo.size(); i++)
    {
        pVBuffer[i * 6].p     = m_vecSubMeshInfo[i].vPosition[0];
        pVBuffer[i * 6].diffuse = 0xFFFFFFFF;
        pVBuffer[i * 6 + 1].p = m_vecSubMeshInfo[i].vPosition[1];
        pVBuffer[i * 6 + 1].diffuse = 0xFFFF0000;
        pVBuffer[i * 6 + 2].p = m_vecSubMeshInfo[i].vPosition[2];
        pVBuffer[i * 6 + 2].diffuse = 0xFF0000FF;
        pVBuffer[i * 6 + 3].p = m_vecSubMeshInfo[i].vPosition[3];
        pVBuffer[i * 6 + 3].diffuse = 0xFF00FF00;
        pVBuffer[i * 6 + 4].p = m_vecSubMeshInfo[i].vPosition[4];
        pVBuffer[i * 6 + 4].diffuse = 0xFFFFFF00;
        pVBuffer[i * 6 + 5].p = m_vecSubMeshInfo[i].vPosition[5];
        pVBuffer[i * 6 + 5].diffuse = 0xFFFFFFFF;
    }

    hRetCode = m_pSysMesh->UnlockVertexBuffer();
    KG_COM_PROCESS_ERROR(hRetCode);


    // index
    hRetCode = m_pSysMesh->LockIndexBuffer(0, (void**)&pIBuffer);
    KG_COM_PROCESS_ERROR(hRetCode);

    for (DWORD i = 0; i < m_vecSubMeshInfo.size(); i++)
    {
        for (DWORD j = 0; j < 24; j++)
        {
            pIBuffer[i * 24 + j] = (WORD)(m_vecSubMeshInfo[i].dwIndex[j] + 6 * i);
        }
    }

    hRetCode = m_pSysMesh->UnlockIndexBuffer();
    KG_COM_PROCESS_ERROR(hRetCode);


    // index
    hRetCode = m_pSysMesh->LockAttributeBuffer(0, (DWORD**)&pABuffer);
    KG_COM_PROCESS_ERROR(hRetCode);

    for (DWORD i = 0; i < m_vecSubMeshInfo.size(); i++)
    {
        for (DWORD j = 0; j < 8; j++)
        {
            pABuffer[i * 8 + j] = i;
        }
    }

    hRetCode = m_pSysMesh->UnlockAttributeBuffer();
    KG_COM_PROCESS_ERROR(hRetCode);

    D3DXComputeNormals(m_pSysMesh, NULL);

    hResult = S_OK;
Exit0:
    return hResult;
}
Exemplo n.º 21
0
//-----------------------------------------------------------------------------
// Name: CDXUTMesh::SetVertexDecl
// Desc: Convert the mesh to the format specified by the given vertex
//       declarations.
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9 *pDecl )
{
    LPD3DXMESH pTempSysMemMesh = NULL;
    LPD3DXMESH pTempLocalMesh  = NULL;

    if( m_pSysMemMesh )
    {
        if( FAILED( m_pSysMemMesh->CloneMesh( m_pSysMemMesh->GetOptions(), pDecl,
                                              pd3dDevice, &pTempSysMemMesh ) ) )
            return E_FAIL;
    }

    if( m_pLocalMesh )
    {
        if( FAILED( m_pLocalMesh->CloneMesh( m_pLocalMesh->GetOptions(), pDecl, pd3dDevice,
                                             &pTempLocalMesh ) ) )
        {
            SAFE_RELEASE( pTempSysMemMesh );
            return E_FAIL;
        }
    }

    // Check if the old declaration contains a normal.
    bool bHadNormal = false;
    D3DVERTEXELEMENT9 aOldDecl[MAX_FVF_DECL_SIZE];
    if( m_pSysMemMesh && SUCCEEDED( m_pSysMemMesh->GetDeclaration( aOldDecl ) ) )
    {
        for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index )
            if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL )
            {
                bHadNormal = true;
                break;
            }
    }

    // Check if the new declaration contains a normal.
    bool bHaveNormalNow = false;
    D3DVERTEXELEMENT9 aNewDecl[MAX_FVF_DECL_SIZE];
    if( pTempSysMemMesh && SUCCEEDED( pTempSysMemMesh->GetDeclaration( aNewDecl ) ) )
    {
        for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index )
            if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL )
            {
                bHaveNormalNow = true;
                break;
            }
    }

    SAFE_RELEASE( m_pSysMemMesh );
    SAFE_RELEASE( m_pLocalMesh );

    if( pTempSysMemMesh )
    {
        m_pSysMemMesh = pTempSysMemMesh;

        if( !bHadNormal && bHaveNormalNow )
        {
            // Compute normals in case the meshes have them
            D3DXComputeNormals( m_pSysMemMesh, NULL );
        }
    }

    if( pTempLocalMesh )
    {
        m_pLocalMesh = pTempLocalMesh;

        if( !bHadNormal && bHaveNormalNow )
        {
            // Compute normals in case the meshes have them
            D3DXComputeNormals( m_pLocalMesh, NULL );
        }
    }

    return S_OK;
}
Exemplo n.º 22
0
MeshContainer* XFileLoader::CreateMeshContainer()
{
	HRESULT hr;

	MeshContainer* meshContainer = NULL;

	Graphics* graphics = Graphics::GetInstance();
	IDirect3DDevice9Ptr pD3DDevice = graphics->GetDirect3DDevice();

	if( !(m_pD3DMesh->GetFVF() & D3DFVF_NORMAL) )
    {
		LPD3DXMESH tmpMesh = NULL;

        // 柔軟な頂点フォーマット (FVF) コードを使ってメッシュのコピーを作成する
        hr = m_pD3DMesh->CloneMeshFVF(
            m_pD3DMesh->GetOptions(),
            m_pD3DMesh->GetFVF() | D3DFVF_NORMAL,
            pD3DDevice,
            &tmpMesh); // ←ここにコピー
        if(FAILED(hr))
        {
            goto exit;
        }
        // メッシュに含まれる各頂点の法線を計算して、設定する
        //D3DXComputeNormals( tmpMesh, reinterpret_cast<DWORD*>(pAdjacencyBuf->GetBufferPointer()) );
		D3DXComputeNormals( tmpMesh, NULL );

		m_pD3DMesh->Release();
		m_pD3DMesh = tmpMesh;
	}

	D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];
	hr = m_pD3DMesh->GetDeclaration(pDecl);
	if( FAILED(hr) )
	{
		goto exit;
	}

	DWORD vertexNum = m_pD3DMesh->GetNumVertices();
	DWORD faceNum = m_pD3DMesh->GetNumFaces();

	DWORD attrNum = 0;
	m_pD3DMesh->GetAttributeTable(NULL, &attrNum);
	
	DWORD size = m_pD3DMesh->GetNumBytesPerVertex();

	BYTE* pD3DVertice = NULL;
	m_pD3DMesh->LockVertexBuffer( 0,(LPVOID*)&pD3DVertice );

	sVertex* vertices = new sVertex[vertexNum];

	for( DWORD vertIdx = 0;vertIdx<vertexNum;vertIdx++ )
	{
		sVertex* vertex = &vertices[vertIdx];
		vertex->uv = D3DXVECTOR2(0.0f,0.0f);
		vertex->color = 0xFFFFFFFF;

		for( DWORD i=0;i<MAX_FVF_DECL_SIZE;i++ )
		{
			D3DVERTEXELEMENT9& decl = pDecl[i];

			if( decl.Stream==0xFF )
			{
				break;
			}

			switch( decl.Usage )
			{
			case D3DDECLUSAGE_POSITION:
				vertex->position = *(D3DXVECTOR3*)(pD3DVertice+vertIdx*size+decl.Offset);
				vertex->position = vertex->position * m_scale;
				break;
			case D3DDECLUSAGE_NORMAL:
				vertex->normal = *(D3DXVECTOR3*)(pD3DVertice+vertIdx*size+decl.Offset);
				break;
			case D3DDECLUSAGE_TEXCOORD:
				vertex->uv = *(D3DXVECTOR2*)(pD3DVertice+vertIdx*size+decl.Offset);
				break;
			case D3DDECLUSAGE_COLOR:
				vertex->color = *(DWORD*)(pD3DVertice+vertIdx*size+decl.Offset);
				break;
			}
		}
	}

	m_pD3DMesh->UnlockVertexBuffer();

	LPDIRECT3DINDEXBUFFER9 pIndexBuffer = NULL;
	m_pD3DMesh->GetIndexBuffer( &pIndexBuffer );
	D3DINDEXBUFFER_DESC desc;
	pIndexBuffer->GetDesc( &desc );
	pIndexBuffer->Release();

	DWORD* indices = new DWORD[faceNum*3];

	if( desc.Format==D3DFMT_INDEX16 )
	{
		WORD* pD3DIndices = NULL;
		m_pD3DMesh->LockIndexBuffer(0,(LPVOID*)&pD3DIndices );
		for( DWORD i=0;i<faceNum*3;i++ )
		{
			indices[i] = pD3DIndices[i];
		}
		m_pD3DMesh->UnlockIndexBuffer();
	}
	else
	{
		DWORD* pD3DIndices =NULL;
		m_pD3DMesh->LockIndexBuffer(0,(LPVOID*)&pD3DIndices );
		memcpy( indices,pD3DIndices,sizeof(DWORD)*faceNum*3 );
		m_pD3DMesh->UnlockIndexBuffer();
	}

	D3DXATTRIBUTERANGE *attrList = new D3DXATTRIBUTERANGE[attrNum];
	m_pD3DMesh->GetAttributeTable(attrList, &attrNum);

	meshContainer = new MeshContainer;

	meshContainer->pMesh = new Mesh;
	meshContainer->pMesh->Create( vertexNum,faceNum,attrNum );

	meshContainer->pMesh->SetVertices( vertices );

	meshContainer->pMesh->SetIndices( indices );

	meshContainer->pMesh->SetAttributeRanges( attrList );

	delete[] vertices;
	delete[] indices;
	delete[] attrList;

	meshContainer->materialNum = m_Materials;
	meshContainer->pMaterials = new sMaterial[m_Materials];

	D3DXMATERIAL* pD3DMaterials = (D3DXMATERIAL*)m_pMaterialBuf->GetBufferPointer();

	for( DWORD i=0;i<m_Materials;i++ )
	{
		sMaterial* pMaterial = &meshContainer->pMaterials[i];

		D3DXMATERIAL* pD3DMaterial = &pD3DMaterials[i];

		pMaterial->colorDiffuse = pD3DMaterial->MatD3D.Diffuse;

		pMaterial->colorSpecular.r = pD3DMaterial->MatD3D.Specular.r;
		pMaterial->colorSpecular.g = pD3DMaterial->MatD3D.Specular.g;
		pMaterial->colorSpecular.b = pD3DMaterial->MatD3D.Specular.b;
		pMaterial->colorSpecular.a = 0.0f;

		pMaterial->colorAmbient.r = pD3DMaterial->MatD3D.Diffuse.r;
		pMaterial->colorAmbient.g = pD3DMaterial->MatD3D.Diffuse.g;
		pMaterial->colorAmbient.b = pD3DMaterial->MatD3D.Diffuse.b;
		pMaterial->colorAmbient.a = 0.0f;

		pMaterial->colorEmissive.r = pD3DMaterial->MatD3D.Emissive.r;
		pMaterial->colorEmissive.g = pD3DMaterial->MatD3D.Emissive.g;
		pMaterial->colorEmissive.b = pD3DMaterial->MatD3D.Emissive.b;
		pMaterial->colorEmissive.a = 0.0f;

		pMaterial->specularPower = pD3DMaterial->MatD3D.Power;

		TCHAR path[MAX_PATH];
		_tcscpy_s( path,m_path.c_str() );

		tstring texFileName;
		tstring sphereFileName;

		if( pD3DMaterial->pTextureFilename && strlen(pD3DMaterial->pTextureFilename)>0 )
		{
			tstring filename = to_tstring(pD3DMaterial->pTextureFilename);

			tstring::size_type index = filename.find( _T("*") );
			if( index != tstring::npos )
			{
				sphereFileName = filename.substr( index+1 );
				PathAppend( path,sphereFileName.c_str() );
				sphereFileName = path;
				PathRemoveFileSpec( path );

				texFileName = filename.erase( index );
				PathAppend( path,texFileName.c_str() );
				texFileName = path;
				PathRemoveFileSpec( path );
			}
			else
			{
				texFileName = filename;
				PathAppend( path,texFileName.c_str() );
				texFileName = path;
				PathRemoveFileSpec( path );
			}

			tstring ext = PathFindExtension( texFileName.c_str() );

			if( ext == _T(".sph" ) || ext == _T(".spa") )
			{
				sphereFileName = texFileName;
				texFileName = _T("");
			}
		}

		if( !texFileName.empty() )
		{
			TexturePtr pTex = ResourceManager::GetInstance().GetResource<Texture>( texFileName );
			if( !pTex )
			{
				pTex = TexturePtr(new Texture);
				if( pTex->CreateFromFile( texFileName ) )
				{
					ResourceManager::GetInstance().AddResource( texFileName,pTex );
				}
				else
				{
					pTex.reset();
				}
			}

			if( pTex )
			{
				pMaterial->textureDiffuse = pTex;
			}
		}

		if( !sphereFileName.empty() )
		{
			TexturePtr pTex = ResourceManager::GetInstance().GetResource<Texture>( sphereFileName );
			if( !pTex )
			{
				pTex = TexturePtr(new Texture);
				if( pTex->CreateFromFile( sphereFileName ) )
				{
					ResourceManager::GetInstance().AddResource( sphereFileName,pTex );
				}
				else
				{
					pTex.reset();
				}
			}

			if( pTex )
			{
				pMaterial->textureSphere = pTex;
			}

			tstring ext = PathFindExtension( sphereFileName.c_str() );
			if( ext == _T(".sph" ) )
			{
				pMaterial->spheremap = eSPHEREMAP_MUL;
			}
			else if( ext == _T(".spa") )
			{
				pMaterial->spheremap = eSPHEREMAP_ADD;
			}
		}
	}

exit:
	if( m_pMaterialBuf )
	{
		m_pMaterialBuf->Release();
		m_pMaterialBuf = NULL;
	}
	if( m_pEffectInstancesBuf )
	{
		m_pEffectInstancesBuf->Release();
		m_pEffectInstancesBuf = NULL;
	}
	if( m_pAdjacencyBuf )
	{
		m_pAdjacencyBuf->Release();
		m_pAdjacencyBuf = NULL;
	}
	if( m_pD3DMesh )
	{
		m_pD3DMesh->Release();
		m_pD3DMesh = NULL;
	}
	return meshContainer;
}
Exemplo n.º 23
0
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMeshRender::InitDeviceObjects()
{
    DWORD cVerticesPerMesh;

    // Load mesh
    LPD3DXBUFFER pAdjacencyBuffer = NULL;
    LPDIRECT3DVERTEXBUFFER9 pVertexBuffer = NULL;
    LPD3DXMESH   pMesh = NULL;
    LPD3DXPMESH  pPMesh = NULL;
    LPD3DXMESH   pTempMesh;
    LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
    void*        pVertices;
    TCHAR        strMediaPath[512];
    HRESULT      hr;
    DWORD        dw32BitFlag;
    DWORD        cVerticesMin;
    DWORD        cVerticesMax;
    DWORD        iPMesh;
    D3DXWELDEPSILONS Epsilons;
    DWORD        i;
    D3DXMATERIAL* d3dxMaterials;

    // Find the path to the mesh
    if( FAILED( DXUtil_FindMediaFileCb( strMediaPath, sizeof(strMediaPath), m_strMeshFilename ) ) )
        return E_FAIL;//D3DAPPERR_MEDIANOTFOUND;

    // Load the mesh from the specified file
    if( FAILED( hr = D3DXLoadMeshFromX( strMediaPath, D3DXMESH_MANAGED, m_pd3dDevice,
                                        &pAdjacencyBuffer, &pD3DXMtrlBuffer, NULL, 
                                        &m_dwNumMaterials, &pMesh ) ) )
    {
        // hide error so that device changes will not cause exit, shows blank screen instead
        goto End;
    }

    dw32BitFlag = (pMesh->GetOptions() & D3DXMESH_32BIT);

    // perform simple cleansing operations on mesh
    if( FAILED( hr = D3DXCleanMesh( pMesh, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), &pTempMesh, 
                                           (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL ) ) )
    {
        m_dwNumMaterials = 0;
        goto End;
    }
    SAFE_RELEASE(pMesh);
    pMesh = pTempMesh;

    //  Perform a weld to try and remove excess vertices like the model bigship1.x in the DX9.0 SDK (current model is fixed)
    //    Weld the mesh using all epsilons of 0.0f.  A small epsilon like 1e-6 works well too
    memset(&Epsilons, 0, sizeof(D3DXWELDEPSILONS));
    if( FAILED( hr = D3DXWeldVertices( pMesh, 0, &Epsilons, 
                                                (DWORD*)pAdjacencyBuffer->GetBufferPointer(), 
                                                (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL, NULL ) ) )
    {
        m_dwNumMaterials = 0;
        goto End;
    }

    // verify validity of mesh for simplification
    if( FAILED( hr = D3DXValidMesh( pMesh, (DWORD*)pAdjacencyBuffer->GetBufferPointer(), NULL ) ) )
    {
        m_dwNumMaterials = 0;
        goto End;
    }

    // Allocate a material/texture arrays
    d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
    m_mtrlMeshMaterials = new D3DMATERIAL9[m_dwNumMaterials];
    m_pMeshTextures     = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];

    // Copy the materials and load the textures
    for( i=0; i<m_dwNumMaterials; i++ )
    {
        m_mtrlMeshMaterials[i] = d3dxMaterials[i].MatD3D;
        m_mtrlMeshMaterials[i].Ambient = m_mtrlMeshMaterials[i].Diffuse;

        // Find the path to the texture and create that texture
        DXUtil_FindMediaFileCb( strMediaPath, sizeof(strMediaPath), d3dxMaterials[i].pTextureFilename );
        if( FAILED( D3DXCreateTextureFromFile( m_pd3dDevice, strMediaPath, 
                                               &m_pMeshTextures[i] ) ) )
            m_pMeshTextures[i] = NULL;
    }
    pD3DXMtrlBuffer->Release();
    pD3DXMtrlBuffer = NULL;


    // Lock the vertex buffer, to generate a simple bounding sphere
    hr = pMesh->GetVertexBuffer( &pVertexBuffer );
    if( FAILED(hr) )
        goto End;

    hr = pVertexBuffer->Lock( 0, 0, &pVertices, D3DLOCK_NOSYSLOCK );
    if( FAILED(hr) )
        goto End;

    hr = D3DXComputeBoundingSphere( (D3DXVECTOR3*)pVertices, pMesh->GetNumVertices(),
                                    D3DXGetFVFVertexSize(pMesh->GetFVF()),
                                    &m_vObjectCenter, &m_fObjectRadius );
    pVertexBuffer->Unlock();
    pVertexBuffer->Release();

    if( FAILED(hr) || m_dwNumMaterials == 0 )
        goto End;

    if ( !(pMesh->GetFVF() & D3DFVF_NORMAL) )
    {
        hr = pMesh->CloneMeshFVF( dw32BitFlag|D3DXMESH_MANAGED, pMesh->GetFVF() | D3DFVF_NORMAL, 
                                            m_pd3dDevice, &pTempMesh );
        if (FAILED(hr))
            goto End;

        D3DXComputeNormals( pTempMesh, NULL );

        pMesh->Release();
        pMesh = pTempMesh;
    }

    hr = D3DXGeneratePMesh( pMesh, (DWORD*)pAdjacencyBuffer->GetBufferPointer(),
                            NULL, NULL, 1, D3DXMESHSIMP_VERTEX, &pPMesh);
    if( FAILED(hr) )
        goto End;

    cVerticesMin = pPMesh->GetMinVertices();
    cVerticesMax = pPMesh->GetMaxVertices();

    cVerticesPerMesh = (cVerticesMax - cVerticesMin) / 10;

    m_cPMeshes = max(1, (DWORD)ceil((cVerticesMax - cVerticesMin) / (float)cVerticesPerMesh));
    m_pPMeshes = new LPD3DXPMESH[m_cPMeshes];
    if (m_pPMeshes == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto End;
    }
    memset(m_pPMeshes, 0, sizeof(LPD3DXPMESH) * m_cPMeshes);

    // clone full size pmesh
    hr = pPMesh->ClonePMeshFVF( D3DXMESH_MANAGED | D3DXMESH_VB_SHARE, pPMesh->GetFVF(), m_pd3dDevice, &m_pPMeshFull );
    if (FAILED(hr))
        goto End;

    // clone all the separate pmeshes
    for (iPMesh = 0; iPMesh < m_cPMeshes; iPMesh++)
    {
        hr = pPMesh->ClonePMeshFVF( D3DXMESH_MANAGED | D3DXMESH_VB_SHARE, pPMesh->GetFVF(), m_pd3dDevice, &m_pPMeshes[iPMesh] );
        if (FAILED(hr))
            goto End;

        // trim to appropriate space
        hr = m_pPMeshes[iPMesh]->TrimByVertices(cVerticesMin + cVerticesPerMesh * iPMesh, cVerticesMin + cVerticesPerMesh * (iPMesh+1), NULL, NULL);
        if (FAILED(hr))
            goto End;

        hr = m_pPMeshes[iPMesh]->OptimizeBaseLOD(D3DXMESHOPT_VERTEXCACHE, NULL);
        if (FAILED(hr))
            goto End;
    }

    // set current to be maximum number of vertices
    m_iPMeshCur = m_cPMeshes - 1;
    hr = m_pPMeshes[m_iPMeshCur]->SetNumVertices(cVerticesMax);
    if (FAILED(hr))
        goto End;

    hr = m_pPMeshFull->SetNumVertices(cVerticesMax);
    if (FAILED(hr))
        goto End;
End:
    SAFE_RELEASE( pAdjacencyBuffer );
    SAFE_RELEASE( pD3DXMtrlBuffer );
    SAFE_RELEASE( pMesh );
    SAFE_RELEASE( pPMesh );

    if (FAILED(hr))
    {
        for (iPMesh = 0; iPMesh < m_cPMeshes; iPMesh++)
        {
            SAFE_RELEASE( m_pPMeshes[iPMesh] );
        }

        delete []m_pPMeshes;
        m_cPMeshes = 0;
        m_pPMeshes = NULL;
        SAFE_RELEASE( m_pPMeshFull )
    }

    return hr;
}
Exemplo n.º 24
0
void Terrain::buildGeometry()
{
	//===============================================================
	// Create one large mesh for the grid in system memory.

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

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


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

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

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

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

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

	// Write triangle data so we can compute normals.

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

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

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

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

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

			buildSubGridMesh(R, v); 
		}
	}

	HR(mesh->UnlockVertexBuffer());

	ReleaseCOM(mesh); // Done with global mesh.
}
Exemplo n.º 25
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;
}
Exemplo n.º 26
0
void LoadXFile(const std::string & filename, ID3DXMesh** meshOut, std::vector<Mtrl> & mtrls, std::vector<IDirect3DTexture9*> & texs)
{
	ID3DXMesh* meshSys				= 0;
	ID3DXBuffer * adjBuffer			= 0;
	ID3DXBuffer * mtrlBuffer		= 0;
	DWORD numMtrls					= 0;

    //step 1. Load the x file into system memory
    HR(D3DXLoadMeshFromX(filename.c_str(), D3DXMESH_SYSTEMMEM, gd3dDevice, &adjBuffer, &mtrlBuffer, 0, &numMtrls, &meshSys));

    //step 2. look into MAX_FVF_DECL_SIZE
    D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
    HR(meshSys->GetDeclaration(elems));

    bool hasNormals = false;
	D3DVERTEXELEMENT9 term = D3DDECL_END();
    for(int i = 0; i < MAX_FVF_DECL_SIZE; ++i)
    {
        //did we reach end?
        if(elems[i].Stream == 0xff)
            break;

        if(elems[i].Type == D3DDECLTYPE_FLOAT3 && elems[i].Usage == D3DDECLUSAGE_NORMAL && elems[i].UsageIndex == 0)
        {
            hasNormals = true;
            break;
        }
    }

    //step 3.
    D3DVERTEXELEMENT9 elements[64];
    UINT numElements = 0;
    VertexPNT::Decl->GetDeclaration(elements, &numElements);
   
    ID3DXMesh * temp = 0;
    //HR(meshSys->CloneMesh(D3DXMESH_SYSTEMMEM, elements, gd3dDevice, &temp));
	 HR(meshSys->CloneMesh(D3DXMESH_32BIT, elements, gd3dDevice, &temp));
	ReleaseCOM(meshSys);
	meshSys = temp;

    //step 4
    if( hasNormals == false )
        HR(D3DXComputeNormals(meshSys, 0));

    //step 5
    HR(meshSys->Optimize(D3DXMESH_MANAGED | D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT
        | D3DXMESHOPT_VERTEXCACHE, (DWORD*)adjBuffer->GetBufferPointer(), 0, 0, 0, meshOut));

    ReleaseCOM(meshSys); //Done w/ system mesh
    ReleaseCOM(adjBuffer); //done with buffer

    //step 6: get the materials and load the textures
    if(mtrlBuffer != 0 && numMtrls != 0)
    {
		D3DXMATERIAL *d3dxMtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();
		
		for(DWORD i = 0; i < numMtrls; ++i)
		{
			//save the ith material.  MatD3D ambient
			//doesnt have a default value, so I'm setting
			//it to be the same as the diffuse
			Mtrl m;
			m.ambient = d3dxMtrls[i].MatD3D.Diffuse;
			m.diffuse = d3dxMtrls[i].MatD3D.Diffuse;
			m.spec = d3dxMtrls[i].MatD3D.Specular;
			m.specPower = d3dxMtrls[i].MatD3D.Power;
			mtrls.push_back(m);

			//check if the ith material has an associative texture
			if(d3dxMtrls[i].pTextureFilename != 0)
			{
				//yes, load the texture for the ith subset
				IDirect3DTexture9* tex = 0;
				char *texFN = d3dxMtrls[i].pTextureFilename;
				HR(D3DXCreateTextureFromFile(gd3dDevice, texFN, &tex));

				//save the loaded texure
				texs.push_back(tex);
			}
			else
			{
				//no texture
				texs.push_back( 0 );
			}
		}
	}

	ReleaseCOM(mtrlBuffer); // done with the buffer
}
Exemplo n.º 27
0
bool XMeshData::Init(const std::wstring& FilePath) {
    Node::Init();

    // 재질을 임시로 보관할 버퍼선언
    LPD3DXBUFFER pD3DXMtrlBuffer;

    mEffect = ResourceManager::GetInstance()->LoadHLSL(L"Shader\\SkinnedMesh.fx");
    if (!mEffect) {
        MessageBox(NULL, L"Could not HLSL file", L"ERROR", MB_OK);
        assert(false);
        return false;
    }

    if (FAILED(D3DXLoadMeshFromX(FilePath.c_str(), D3DXMESH_SYSTEMMEM,
                                 GetDevice(), NULL,
                                 &pD3DXMtrlBuffer, NULL, &mNumMaterial,
                                 &mXMesh)))
    {
        MessageBox(NULL, L"Could not find mesh file", L"ERROR", MB_OK);
        return false;
    }

    // 재질정보와 텍스쳐 정보를 따로 뽑아낸다.
    D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
    mMaterial = new D3DMATERIAL9[mNumMaterial];			// 재질개수만큼 재질구조체 배열 생성
    mTexture = new LPDIRECT3DTEXTURE9[mNumMaterial];	// 재질개수만큼 텍스쳐 배열 생성

    for (DWORD j = 0; j<mNumMaterial; j++) {
        // 재질정보를 복사
        mMaterial[j] = d3dxMaterials[j].MatD3D;

        // 주변광원정보를 Diffuse정보로
        mMaterial[j].Ambient = mMaterial[j].Diffuse;

        mTexture[j] = NULL;

        if (d3dxMaterials[j].pTextureFilename != NULL &&
                strlen(d3dxMaterials[j].pTextureFilename) > 0)
        {
            // 텍스쳐를 파일에서 로드한다
            // w로 통일할껀지 정해야함
            std::string FileName = "Model\\";
            FileName += d3dxMaterials[j].pTextureFilename;

            if (FAILED(D3DXCreateTextureFromFileA(GetDevice(),
                                                  FileName.c_str(),
                                                  &mTexture[j])))
            {
                MessageBox(NULL, L"Could not find texture map", L"ERROR", MB_OK);
                assert(false);

                return false;
            }
        }
    }
    SAFE_RELEASE( pD3DXMtrlBuffer );

    //메쉬에 법선백터를 추가하는 부분
    if (!(mXMesh->GetFVF() & D3DFVF_NORMAL)) {
        //가지고 있지 않다면 메쉬를 복제하고 D3DFVF_NORMAL을 추가한다.
        ID3DXMesh* pTempMesh = 0;

        mXMesh->CloneMeshFVF(D3DXMESH_MANAGED,
                             mXMesh->GetFVF() | D3DFVF_NORMAL,  //이곳에 추가
                             GetDevice(),
                             &pTempMesh);

        // 법선을 계산한다.
        D3DXComputeNormals(pTempMesh, 0);

        mXMesh->Release(); // 기존메쉬를 제거한다
        mXMesh = pTempMesh; // 기존메쉬를 법선이 계산된 메쉬로 지정한다.
    }

    // Init Vertices and Indices

    int VerticesNum = mXMesh->GetNumVertices();
    BYTE* vertexBuffer;
    DWORD numBytesPerVertex = mXMesh->GetNumBytesPerVertex();
    unsigned int offset = D3DXGetFVFVertexSize(mXMesh->GetFVF());

    mXMesh->LockVertexBuffer(D3DLOCK_READONLY, (void**)&vertexBuffer);
    for (WORD i = 0; i < VerticesNum; i++)
        mVertices.push_back(*((D3DXVECTOR3*)(vertexBuffer + i * offset)));
    mXMesh->UnlockVertexBuffer();


    void *pIB;
    int IndicesNum = mXMesh->GetNumFaces();
    WORD *indexBuffer = new WORD[IndicesNum * 3];

    mXMesh->LockIndexBuffer(D3DLOCK_READONLY, (void**)&pIB);
    memcpy(indexBuffer, pIB, sizeof(WORD)*IndicesNum * 3);

    for (int i = 0; i < IndicesNum; ++i)
        mIndices.push_back(D3DXVECTOR3(indexBuffer[i * 3], indexBuffer[i * 3 + 1], indexBuffer[i * 3 + 2]));

    mXMesh->UnlockIndexBuffer();
    delete[]indexBuffer;

    return true;
}
Exemplo n.º 28
0
HRESULT InitGeometry()
{
	LPD3DXBUFFER pD3DXMtrlBuffer;
	if ( FAILED( D3DXLoadMeshFromX( L"./Resource/girl.x", D3DXMESH_SYSTEMMEM, g_pd3dDevice,
		NULL, &pD3DXMtrlBuffer, NULL, &g_dwNumMaterials, &g_pMesh ) ) )
	{
		MessageBox( NULL, L"Could not find girl.x", L"D3D Tutorial", MB_OK );
		return E_FAIL;
	}

	D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();

	g_pMeshMaterials = new D3DMATERIAL9[g_dwNumMaterials];
	if ( g_pMeshMaterials == NULL )
	{
		return E_OUTOFMEMORY;
	}

	g_pMeshTextures = new LPDIRECT3DTEXTURE9[g_dwNumMaterials];
	if ( g_pMeshTextures == NULL )
	{
		return E_OUTOFMEMORY;
	}

	if ( !( g_pMesh->GetFVF() & D3DFVF_NORMAL ) )
	{
		//가지고 있지 않다면 메쉬를 복제하고 D3DFVF_NORMAL을 추가한다.
		ID3DXMesh* pTempMesh = 0;
		g_pMesh->CloneMeshFVF( D3DXMESH_MANAGED, g_pMesh->GetFVF() | D3DFVF_NORMAL, g_pd3dDevice, &pTempMesh );

		// 법선을 계산한다.
		D3DXComputeNormals( pTempMesh, 0 );

		g_pMesh->Release(); // 기존메쉬를 제거한다
		g_pMesh = pTempMesh; // 기존메쉬를 법선이 계산된 메쉬로 지정한다.
	}

	for ( DWORD i = 0; i < g_dwNumMaterials; ++i )
	{
		g_pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
		g_pMeshMaterials[i].Ambient = g_pMeshMaterials[i].Diffuse;

		g_pMeshTextures[i] = NULL;

		if ( d3dxMaterials[i].pTextureFilename != NULL &&
			 lstrlenA( d3dxMaterials[i].pTextureFilename ) > 0 )
		{
			if ( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice,
				d3dxMaterials[i].pTextureFilename, &g_pMeshTextures[i] ) ) )
			{
				const CHAR* strPrefix = "./Resource/";
				CHAR strTexture[MAX_PATH];
				strcpy_s( strTexture, MAX_PATH, strPrefix );
				strcat_s( strTexture, MAX_PATH, d3dxMaterials[i].pTextureFilename );

				if ( FAILED( D3DXCreateTextureFromFileA( g_pd3dDevice, strTexture, &g_pMeshTextures[i] ) ) )
				{
					MessageBox( NULL, L"Could not find texture map", L"D3D Tutorial", MB_OK );
				}
			}
		}
	}

	pD3DXMtrlBuffer->Release();

	return S_OK;
}
Exemplo n.º 29
0
//-----------------------------------------------------------------------------
// Convert the mesh to the format specified by the given vertex declarations.
//-----------------------------------------------------------------------------
HRESULT CDXUTMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9 *pDecl, 
                                  bool bAutoComputeNormals, bool bAutoComputeTangents, 
                                  bool bSplitVertexForOptimalTangents )
{
    LPD3DXMESH pTempMesh = NULL;

    if( m_pMesh )
    {
        if( FAILED( m_pMesh->CloneMesh( m_pMesh->GetOptions(), pDecl,
                                        pd3dDevice, &pTempMesh ) ) )
        {
            SAFE_RELEASE( pTempMesh );
            return E_FAIL;
        }
    }


    // Check if the old declaration contains a normal.
    bool bHadNormal = false;
    bool bHadTangent = false;
    D3DVERTEXELEMENT9 aOldDecl[MAX_FVF_DECL_SIZE];
    if( m_pMesh && SUCCEEDED( m_pMesh->GetDeclaration( aOldDecl ) ) )
    {
        for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index )
        {
            if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL )
            {
                bHadNormal = true;
            }
            if( aOldDecl[index].Usage == D3DDECLUSAGE_TANGENT )
            {
                bHadTangent = true;
            }
        }
    }

    // Check if the new declaration contains a normal.
    bool bHaveNormalNow = false;
    bool bHaveTangentNow = false;
    D3DVERTEXELEMENT9 aNewDecl[MAX_FVF_DECL_SIZE];
    if( pTempMesh && SUCCEEDED( pTempMesh->GetDeclaration( aNewDecl ) ) )
    {
        for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index )
        {
            if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL )
            {
                bHaveNormalNow = true;
            }
            if( aNewDecl[index].Usage == D3DDECLUSAGE_TANGENT )
            {
                bHaveTangentNow = true;
            }
        }
    }

    SAFE_RELEASE( m_pMesh );

    if( pTempMesh )
    {
        m_pMesh = pTempMesh;

        if( !bHadNormal && bHaveNormalNow && bAutoComputeNormals )
        {
            // Compute normals in case the meshes have them
            D3DXComputeNormals( m_pMesh, NULL );
        }

        if( bHaveNormalNow && !bHadTangent && bHaveTangentNow && bAutoComputeTangents )
        {
            ID3DXMesh* pNewMesh;
            HRESULT hr;

            DWORD *rgdwAdjacency = NULL;
            rgdwAdjacency = new DWORD[m_pMesh->GetNumFaces() * 3];
            if( rgdwAdjacency == NULL )
                return E_OUTOFMEMORY;
            V( m_pMesh->GenerateAdjacency(1e-6f,rgdwAdjacency) );

            float fPartialEdgeThreshold;
            float fSingularPointThreshold;
            float fNormalEdgeThreshold;
            if( bSplitVertexForOptimalTangents )
            {
                fPartialEdgeThreshold = 0.01f;
                fSingularPointThreshold = 0.25f;
                fNormalEdgeThreshold = 0.01f;
            }
            else
            {
                fPartialEdgeThreshold = -1.01f;
                fSingularPointThreshold = 0.01f;
                fNormalEdgeThreshold = -1.01f;
            }

            // Compute tangents, which are required for normal mapping
            hr = D3DXComputeTangentFrameEx( m_pMesh, 
                                            D3DDECLUSAGE_TEXCOORD, 0, 
                                            D3DDECLUSAGE_TANGENT, 0,
                                            D3DX_DEFAULT, 0, 
                                            D3DDECLUSAGE_NORMAL, 0,
                                            0, rgdwAdjacency, 
                                            fPartialEdgeThreshold, fSingularPointThreshold, fNormalEdgeThreshold, 
                                            &pNewMesh, NULL );

            SAFE_DELETE_ARRAY( rgdwAdjacency );
            if( FAILED(hr) )
                return hr;

            SAFE_RELEASE( m_pMesh );
            m_pMesh = pNewMesh;
        }
    }

    return S_OK;
}
Exemplo n.º 30
0
void LoadXFile(
			   const std::string& filename, 
			   ID3DXMesh** meshOut,
			   std::vector<Mtrl>& mtrls, 
			   std::vector<IDirect3DTexture9*>& texs)
{
	// Step 1: Load the .x file from file into a system memory mesh.

	ID3DXMesh* meshSys      = 0;
	ID3DXBuffer* adjBuffer  = 0;
	ID3DXBuffer* mtrlBuffer = 0;
	DWORD numMtrls          = 0;

	HR(D3DXLoadMeshFromX(filename.c_str(), D3DXMESH_SYSTEMMEM, gd3dDevice,
		&adjBuffer,	&mtrlBuffer, 0, &numMtrls, &meshSys));


	// Step 2: Find out if the mesh already has normal info?

	D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE];
	HR(meshSys->GetDeclaration(elems));

	bool hasNormals = false;
	D3DVERTEXELEMENT9 term = D3DDECL_END();
	for(int i = 0; i < MAX_FVF_DECL_SIZE; ++i)
	{
		// Did we reach D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED, 0,0,0}?
		if(elems[i].Stream == 0xff )
			break;

		if( elems[i].Type == D3DDECLTYPE_FLOAT3 &&
			elems[i].Usage == D3DDECLUSAGE_NORMAL &&
			elems[i].UsageIndex == 0 )
		{
			hasNormals = true;
			break;
		}
	}


	// Step 3: Change vertex format to VertexPNT.

	D3DVERTEXELEMENT9 elements[64];
	UINT numElements = 0;
	VertexPNT::Decl->GetDeclaration(elements, &numElements);

	ID3DXMesh* temp = 0;
	HR(meshSys->CloneMesh(D3DXMESH_SYSTEMMEM, 
		elements, gd3dDevice, &temp));
	ReleaseCOM(meshSys);
	meshSys = temp;


	// Step 4: If the mesh did not have normals, generate them.

	if( hasNormals == false)
		HR(D3DXComputeNormals(meshSys, 0));


	// Step 5: Optimize the mesh.

	HR(meshSys->Optimize(D3DXMESH_MANAGED | 
		D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, 
		(DWORD*)adjBuffer->GetBufferPointer(), 0, 0, 0, meshOut));
	ReleaseCOM(meshSys); // Done w/ system mesh.
	ReleaseCOM(adjBuffer); // Done with buffer.

	// Step 6: Extract the materials and load the textures.

	if( mtrlBuffer != 0 && numMtrls != 0 )
	{
		D3DXMATERIAL* d3dxmtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();

		for(DWORD i = 0; i < numMtrls; ++i)
		{
			// Save the ith material.  Note that the MatD3D property does not have an ambient
			// value set when its loaded, so just set it to the diffuse value.
			Mtrl m;
			m.ambient   = d3dxmtrls[i].MatD3D.Diffuse;
			m.diffuse   = d3dxmtrls[i].MatD3D.Diffuse;
			m.spec      = d3dxmtrls[i].MatD3D.Specular;
			m.specPower = d3dxmtrls[i].MatD3D.Power;
			mtrls.push_back( m );

			// Check if the ith material has an associative texture
			if( d3dxmtrls[i].pTextureFilename != 0 )
			{
				// Yes, load the texture for the ith subset
				IDirect3DTexture9* tex = 0;
				char* texFN = d3dxmtrls[i].pTextureFilename;
				HR(D3DXCreateTextureFromFile(gd3dDevice, texFN, &tex));

				// Save the loaded texture
				texs.push_back( tex );
			}
			else
			{
				// No texture for the ith subset
				texs.push_back( 0 );
			}
		}
	}
	ReleaseCOM(mtrlBuffer); // done w/ buffer
}