HRESULT hr = S_OK;
LPD3DXMESH pMeshSysMem = NULL, pMeshSysMem2 = NULL;
D3DXLoadMeshFromX(L"sphere.x", D3DXMESH_SYSTEMMEM, pd3dDevice, NULL, NULL, NULL, NULL, &pMeshSysMem);
VertexModel* pV;
pMeshSysMem->LockVertexBuffer(0,(void**)&pV);
for(int i = 0;i < pMeshSysMem->GetNumVertices();i++)
{
VertexModel p = pV[i];
LogHelper.Trace("%d\n",i);
// LogHelper.Trace("%10.6f\t%10.6f\t%10.6f\n",pV[i].vPos.x,pV[i].vPos.y,pV[i].vPos.z);
// LogHelper.Trace("%10.6f\t%10.6f\n",pV[i].vTex.x,pV[i].vTex.y);
// LogHelper.Trace("%10.6f\t%10.6f\t%10.6f\n\n",pV[i].vNormal.x,pV[i].vNormal.y,pV[i].vNormal.z);
}
pMeshSysMem->UnlockVertexBuffer();
// D3DFVF_XYZ
// DWORD fvf = pMeshSysMem->GetFVF();
D3DVERTEXELEMENT9 decl[]=
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
D3DDECL_END()
};
hr = pMeshSysMem->CloneMesh(D3DXMESH_MANAGED, decl, pd3dDevice, &pMeshSysMem2);
DWORD fvf = pMeshSysMem->GetFVF();
VertexWithTan* pVT;
pMeshSysMem2->LockVertexBuffer(0,(void**)&pVT);
for(int i = 0;i < pMeshSysMem2->GetNumVertices();i++)
{
VertexWithTan p = pVT[i];
}
pMeshSysMem2->UnlockVertexBuffer();
// compute the normals
// D3DXComputeNormals(pMeshSysMem2,NULL);
// D3DXComputeTangent(pMeshSysMem2,0,0,0,TRUE,NULL);
// D3DXComputeTangentFrame(pMeshSysMem2, D3DXTANGENT_WRAP_UV);
D3DXComputeTangentFrameEx(pMeshSysMem, 1, 0, 3, 0, D3DX_DEFAULT, 0, D3DX_DEFAULT, 0,
D3DXTANGENT_WRAP_UV, NULL, 0, 0, 0,&pMeshSysMem, NULL);
// 这个究竟要设置什么样的组合才可以呢??
// D3DXComputeTangentFrame(pMeshSysMem2, D3DXTANGENT_WRAP_UV | D3DXTANGENT_ORTHOGONALIZE_FROM_U | D3DXTANGENT_GENERATE_IN_PLACE);
// 用两种格式的顶点看看里面到底是什么格式的数据
pMeshSysMem2->LockVertexBuffer(0,(void**)&pVT);
for(int i = 0;i < pMeshSysMem2->GetNumVertices();i++)
{
VertexWithTan p = pVT[i];
// LogHelper.Trace("%d\n",i);
// LogHelper.Trace("%10.6f\t%10.6f\t%10.6f\n",pVT[i].vPos.x,pVT[i].vPos.y,pVT[i].vPos.z);
// LogHelper.Trace("%10.6f\t%10.6f\n",pVT[i].vTex.x,pVT[i].vTex.y);
// LogHelper.Trace("%10.6f\t%10.6f\t%10.6f\n\n",pVT[i].vNormal.x,pVT[i].vNormal.y,pVT[i].vNormal.z);
}
pMeshSysMem2->UnlockVertexBuffer();
D3DVERTEXELEMENT9 decl2[]=
{
// stream, offset, type, method, semantic type (for example normal), ?
{0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 16, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 28, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0},
D3DDECL_END()
};
hr = pMeshSysMem2->CloneMesh(D3DXMESH_MANAGED, decl2, pd3dDevice, &m_pD3DXMesh);
fvf = pMeshSysMem->GetFVF();
// cleanup
SAFE_RELEASE(pMeshSysMem);
SAFE_RELEASE(pMeshSysMem2);
if( FAILED( hr = D3DXCreateEffectFromFile( pd3dDevice, L"hlsl.fx", NULL, NULL,
D3DXSHADER_DEBUG, NULL, &m_pEffect, NULL ) ) )
return hr;
if(FAILED(D3DXCreateTextureFromFile(pd3dDevice, L"earth.tga",&m_pColorMap)))
return E_FAIL;
if(FAILED(D3DXCreateTextureFromFile(pd3dDevice, L"normal.tga",&m_pBumpMap)))
return E_FAIL;
D3DXMatrixIdentity( &g_World );
pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
// pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE );
// pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
D3DXMatrixPerspectiveFovLH(&g_Projection, 0.05f,
640.0f/480.0f, 1.0f, 500.0f);
直接上代码还是
主要问题就是自己填充一个MESH网格,然后计算法线和切线(法线我都自己填充好了),现在有两个问题
1,不知道D3DXComputeTangent如何实现的,
2,不知道用新版本的应该如何传递参数
RENDER函数就是设置寄存器+渲染,掠过了
D3DXComputeNormals(pMeshSysMem,NULL);
D3DXComputeTangent(pMeshSysMem,0,0,0,FALSE,NULL);
SHADER代码很简单,就是根据顶点中的TANGENT值,法线值,计算一个有世界空间变换到切线空间矩阵,然后在这个空间进行光照计算
// 计算矩阵
float3x3 worldToTangentSpace;
worldToTangentSpace[0] = mul(Tangent, matWorld);
worldToTangentSpace[1] = mul(cross(Tangent, Normal), matWorld);
worldToTangentSpace[2] = mul(Normal, matWorld);
//变换
Out.Light.xyz = mul(worldToTangentSpace, vecLightDir);
// L
float3 PosWorld = normalize(mul(Pos, matWorld));
float3 Viewer = vecEye - PosWorld; // V
Out.View = mul(worldToTangentSpace, Viewer);
//光照计算
float3 bumpNormal = 2 * (tex2D(BumpMapSampler, Tex) - 0.5); // bump map
float3 LightDir = normalize(Light); // L
float3 ViewDir = normalize(View); // V
float4 diff = saturate(dot(bumpNormal, LightDir)); // diffuse comp.