📄 mload.cpp
字号:
}
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 + -