コード例 #1
0
ファイル: pmesh.cpp プロジェクト: chenbk85/3dlearn
//
// Framework functions
//
bool Setup()
{
	HRESULT hr = 0;

	//
	// Load the XFile data.
	//

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

	hr = D3DXLoadMeshFromX(  
		"bigship1.x",
		D3DXMESH_MANAGED,
		Device,
		&adjBuffer,
		&mtrlBuffer,
		0,
		&numMtrls,
		&SourceMesh);

	if(FAILED(hr))
	{
		::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0);
		return false;
	}

	//
	// Extract the materials, load textures.
	//

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

		for(int i = 0; i < numMtrls; i++)
		{
			// the MatD3D property doesn't have an ambient value set
			// when its loaded, so set it now:
			mtrls[i].MatD3D.Ambient = mtrls[i].MatD3D.Diffuse;

			// save the ith material
			Mtrls.push_back( mtrls[i].MatD3D );

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

				// save the loaded texture
				Textures.push_back( tex );
			}
			else
			{
				// no texture for the ith subset
				Textures.push_back( 0 );
			}
		}
	}
	d3d::Release<ID3DXBuffer*>(mtrlBuffer); // done w/ buffer

	//
	// Optimize the mesh.
	//

	hr = SourceMesh->OptimizeInplace(		
		D3DXMESHOPT_ATTRSORT |
		D3DXMESHOPT_COMPACT  |
		D3DXMESHOPT_VERTEXCACHE,
		(DWORD*)adjBuffer->GetBufferPointer(),
		(DWORD*)adjBuffer->GetBufferPointer(), // new adjacency info
		0, 0);

	if(FAILED(hr))
	{
		::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0);
		d3d::Release<ID3DXBuffer*>(adjBuffer); // free
		return false;
	}

	//
	// Generate the progressive mesh. 
	//

	hr = D3DXGeneratePMesh(
		SourceMesh,
		(DWORD*)adjBuffer->GetBufferPointer(), // adjacency
		0,                  // default vertex attribute weights
		0,                  // default vertex weights
		1,                  // simplify as low as possible
		D3DXMESHSIMP_FACE,  // simplify by face count
		&PMesh);

	d3d::Release<ID3DXMesh*>(SourceMesh);  // done w/ source mesh
	d3d::Release<ID3DXBuffer*>(adjBuffer); // done w/ buffer

	if(FAILED(hr))
	{
		::MessageBox(0, "D3DXGeneratePMesh() - FAILED", 0, 0);
		return false;
	}

	// set to original detail
	DWORD maxFaces = PMesh->GetMaxFaces();
	PMesh->SetNumFaces(maxFaces);

	//
	// Set texture filters.
	//

	Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

	// 
	// Set Lights.
	//

	D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f);
	D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);
	D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);

	Device->SetLight(0, &light);
	Device->LightEnable(0, true);
	Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
	Device->SetRenderState(D3DRS_SPECULARENABLE, true);

	//
	// Set camera.
	//

	D3DXVECTOR3 pos(-8.0f, 4.0f, -12.0f);
	D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);

	//pos/=2;
	D3DXMATRIX V;
	D3DXMatrixLookAtLH(
		&V,
		&pos,
		&target,
		&up);

	Device->SetTransform(D3DTS_VIEW, &V);

	//
	// Set projection matrix.
	//

	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(
			&proj,
			D3DX_PI * 0.5f, // 90 - degree
			(float)Width / (float)Height,
			1.0f,
			1000.0f);
	Device->SetTransform(D3DTS_PROJECTION, &proj);

	return true;
}
コード例 #2
0
ファイル: Mesh.cpp プロジェクト: agmonr/Emotion_for_windows
//-----------------------------------------------------------------------------
// 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;
}
コード例 #3
0
ファイル: MeshLoadX.cpp プロジェクト: recter/D3DXTest
//-------------------------------------------------------------------------
bool CMeshLoadX::Setup(IDirect3DDevice9* pDevice,int nWidth,int nHeight)
{
	if (0 == pDevice)
	{
		return false;
	}
	m_Device = pDevice;
	m_nHeight = nHeight;
	m_nWidth = nWidth;

	// 读取X文件并解析
	{
		HRESULT hr = 0;
		ID3DXBuffer* adjBuffer = 0;
		ID3DXBuffer* mtrlBuffer = 0;
		DWORD	numMtrls = 0;
		hr = D3DXLoadMeshFromX(
			s_szMeshFilePath,
			D3DXMESH_MANAGED,
			m_Device,
			&adjBuffer,
			&mtrlBuffer,
			0,
			&numMtrls,
			&m_SourceMesh);

		if (FAILED(hr))
		{
			::MessageBox(0,"CMeshLoadX::Setup hr is failed",0,0);
			return false;
		}

		if (mtrlBuffer != 0 && numMtrls != 0)
		{
			D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();
			for (int nIndex = 0; nIndex < numMtrls; ++nIndex)
			{
				mtrls[nIndex].MatD3D.Ambient = mtrls[nIndex].MatD3D.Diffuse;
				m_vecMtrls.push_back(mtrls[nIndex].MatD3D);
				if (mtrls[nIndex].pTextureFilename != 0)
				{
					IDirect3DTexture9* pTex = 0;
					D3DXCreateTextureFromFile(m_Device,mtrls[nIndex].pTextureFilename,&pTex);
					m_vecTextures.push_back(pTex);
				}
				else
				{
					m_vecTextures.push_back(0);
				}
			}
		}

		d3d::Release<ID3DXBuffer*>(mtrlBuffer);

		hr = m_SourceMesh->OptimizeInplace(		
			D3DXMESHOPT_ATTRSORT |
			D3DXMESHOPT_COMPACT  |
			D3DXMESHOPT_VERTEXCACHE,
			(DWORD*)adjBuffer->GetBufferPointer(),
			(DWORD*)adjBuffer->GetBufferPointer(), // new adjacency info
			0, 0);

		if(FAILED(hr))
		{
			::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0);
			return false;
		}

		hr = D3DXGeneratePMesh(
			m_SourceMesh,
			(DWORD*)adjBuffer->GetBufferPointer(),
			0,
			0,
			1,
			D3DXMESHSIMP_FACE,
			&m_ProcessMesh);

		
	

		if(FAILED(hr))
		{
			::MessageBox(0, "D3DXGeneratePMesh() - FAILED", 0, 0);
			return false;
		}

		m_ProcessMesh->SetNumFaces(m_ProcessMesh->GetMaxFaces());

		d3d::Release<ID3DXBuffer*>(adjBuffer); // done w/ buffer

	}

	// 新建字体
	{
		D3DXFONT_DESCA lf;
		::ZeroMemory(&lf,sizeof(D3DXFONT_DESCA));

		lf.Height = 25;
		lf.Width = 14;
		lf.Weight = 500;
		lf.Italic = false;
		lf.CharSet = DEFAULT_CHARSET;
#pragma warning ( disable: 4996 )
		strcpy(lf.FaceName,"Times New Roman");
#pragma warning ( default : 4996 )
		D3DXCreateFontIndirect(m_Device,&lf,&m_XFont);
	}

	// 写Mesh数据文件
	{
		m_OutFile.open("MeshDumpX.txt");

		__dumpVertices(m_OutFile, m_SourceMesh);
		__dumpIndices(m_OutFile, m_SourceMesh);
		__dumpAttributeTable(m_OutFile, m_SourceMesh); 	
		__dumpAttributeBuffer(m_OutFile, m_SourceMesh);		
		__dumpAdjacencyBuffer(m_OutFile, m_SourceMesh);

		m_OutFile.close();
	}
	
	d3d::BoundingSphere boundingSphere;
	d3d::BoundingBox    boundingBox;

	__ComputeBoundingSphere(m_SourceMesh, &boundingSphere);
	__ComputeBoundingBox(m_SourceMesh, &boundingBox);

	D3DXCreateSphere(
		m_Device,
		boundingSphere._radius,
		20,
		20,
		&m_SphereMesh,
		0);

	D3DXCreateBox(
		m_Device,
		boundingBox._max.x - boundingBox._min.x,
		boundingBox._max.y - boundingBox._min.y,
		boundingBox._max.z - boundingBox._min.z,
		&m_BoxMesh,
		0);

	//
	// Set texture filters.
	//

	m_Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	m_Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	m_Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

	// 
	// Set Lights.
	//

	D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f);
	D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);
	D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);

	m_Device->SetLight(0, &light);
	m_Device->LightEnable(0, true);
	m_Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
	m_Device->SetRenderState(D3DRS_SPECULARENABLE, true);

	//
	// Set camera.
	//

	D3DXVECTOR3 pos(4.0f, 4.0f, -20.0f);
	D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);

	D3DXMATRIX V;
	D3DXMatrixLookAtLH(
		&V,
		&pos,
		&target,
		&up);

	m_Device->SetTransform(D3DTS_VIEW, &V);

	//
	// Set projection matrix.
	//

	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(
		&proj,
		D3DX_PI * 0.5f, // 90 - degree
		(float)m_nWidth / (float)m_nHeight,
		1.0f,
		1000.0f);
	m_Device->SetTransform(D3DTS_PROJECTION, &proj);

	return true;
}