⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mload.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    }

    GXRELEASE(pDevice);

    GXRELEASE(pVertexRemapA);

    GXRELEASE(pVertexRemapB);

    if (FAILED(hr))
    {
        GXRELEASE(pMeshA);

        GXRELEASE(pMeshB);

        pMeshA  = NULL;

        pMeshB  = NULL;
    }

    *ppMeshA    = pMeshA;

    *ppMeshB    = pMeshB;

    return hr;
}

HRESULT CShaderPaletteSkin::CreateBasisVectors(LPDIRECT3DVERTEXBUFFER8 pVertexBuffer, LPDIRECT3DINDEXBUFFER8 pIndexBuffer)
{
	DWORD i;
	PSVertex* pVertices;
	WORD* pIndices;
	HRESULT hr;
	
	assert(pVertexBuffer);
	assert(pIndexBuffer);
	
	// Calculate number of vertices and indices
	D3DVERTEXBUFFER_DESC VBDesc;
	D3DINDEXBUFFER_DESC IBDesc;
	
	pVertexBuffer->GetDesc(&VBDesc);
	pIndexBuffer->GetDesc(&IBDesc);
	
	DWORD dwNumIndices;
	DWORD dwNumVertices;
	switch(IBDesc.Format)
	{
	case D3DFMT_INDEX16:
		dwNumIndices = IBDesc.Size / 2;
		break;
	case D3DFMT_INDEX32:
		dwNumIndices = IBDesc.Size / 4;
		break;
	default:
		assert(0);
		return E_FAIL;
	}
	
	dwNumVertices = VBDesc.Size / sizeof(PSVertex);
	
	// Get a pointer to the indices and the vertices
	hr = pVertexBuffer->Lock(0, 0, (BYTE**)&pVertices, 0);
	if (FAILED(hr))
		return hr;
	
	hr = pIndexBuffer->Lock(0, 0, (BYTE**)&pIndices, 0);
	if (FAILED(hr))
		return hr;
	
	// Clear the basis vectors
	for (i = 0; i < dwNumVertices; i++)
	{
		pVertices[i].S = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
		pVertices[i].T = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	}
	
	// Walk through the triangle list and calculate gradiants for each triangle.
	// Sum the results into the S and T components.
    for( i = 0; i < dwNumIndices; i += 3 )
    {       
		DWORD TriIndex[3];
		D3DXVECTOR3 du, dv;
		D3DXVECTOR3 edge01;
		D3DXVECTOR3 edge02;
		D3DXVECTOR3 cp;
		
		TriIndex[0] = pIndices[i];
		TriIndex[1] = pIndices[i+1];
		TriIndex[2] = pIndices[i+2];
		
		assert((TriIndex[0] < dwNumVertices) && (TriIndex[1] < dwNumVertices) && (TriIndex[2] < dwNumVertices));
		
		PSVertex& v0 = pVertices[TriIndex[0]];
		PSVertex& v1 = pVertices[TriIndex[1]];
		PSVertex& v2 = pVertices[TriIndex[2]];
		
		// x, s, t
		edge01 = D3DXVECTOR3( v1.Position.x - v0.Position.x, v1.Texture.x - v0.Texture.x, v1.Texture.y - v0.Texture.y );
		edge02 = D3DXVECTOR3( v2.Position.x - v0.Position.x, v2.Texture.x - v0.Texture.x, v2.Texture.y - v0.Texture.y );
		
		D3DXVec3Cross(&cp, &edge01, &edge02);
		if ( fabs(cp.x) > 1e-12 )
		{
			v0.S.x += -cp.y / cp.x;
			v0.T.x += -cp.z / cp.x;
			
			v1.S.x += -cp.y / cp.x;
			v1.T.x += -cp.z / cp.x;
			
			v2.S.x += -cp.y / cp.x;
			v2.T.x += -cp.z / cp.x;
		}
		
		// y, s, t
		edge01 = D3DXVECTOR3( v1.Position.y - v0.Position.y, v1.Texture.x - v0.Texture.x, v1.Texture.y - v0.Texture.y );
		edge02 = D3DXVECTOR3( v2.Position.y - v0.Position.y, v2.Texture.x - v0.Texture.x, v2.Texture.y - v0.Texture.y );
		
		D3DXVec3Cross(&cp, &edge01, &edge02);
		if ( fabs(cp.x) > 1e-12 )
		{
			v0.S.y += -cp.y / cp.x;
			v0.T.y += -cp.z / cp.x;
			
			v1.S.y += -cp.y / cp.x;
			v1.T.y += -cp.z / cp.x;
			
			v2.S.y += -cp.y / cp.x;
			v2.T.y += -cp.z / cp.x;
		}
		
		// z, s, t
		edge01 = D3DXVECTOR3( v1.Position.z - v0.Position.z, v1.Texture.x - v0.Texture.x, v1.Texture.y - v0.Texture.y );
		edge02 = D3DXVECTOR3( v2.Position.z - v0.Position.z, v2.Texture.x - v0.Texture.x, v2.Texture.y - v0.Texture.y );
		
		D3DXVec3Cross(&cp, &edge01, &edge02);
		if ( fabs(cp.x) > 1e-12 )
		{
			v0.S.z += -cp.y / cp.x;
			v0.T.z += -cp.z / cp.x;
			
			v1.S.z += -cp.y / cp.x;
			v1.T.z += -cp.z / cp.x;
			
			v2.S.z += -cp.y / cp.x;
			v2.T.z += -cp.z / cp.x;
		}
    }
	
    // Calculate the SxT vector
	for(i = 0; i < dwNumVertices; i++)
	{		
		// Normalize the S, T vectors
		D3DXVec3Normalize(&pVertices[i].S, &pVertices[i].S);
		D3DXVec3Normalize(&pVertices[i].T, &pVertices[i].T);
		
		// Get the cross of the S and T vectors
		D3DXVec3Cross(&pVertices[i].SxT, &pVertices[i].S, &pVertices[i].T);
		
		// Need a normalized normal
		D3DXVec3Normalize(&pVertices[i].Normal, &pVertices[i].Normal);
		
		// v coordinates go in opposite direction from the texture v increase in xyz
		pVertices[i].T = -pVertices[i].T;
		
		// Get the direction of the SxT vector
		if (D3DXVec3Dot(&pVertices[i].SxT, &pVertices[i].Normal) < 0.0f)
		{
			pVertices[i].SxT = -pVertices[i].SxT;
		}
	}
	
	pVertexBuffer->Unlock();
	pIndexBuffer->Unlock();
	
	return S_OK;

}



