stencilbuffer的比较是用参考值与目标值比较,参考值在前面,所以如果比较函数是小于,那么是参考值小于目标值。
COLORWITEENABLE渲染状态有点特殊,禁用可以是FALSE,但启用一遍要用0x7.因为COLORWRITEENABLE可以控制4个颜色通道。分别用低4为控制,0x7可启用的蓝绿红3个通道。
DirectX所有的Draw函数要根据三角形的朝向,不要以为只有DrawIndexedPrimitive.
使用CD3DMesh的时候要注意,一般加载的模型以具有所需的顶点格式,记住调用SetFVF
当采用固定管线启用关照不成功是,如果灯管材质都设置了,模型还是黑的,可能是光照的Diffuse值为0,影响Diffuse可能是物体没有法线,所以用CD3DMesh要特别注意,一定要SetFVF一下,保证有需要的格式。当然其他的可能也有,只是特别提示这个,以便能在需要的时候想起来。
HRESULT CMyD3DApplication::LoadXFile(TCHAR* name) { HRESULT hr; LPD3DXMESH pMeshSysMem = NULL, pMeshSysMem2 = NULL; if (FAILED (D3DXLoadMeshFromX(name, D3DXMESH_SYSTEMMEM, m_pd3dDevice, NULL, NULL, NULL, NULL, &pMeshSysMem))) return E_FAIL; D3DVERTEXELEMENT9 decl[]= { // stream, offset, type, method, semantic type (for example normal), ? {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END() }; hr = pMeshSysMem->CloneMesh(D3DXMESH_MANAGED, decl, m_pd3dDevice, &m_pD3DXMesh); // compute the normals hr = D3DXComputeNormals(m_pD3DXMesh,NULL); if(FAILED(hr)) { SAFE_RELEASE(pMeshSysMem); return E_FAIL; } // cleanup SAFE_RELEASE(pMeshSysMem); return S_OK; }
如果将decl中的NORMAL,POSITION任意一个改成D3DDECLTYPE_FLOAT4,并且将offset进行相应修改, 则下面的计算法线的函数将会报错。具体原因暂时未能在Doc明确查明,只是找到一张FVF映射到Vertex Element 的图,因为FVF是D3D中比较规范并支持的,所以按FVF格式应该没问题。
7. 以前总认为由于float在计算后存在误差,以至于认为两次相同的 A * B 相乘结果会不同。这样的想法是错误,硬件是极其固件化的,即使结果可能存在误差,但是两次相同的浮点数相乘总能得到完全相同的结果。在ShadowVolume给我一个教训,要想让原物体网格和阴影网格完完全全重叠,必须让阴影网格和原物体网格使用相同的变换矩阵。例如:A是用于原物体网格的变换矩阵。W是用于阴影网格的矩阵。A = B * ( C * D ); W = ( B * C ) * D; 这样的A,W就是问题,他们的结果是存在极细微误差的,而这点误差就会导致z fighting。 如果想让两者完全相同的则两次的计算顺序也必须相同。 紧记。
8. 在使用DXUT框架时,一般情况下,如窗口大小改变,将会引起OnLostDevice()和OnCreateDevice()被调用。 但是如果在OnLostDevice()中未能将所有存在于POOL_DEFAULT的资源释放,则DXUT框架会调用OnDestroyDevice(),并重新调用OnCreateDevice(). 特别注意。
9. 并不是所有网格的纹理坐标都在(0,1),所以不要盲目的设定纹理U,V的访问模式为Clamp,有的物体网格是需要Wrap的,如Media\tiger\tiger.x。让我找了1个小时的bug才找出来是UV访问模式的问题。
10. 在pick操作中,我们应该知道投影平面是位于z=1的上的,另外点在投影平面的位置可能被缩放过,所以需要从投影矩阵的读出缩放量,在转换成正确的值。