📄 dxutcamera.cpp
字号:
" VS_OUTPUT Output;\r\n"
"\r\n"
" // Transform the position from object space to homogeneous projection space\r\n"
" Output.Position = mul(vPos, g_mWorldViewProjection);\r\n"
"\r\n"
" // Transform the normal from object space to world space\r\n"
" float3 vNormalWorldSpace;\r\n"
" vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)\r\n"
"\r\n"
" // Compute simple directional lighting equation\r\n"
" Output.Diffuse.rgb = g_MaterialDiffuseColor * max(0,dot(vNormalWorldSpace, g_LightDir));\r\n"
" Output.Diffuse.a = 1.0f;\r\n"
"\r\n"
" return Output;\r\n"
"}\r\n"
"\r\n"
"float4 RenderWith1LightNoTexturePS( float4 Diffuse : COLOR0 ) : COLOR0\r\n"
"{\r\n"
" return Diffuse;\r\n"
"}\r\n"
"\r\n"
"technique RenderWith1LightNoTexture\r\n"
"{\r\n"
" pass P0\r\n"
" {\r\n"
" VertexShader = compile vs_2_0 RenderWith1LightNoTextureVS();\r\n"
" PixelShader = compile ps_2_0 RenderWith1LightNoTexturePS();\r\n"
" }\r\n"
"}\r\n"
"";
UINT dwBufferSize = (UINT)strlen(g_strBuffer) + 1;
V_RETURN( D3DXCreateEffect( s_pd3d9Device, g_strBuffer, dwBufferSize, NULL, NULL, D3DXFX_NOT_CLONEABLE, NULL, &s_pD3D9Effect, NULL ) );
// Load the mesh with D3DX and get back a ID3DXMesh*. For this
// sample we'll ignore the X file's embedded materials since we know
// exactly the model we're loading. See the mesh samples such as
// "OptimizedMesh" for a more generic mesh loading example.
V_RETURN( DXUTCreateArrowMeshFromInternalArray( s_pd3d9Device, &s_pD3D9Mesh ) );
// Optimize the mesh for this graphics card's vertex cache
// so when rendering the mesh's triangle list the vertices will
// cache hit more often so it won't have to re-execute the vertex shader
// on those vertices so it will improve perf.
DWORD* rgdwAdjacency = new DWORD[s_pD3D9Mesh->GetNumFaces() * 3];
if( rgdwAdjacency == NULL )
return E_OUTOFMEMORY;
V( s_pD3D9Mesh->GenerateAdjacency(1e-6f,rgdwAdjacency) );
V( s_pD3D9Mesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
delete []rgdwAdjacency;
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDirectionWidget::OnD3D9ResetDevice( const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
{
m_ArcBall.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
return S_OK;
}
//--------------------------------------------------------------------------------------
void CDXUTDirectionWidget::StaticOnD3D9LostDevice()
{
if( s_pD3D9Effect )
s_pD3D9Effect->OnLostDevice();
}
//--------------------------------------------------------------------------------------
void CDXUTDirectionWidget::StaticOnD3D9DestroyDevice()
{
SAFE_RELEASE(s_pD3D9Effect);
SAFE_RELEASE(s_pD3D9Mesh);
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDirectionWidget::StaticOnD3D10CreateDevice( ID3D10Device* pd3dDevice )
{
s_pd3d10Device = pd3dDevice;
const char* g_strBuffer =
"float4 g_MaterialDiffuseColor; // Material's diffuse color\r\n"
"float4 g_LightDir; // Light's direction in world space\r\n"
"float4x4 g_mWorld; // World matrix for object\r\n"
"float4x4 g_mWorldViewProjection; // World * View * Projection matrix\r\n"
"\r\n"
"struct VS_OUTPUT\r\n"
"{\r\n"
" float4 Position : SV_POSITION; // vertex position\r\n"
" float4 Diffuse : COLOR0; // vertex diffuse color\r\n"
"};\r\n"
"\r\n"
"VS_OUTPUT RenderWith1LightNoTextureVS( float3 vPos : POSITION,\r\n"
" float3 vNormal : NORMAL )\r\n"
"{\r\n"
" VS_OUTPUT Output;\r\n"
"\r\n"
" // Transform the position from object space to homogeneous projection space\r\n"
" Output.Position = mul( float4(vPos,1), g_mWorldViewProjection);\r\n"
"\r\n"
" // Transform the normal from object space to world space\r\n"
" float3 vNormalWorldSpace;\r\n"
" vNormalWorldSpace = normalize(mul(vNormal, (float3x3)g_mWorld)); // normal (world space)\r\n"
"\r\n"
" // Compute simple directional lighting equation\r\n"
" Output.Diffuse.rgb = g_MaterialDiffuseColor * max(0,dot(vNormalWorldSpace, g_LightDir));\r\n"
" Output.Diffuse.a = 1.0f;\r\n"
"\r\n"
" return Output;\r\n"
"}\r\n"
"\r\n"
"float4 RenderWith1LightNoTexturePS( VS_OUTPUT Input ) : SV_TARGET\r\n"
"{\r\n"
" return Input.Diffuse;\r\n"
"}\r\n"
"\r\n"
"technique10 RenderWith1LightNoTexture\r\n"
"{\r\n"
" pass p0\r\n"
" {\r\n"
" SetVertexShader( CompileShader( vs_4_0, RenderWith1LightNoTextureVS() ) );\r\n"
" SetGeometryShader( NULL );\r\n"
" SetPixelShader( CompileShader( ps_4_0, RenderWith1LightNoTexturePS() ) );\r\n"
" }\r\n"
"}\r\n"
"";
UINT dwBufferSize = (UINT)strlen(g_strBuffer) + 1;
HRESULT hr = D3DX10CreateEffectFromMemory( g_strBuffer, dwBufferSize, "None", NULL, NULL, "fx_4_0", D3D10_SHADER_ENABLE_STRICTNESS, 0, pd3dDevice, NULL, NULL, &s_pD3D10Effect, NULL, NULL );
if( FAILED(hr) )
return hr;
s_pRenderTech = s_pD3D10Effect->GetTechniqueByName( "RenderWith1LightNoTexture" );
g_pMaterialDiffuseColor = s_pD3D10Effect->GetVariableByName( "g_MaterialDiffuseColor" )->AsVector();
g_pLightDir = s_pD3D10Effect->GetVariableByName( "g_LightDir" )->AsVector();
g_pmWorld = s_pD3D10Effect->GetVariableByName( "g_mWorld" )->AsMatrix();
g_pmWorldViewProjection = s_pD3D10Effect->GetVariableByName( "g_mWorldViewProjection" )->AsMatrix();
const D3D10_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
D3D10_PASS_DESC PassDesc;
V_RETURN( s_pRenderTech->GetPassByIndex( 0 )->GetDesc( &PassDesc ) );
V_RETURN( pd3dDevice->CreateInputLayout( layout, 2, PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize, &s_pVertexLayout ) );
//TODO: Add loading code here
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDirectionWidget::OnRender10( D3DXCOLOR color, const D3DXMATRIX* pmView, const D3DXMATRIX* pmProj, const D3DXVECTOR3* pEyePt )
{
m_mView = *pmView;
// Render the light spheres so the user can visually see the light dir
D3DXMATRIX mRotate;
D3DXMATRIX mScale;
D3DXMATRIX mTrans;
D3DXMATRIXA16 mWorldViewProj;
g_pMaterialDiffuseColor->SetFloatVector( (float*)&color );
D3DXVECTOR3 vEyePt;
D3DXVec3Normalize( &vEyePt, pEyePt );
g_pLightDir->SetFloatVector( (float*)&vEyePt );
// Rotate arrow model to point towards origin
D3DXMATRIX mRotateA, mRotateB;
D3DXVECTOR3 vAt = D3DXVECTOR3(0,0,0);
D3DXVECTOR3 vUp = D3DXVECTOR3(0,1,0);
D3DXMatrixRotationX( &mRotateB, D3DX_PI );
D3DXMatrixLookAtLH( &mRotateA, &m_vCurrentDir, &vAt, &vUp );
D3DXMatrixInverse( &mRotateA, NULL, &mRotateA );
mRotate = mRotateB * mRotateA;
D3DXVECTOR3 vL = m_vCurrentDir * m_fRadius * 1.0f;
D3DXMatrixTranslation( &mTrans, vL.x, vL.y, vL.z );
D3DXMatrixScaling( &mScale, m_fRadius*0.2f, m_fRadius*0.2f, m_fRadius*0.2f );
D3DXMATRIX mWorld = mRotate * mScale * mTrans;
mWorldViewProj = mWorld * (m_mView) * (*pmProj);
g_pmWorldViewProjection->SetMatrix( (float*)&mWorldViewProj );
g_pmWorld->SetMatrix( (float*)&mWorld );
s_pd3d10Device->IASetInputLayout( s_pVertexLayout );
//TODO: Add rendering code here
return S_OK;
}
//--------------------------------------------------------------------------------------
void CDXUTDirectionWidget::StaticOnD3D10DestroyDevice()
{
SAFE_RELEASE(s_pVertexLayout);
SAFE_RELEASE(s_pD3D10Effect);
}
//--------------------------------------------------------------------------------------
LRESULT CDXUTDirectionWidget::HandleMessages( HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam )
{
switch( uMsg )
{
case WM_LBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
{
if( ((m_nRotateMask & MOUSE_LEFT_BUTTON) != 0 && uMsg == WM_LBUTTONDOWN) ||
((m_nRotateMask & MOUSE_MIDDLE_BUTTON) != 0 && uMsg == WM_MBUTTONDOWN) ||
((m_nRotateMask & MOUSE_RIGHT_BUTTON) != 0 && uMsg == WM_RBUTTONDOWN) )
{
int iMouseX = (int)(short)LOWORD(lParam);
int iMouseY = (int)(short)HIWORD(lParam);
m_ArcBall.OnBegin( iMouseX, iMouseY );
SetCapture(hWnd);
}
return TRUE;
}
case WM_MOUSEMOVE:
{
if( m_ArcBall.IsBeingDragged() )
{
int iMouseX = (int)(short)LOWORD(lParam);
int iMouseY = (int)(short)HIWORD(lParam);
m_ArcBall.OnMove( iMouseX, iMouseY );
UpdateLightDir();
}
return TRUE;
}
case WM_LBUTTONUP:
case WM_MBUTTONUP:
case WM_RBUTTONUP:
{
if( ((m_nRotateMask & MOUSE_LEFT_BUTTON) != 0 && uMsg == WM_LBUTTONUP) ||
((m_nRotateMask & MOUSE_MIDDLE_BUTTON) != 0 && uMsg == WM_MBUTTONUP) ||
((m_nRotateMask & MOUSE_RIGHT_BUTTON) != 0 && uMsg == WM_RBUTTONUP) )
{
m_ArcBall.OnEnd();
ReleaseCapture();
}
UpdateLightDir();
return TRUE;
}
case WM_CAPTURECHANGED:
{
if( (HWND)lParam != hWnd )
{
if( (m_nRotateMask & MOUSE_LEFT_BUTTON) ||
(m_nRotateMask & MOUSE_MIDDLE_BUTTON) ||
(m_nRotateMask & MOUSE_RIGHT_BUTTON) )
{
m_ArcBall.OnEnd();
ReleaseCapture();
}
}
return TRUE;
}
}
return 0;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDirectionWidget::OnRender9( D3DXCOLOR color, const D3DXMATRIX* pmView,
const D3DXMATRIX* pmProj, const D3DXVECTOR3* pEyePt )
{
m_mView = *pmView;
// Render the light spheres so the user can visually see the light dir
UINT iPass, cPasses;
D3DXMATRIX mRotate;
D3DXMATRIX mScale;
D3DXMATRIX mTrans;
D3DXMATRIXA16 mWorldViewProj;
HRESULT hr;
V( s_pD3D9Effect->SetTechnique( "RenderWith1LightNoTexture" ) );
V( s_pD3D9Effect->SetVector( "g_MaterialDiffuseColor", (D3DXVECTOR4*)&color ) );
D3DXVECTOR3 vEyePt;
D3DXVec3Normalize( &vEyePt, pEyePt );
V( s_pD3D9Effect->SetValue( "g_LightDir", &vEyePt, sizeof(D3DXVECTOR3) ) );
// Rotate arrow model to point towards origin
D3DXMATRIX mRotateA, mRotateB;
D3DXVECTOR3 vAt = D3DXVECTOR3(0,0,0);
D3DXVECTOR3 vUp = D3DXVECTOR3(0,1,0);
D3DXMatrixRotationX( &mRotateB, D3DX_PI );
D3DXMatrixLookAtLH( &mRotateA, &m_vCurrentDir, &vAt, &vUp );
D3DXMatrixInverse( &mRotateA, NULL, &mRotateA );
mRotate = mRotateB * mRotateA;
D3DXVECTOR3 vL = m_vCurrentDir * m_fRadius * 1.0f;
D3DXMatrixTranslation( &mTrans, vL.x, vL.y, vL.z );
D3DXMatrixScaling( &mScale, m_fRadius*0.2f, m_fRadius*0.2f, m_fRadius*0.2f );
D3DXMATRIX mWorld = mRotate * mScale * mTrans;
mWorldViewProj = mWorld * (m_mView) * (*pmProj);
V( s_pD3D9Effect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProj ) );
V( s_pD3D9Effect->SetMatrix( "g_mWorld", &mWorld ) );
for( int iSubset=0; iSubset<2; iSubset++ )
{
V( s_pD3D9Effect->Begin(&cPasses, 0) );
for (iPass = 0; iPass < cPasses; iPass++)
{
V( s_pD3D9Effect->BeginPass(iPass) );
V( s_pD3D9Mesh->DrawSubset(iSubset) );
V( s_pD3D9Effect->EndPass() );
}
V( s_pD3D9Effect->End() );
}
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTDirectionWidget::UpdateLightDir()
{
D3DXMATRIX mInvView;
D3DXMatrixInverse(&mInvView, NULL, &m_mView);
mInvView._41 = mInvView._42 = mInvView._43 = 0;
D3DXMATRIX mLastRotInv;
D3DXMatrixInverse(&mLastRotInv, NULL, &m_mRotSnapshot);
D3DXMATRIX mRot = *m_ArcBall.GetRotationMatrix();
m_mRotSnapshot = mRot;
// Accumulate the delta of the arcball's rotation in view space.
// Note that per-frame delta rotations could be problematic over long periods of time.
m_mRot *= m_mView * mLastRotInv * mRot * mInvView;
// Since we're accumulating delta rotations, we need to orthonormalize
// the matrix to prevent eventual matrix skew
D3DXVECTOR3* pXBasis = (D3DXVECTOR3*) &m_mRot._11;
D3DXVECTOR3* pYBasis = (D3DXVECTOR3*) &m_mRot._21;
D3DXVECTOR3* pZBasis = (D3DXVECTOR3*) &m_mRot._31;
D3DXVec3Normalize( pXBasis, pXBasis );
D3DXVec3Cross( pYBasis, pZBasis, pXBasis );
D3DXVec3Normalize( pYBasis, pYBasis );
D3DXVec3Cross( pZBasis, pXBasis, pYBasis );
// Transform the default direction vector by the light's rotation matrix
D3DXVec3TransformNormal( &m_vCurrentDir, &m_vDefaultDir, &m_mRot );
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -