Create a projector in DirectX

来源:互联网 发布:linux 程序输出重定向 编辑:程序博客网 时间:2024/05/14 11:09

//[1].set render state:enable alpha blend
 g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
 g_pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
 g_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
 g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,         D3DCULL_CCW);

 //[2].The image you want to project:g_projectTexture
 g_pd3dDevice->SetTexture(0, g_projectTexture);

 //[3].使用自动生成贴图坐标功能`
 g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);

 //打开贴图坐标矩阵转换功能`
 g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT4 | D3DTTFF_PROJECTED);
 g_pd3dDevice->SetSamplerState(0,  D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
 g_pd3dDevice->SetSamplerState(0,  D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);

 //[4].The inverse matrix of matView
 D3DXMATRIX inv_view = matView;
 D3DXMatrixInverse(&inv_view, NULL, &matView);

 //[5].Create a projector and set its position view and projection matrix
 D3DXVECTOR3 vLightPos(1.0f, 1.0f, -15.0f);
 D3DXVECTOR3 vLightUp(0.0f, 1.0f, 0.0f);
 D3DXVECTOR3 vLightLookat(0.0f, 0.0f, 0.0f);
 //D3DXVec3TransformCoord(&vLightPos, &vLightPos, &matWorld);
 /*D3DXVec3TransformCoord(&vLightLookat, &vLightLookat, &matWorld);*/

 D3DXMATRIX light_view_matrix;
 D3DXMatrixLookAtLH(&light_view_matrix, &vLightPos, &vLightLookat, &vLightUp);
 D3DXMATRIX light_projection_matrix;
 D3DXMatrixPerspectiveFovLH(&light_projection_matrix, 30.0f, 1.0f, 0.1f, 100.0f);
 D3DXMATRIX uv_offset_matrix;
 D3DXMatrixIdentity(&uv_offset_matrix);
 D3DXMatrixScaling(&uv_offset_matrix, 0.1, 0.1, 0);
 D3DXMATRIX offsetMatrix;
 D3DXMATRIX restoreMatrix;
 D3DXMatrixTranslation(&offsetMatrix, -0.5f, -0.5f, -0.5f);
 D3DXMatrixTranslation(&restoreMatrix, 0.5f, 0.5f, 0.5f);

 //[6].Create a texture matrix ->that's the key point
 D3DXMATRIX texture_matrix = offsetMatrix * inv_view * light_view_matrix * light_projection_matrix * restoreMatrix;
 //use the texture matrix
 g_pd3dDevice->SetTransform(D3DTS_TEXTURE0, &texture_matrix);
 g_pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
 //project what you see
 for (DWORD i = 0; i < g_dwNumMtrls; i++)
 {
  g_pd3dDevice->SetMaterial(&g_pMaterials[i]);
  g_pMeshTiny->DrawSubset(i);
 }
 g_pMirrorMesh->DrawSubset(0);

 //[7].Recover Sample State
 g_pd3dDevice->SetSamplerState(0,  D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
 g_pd3dDevice->SetSamplerState(0,  D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
 g_pd3dDevice->SetSamplerState(0,  D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
 D3DXMatrixIdentity(&inv_view);
 //g_pd3dDevice->SetTransform(D3DTS_TEXTURE0, &inv_view);
 g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
 g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);

 

 

//[6].Create a texture matrix ->that's the key point

First you got to create a matrix which is the inverse matrix of matView.It's easy to understand projector is project what you see,so you have to calculate the inverse matrix of the matView to recover the coordinate of the model to world matrix

Then you have to create the projector's view matrix and projection matrix just like create a Camera's

After using the texture matrix now you can create a effect like projector just as the two images show.

 

原创粉丝点击