HRESULT CShaderPaletteSkin::GenerateMesh(SMeshContainer *pmcMesh)
{
    // ASSUMPTION:  pmcMesh->m_rgiAdjacency contains the current adjacency
    HRESULT hr  = S_OK;

    DWORD*  pAdjacencyIn    = NULL;

    DWORD   cFaces  = pmcMesh->m_pSkinMesh->GetNumFaces();

    pAdjacencyIn    = new DWORD[pmcMesh->m_pSkinMesh->GetNumFaces() * 3];

    if (pAdjacencyIn == NULL)
    {
        hr = E_OUTOFMEMORY;

        return hr;
    }
    
    memcpy(pAdjacencyIn, pmcMesh->m_rgiAdjacency, cFaces * 3 * sizeof(DWORD));

    GXRELEASE(pmcMesh->pMesh);
    GXRELEASE(pmcMesh->pMeshHW);
    GXRELEASE(pmcMesh->pMeshSW);

    pmcMesh->pMesh      = NULL;
    pmcMesh->pMeshHW    = NULL;
    pmcMesh->pMeshSW    = NULL;
    
	hr = pmcMesh->m_pSkinMesh->ConvertToIndexedBlendedMesh(D3DXMESH_SYSTEMMEM, pAdjacencyIn, PALETTE_SIZE/*255*/, NULL,
		&pmcMesh->cpattr, &pmcMesh->m_pBoneCombinationBuf, &pmcMesh->pMesh);
	if (FAILED(hr))
		return hr;
	
	//get attribute table
	pmcMesh->m_pAttrTable  = new D3DXATTRIBUTERANGE[pmcMesh->cpattr];
	
	hr = pmcMesh->pMesh->GetAttributeTable(pmcMesh->m_pAttrTable, NULL);
	
	if (FAILED(hr))
		return hr;
	
	//create new VB for rendering purposes
	MeshVertex* meshPtr;
	PSVertex* psPtr;
	
	m_pD3DDev->CreateVertexBuffer(sizeof(PSVertex)*(pmcMesh->pMesh->GetNumVertices()), D3DUSAGE_WRITEONLY, 
		0, D3DPOOL_DEFAULT, &m_pRenderVB);
	
	//lock and fill
	m_pRenderVB->Lock(0, 0, (BYTE**)&psPtr, 0);
	pmcMesh->pMesh->LockVertexBuffer(0, (BYTE**)&meshPtr);
	
	for(int i = 0; i < pmcMesh->pMesh->GetNumVertices(); i++)
	{
		memset(&psPtr[i], 0, sizeof(PSVertex));
		
		psPtr[i].Position = meshPtr[i].Position;
		psPtr[i].weight0  = meshPtr[i].weight;
		psPtr[i].weight1  = 1.0f - meshPtr[i].weight;
		psPtr[i].index1	  = (float)((int)(meshPtr[i].indices & 0x000000FF)) * 3.f;
		psPtr[i].index2   = (float)((int)((meshPtr[i].indices & 0x0000FF00) >> 8)) * 3.f;
		psPtr[i].Normal   = meshPtr[i].Normal;
		psPtr[i].Texture  = meshPtr[i].Texture;
	}
	pmcMesh->pMesh->UnlockVertexBuffer();
	m_pRenderVB->Unlock();
	
	//go through and fill in S, T, SxT
	LPDIRECT3DINDEXBUFFER8 tempIB;
	pmcMesh->pMesh->GetIndexBuffer(&tempIB);
	CreateBasisVectors(m_pRenderVB, tempIB);
	tempIB->Release();  //decrement reference count

    delete[] pAdjacencyIn;

    return hr;
}




HRESULT CShaderPaletteSkin::LoadMesh(LPDIRECTXFILEDATA pxofobjCur, DWORD options, SFrame *pframeParent)
{
    HRESULT hr = S_OK;
    SMeshContainer *pmcMesh = NULL;
    LPD3DXBUFFER pbufMaterials = NULL;
    LPD3DXBUFFER pbufAdjacency = NULL;
    DWORD cchName;
    UINT cFaces;
    UINT iMaterial;
    
    pmcMesh = new SMeshContainer();
    if (pmcMesh == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto e_Exit;
    }
    
    hr = pxofobjCur->GetName(NULL, &cchName);
    if (FAILED(hr))
        goto e_Exit;
    
    if (cchName > 0)
    {
        pmcMesh->szName = new char[cchName];
        if (pmcMesh->szName == NULL)
        {
            hr = E_OUTOFMEMORY;
            goto e_Exit;
        }
        
        hr = pxofobjCur->GetName(pmcMesh->szName, &cchName);
        if (FAILED(hr))
            goto e_Exit;
    }
    
    hr = D3DXLoadSkinMeshFromXof(pxofobjCur, options, m_pD3DDev, &pbufAdjacency, &pbufMaterials, &pmcMesh->cMaterials, 
        &pmcMesh->m_pBoneNamesBuf, &pmcMesh->m_pBoneOffsetBuf, &pmcMesh->m_pSkinMesh);
    if (FAILED(hr))
        goto e_Exit;
    
    cFaces = pmcMesh->m_pSkinMesh->GetNumFaces();

    // Process skinning data
    if (pmcMesh->m_pSkinMesh->GetNumBones())
    {
        pmcMesh->m_pBoneMatrix = new D3DXMATRIX*[pmcMesh->m_pSkinMesh->GetNumBones()];
        if (pmcMesh->m_pBoneMatrix == NULL)
            goto e_Exit;
        pmcMesh->m_pBoneOffsetMat = reinterpret_cast<D3DXMATRIX*>(pmcMesh->m_pBoneOffsetBuf->GetBufferPointer());
        LPDWORD pAdjacencyIn = static_cast<LPDWORD>(pbufAdjacency->GetBufferPointer());

        pmcMesh->m_rgiAdjacency = new DWORD[cFaces * 3];

        if (pmcMesh->m_rgiAdjacency == NULL)
        {
            hr = E_OUTOFMEMORY;

            goto e_Exit;
        }

        memcpy(pmcMesh->m_rgiAdjacency, pAdjacencyIn, cFaces * 3 * sizeof(DWORD));
        
        hr = GenerateMesh(pmcMesh);

        if (FAILED(hr))
            goto e_Exit;
    }
    else
    {
        pmcMesh->m_pSkinMesh->GetOriginalMesh(&(pmcMesh->pMesh));
        pmcMesh->m_pSkinMesh->Release();
        pmcMesh->m_pSkinMesh = NULL;
        pmcMesh->cpattr = pmcMesh->cMaterials;
    }
    
    if ((pbufMaterials == NULL) || (pmcMesh->cMaterials == 0))
    {
        pmcMesh->rgMaterials = new D3DMATERIAL8[1];
        pmcMesh->pTextures = new LPDIRECT3DTEXTURE8[1];
        if (pmcMesh->rgMaterials == NULL || pmcMesh->pTextures == NULL)
        {
            hr = E_OUTOFMEMORY;
            goto e_Exit;
        }
        
        memset(pmcMesh->rgMaterials, 0, sizeof(D3DXMATERIAL));
        pmcMesh->rgMaterials[0].Diffuse.r = 0.5f;
        pmcMesh->rgMaterials[0].Diffuse.g = 0.5f;
        pmcMesh->rgMaterials[0].Diffuse.b = 0.5f;
        pmcMesh->rgMaterials[0].Specular = pmcMesh->rgMaterials[0].Diffuse;
        pmcMesh->pTextures[0] = NULL;
    }
    else
    {
        pmcMesh->rgMaterials = new D3DMATERIAL8[pmcMesh->cMaterials];
        pmcMesh->pTextures = new LPDIRECT3DTEXTURE8[pmcMesh->cMaterials];
        if (pmcMesh->rgMaterials == NULL || pmcMesh->pTextures == NULL)
        {
            hr = E_OUTOFMEMORY;
            goto e_Exit;
        }
        
        LPD3DXMATERIAL pMaterials = (LPD3DXMATERIAL)pbufMaterials->GetBufferPointer();
        
        for (iMaterial = 0; iMaterial < pmcMesh->cMaterials; iMaterial++)
        {
            
            pmcMesh->rgMaterials[iMaterial] = pMaterials[iMaterial].MatD3D;
            
            pmcMesh->pTextures[iMaterial] = NULL;
            if (pMaterials[iMaterial].pTextureFilename != NULL)
            {
                TCHAR szPath[MAX_PATH] = "tiny_skin.bmp";
                //DXUtil_FindMediaFile(szPath, pMaterials[iMaterial].pTextureFilename);
				//strcpy(szPath, GetFilePath(pMaterials[iMaterial].pTextureFilename).c_str());

                hr = D3DXCreateTextureFromFile(m_pD3DDev, GetFilePath("tiny_skin.bmp").c_str(), &(pmcMesh->pTextures[iMaterial]));
                if (FAILED(hr))
                    pmcMesh->pTextures[iMaterial] = NULL;
            }
        }
    }
    
    // add the mesh to the parent frame
    pframeParent->AddMesh(pmcMesh);
    pmcMesh = NULL;
    
e_Exit:
    delete pmcMesh;
    
    GXRELEASE(pbufAdjacency);
    GXRELEASE(pbufMaterials);

    return hr;
}




HRESULT CShaderPaletteSkin::LoadFrames(LPDIRECTXFILEDATA pxofobjCur, SDrawElement *pde,
                                      DWORD options, SFrame *pframeParent)
{
    HRESULT hr = S_OK;
    LPDIRECTXFILEDATA pxofobjChild = NULL;
    LPDIRECTXFILEOBJECT pxofChild = NULL;
    const GUID *type;
    DWORD cbSize;
    D3DXMATRIX *pmatNew;
    SFrame *pframeCur;
    DWORD cchName;
    
    // Get the type of the object
    hr = pxofobjCur->GetType(&type);
    if (FAILED(hr))
        goto e_Exit;
    
    
    if (*type == TID_D3DRMMesh)
    {
        hr = LoadMesh(pxofobjCur, options, pframeParent);
        if (FAILED(hr))
            goto e_Exit;
    }
    else if (*type == TID_D3DRMFrameTransformMatrix)
    {
        hr = pxofobjCur->GetData(NULL, &cbSize, (PVOID*)&pmatNew);
        if (FAILED(hr))
            goto e_Exit;
        
        // update the parents matrix with the new one
        pframeParent->matRot = *pmatNew;
        pframeParent->matRotOrig = *pmatNew;
    }
    else if (*type == TID_D3DRMAnimationSet)
    {
        LoadAnimationSet(pxofobjCur, pde, options, pframeParent);
    }
    else if (*type == TID_D3DRMAnimation)
    {
        LoadAnimation(pxofobjCur, pde, options, pframeParent);
    }
    else if (*type == TID_D3DRMFrame)
    {
        pframeCur = new SFrame();
        if (pframeCur == NULL)
        {
            hr = E_OUTOFMEMORY;
            goto e_Exit;
        }
        
        hr = pxofobjCur->GetName(NULL, &cchName);
        if (FAILED(hr))
            goto e_Exit;
        
        if (cchName > 0)
        {
            pframeCur->szName = new char[cchName];
            if (pframeCur->szName == NULL)
            {
                hr = E_OUTOFMEMORY;
                goto e_Exit;
            }
            
            hr = pxofobjCur->GetName(pframeCur->szName, &cchName);
            if (FAILED(hr))
                goto e_Exit;
        }
        
        pframeParent->AddFrame(pframeCur);
        
        // Enumerate child objects.
        // Child object can be data, data reference or binary.
        // Use QueryInterface() to find what type of object a child is.
        while (SUCCEEDED(pxofobjCur->GetNextObject(&pxofChild)))
        {
            // Query the child for it's FileData
            hr = pxofChild->QueryInterface(IID_IDirectXFileData,
                (LPVOID *)&pxofobjChild);
            if (SUCCEEDED(hr))
            {
                hr = LoadFrames(pxofobjChild, pde, options, pframeCur);
                if (FAILED(hr))
                    goto e_Exit;
                
                GXRELEASE(pxofobjChild);
            }
            
            GXRELEASE(pxofChild);
        }
        
    }
    
e_Exit:
    GXRELEASE(pxofobjChild);
    GXRELEASE(pxofChild);
    return hr;
}


         
                                      
HRESULT  CShaderPaletteSkin::DeleteSelectedMesh()
{
    if (m_pdeSelected != NULL)
    {
        SDrawElement *pdeCur = m_pdeHead;
        SDrawElement *pdePrev = NULL;
        while ((pdeCur != NULL) && (pdeCur != m_pdeSelected))
        {
            pdePrev = pdeCur;
            pdeCur = pdeCur->pdeNext;
        }

        if (pdePrev == NULL)
        {
            m_pdeHead = m_pdeHead->pdeNext;
        }
        else
        {
            pdePrev->pdeNext = pdeCur->pdeNext;
        }

        m_pdeSelected->pdeNext = NULL;
        if (m_pdeHead == m_pdeSelected)
            m_pdeHead = NULL;
        delete m_pdeSelected;
        m_pdeSelected = NULL;
    }

    return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -