📄 shader_dot3_directional.cpp
字号:
D3DXMATRIX matProj = m_pNVDevice->GetProjectionTransform();
D3DXMATRIX matView = m_pNVDevice->GetViewTransform();
D3DXMatrixMultiply(&matTemp, &matWorld, &matView);
D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProj);
D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
D3DXMatrixInverse(&matWorldInverse, NULL, &matWorld);
// Create a 3x3 invertse of the worldview for the normal transformation (we transpose it as we load it into
// the constant store)
D3DXMatrixInverse(&matWorldViewIT, NULL, &matWorldView);
// Projection to clip space
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
// Transform to eye space
D3DXMatrixTranspose(&matWorldView, &matWorldView);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4);
D3DXMatrixTranspose(&matWorldView, &matWorldView);
// Transform to world space
D3DXMatrixTranspose(&matWorld, &matWorld);
m_pD3DDev->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 4);
D3DXMatrixTranspose(&matWorld, &matWorld);
// Transform for normals
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matWorldViewIT(0, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_1, &matWorldViewIT(1, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_2, &matWorldViewIT(2, 0), 1);
return S_OK;
}
// Draw the actual light so we can see where it's pointing.
HRESULT CShaderDot3Directional::DrawDirectionalLightObject(D3DXVECTOR3 vecLightDirection)
{
D3DXMATRIX matWorld;
D3DXMATRIX matTemp;
D3DXVECTOR3 vecNormalizedDirection;
const NVBounds* pBounds = m_pLightMesh->GetBounds();
D3DXMatrixIdentity(&matWorld);
// Translate to the middle
D3DXMatrixTranslation(&matTemp, -pBounds->m_vecCenter.x, -pBounds->m_vecCenter.y, -pBounds->m_vecCenter.z);
D3DXMatrixMultiply(&matWorld, &matWorld, &matTemp);
float fLightScale = 0.1f;
D3DXMatrixScaling(&matTemp, fLightScale / pBounds->m_fRadius, fLightScale / pBounds->m_fRadius, fLightScale / pBounds->m_fRadius);
D3DXMatrixMultiply(&matWorld, &matWorld, &matTemp);
// Orientation of the light object (the arrow)
D3DXVECTOR3 vLightObject = D3DXVECTOR3(0.0f, -1.0f, 0.0f);
D3DXVec3Normalize(&vecNormalizedDirection, &vecLightDirection);
// Create the rotation axis
D3DXVECTOR3 vOrthoNormal;
D3DXVec3Cross(&vOrthoNormal, &vecNormalizedDirection, &vLightObject);
D3DXVec3Normalize(&vOrthoNormal, &vOrthoNormal);
// Calculate the angle between the two vectors.
float fAngle = acos(D3DXVec3Dot(&vecNormalizedDirection, &vLightObject));
// Rotate the object about our rotation axis to map one vector onto another
D3DXMatrixRotationAxis(&matTemp, &vOrthoNormal, -fAngle);
D3DXMatrixMultiply(&matWorld, &matWorld, &matTemp);
D3DXMATRIX matTranslate = m_pUI->GetTranslationMatrix();
// vecLightDirection is a direction vector, pointing at the origin, so we negate it to find the position
D3DXMatrixTranslation(&matTemp, -vecLightDirection.x + matTranslate._41, -vecLightDirection.y + matTranslate._42, -vecLightDirection.z + matTranslate._43);
D3DXMatrixMultiply(&matWorld, &matWorld, &matTemp);
D3DXVECTOR3 LightColor(1.0f, 1.0f, 1.0f);
m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_COLOR, &LightColor.x, 1);
m_pNVDevice->SetWorldTransform(&matWorld);
SetTransform();
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pLightMesh->Render(m_pNVDevice);
return S_OK;
}
HRESULT CShaderDot3Directional::Tick(EBTimer* pTimer)
{
HRESULT hr = S_OK;
//////////////////////
assert( m_pCA_Water != NULL );
m_pCA_Water->Tick();
//////////////////////
// Point at the vertex data
hr = m_pD3DDev->SetStreamSource(0, m_pSphereVertexBuffer, sizeof(Dot3Vertex));
if (FAILED(hr))
{
m_strLastError = "Could not set VB source";
return hr;
}
// Point at the index data
hr = m_pD3DDev->SetIndices(m_pSphereIndexBuffer, 0);
if (FAILED(hr))
{
m_strLastError = "Could not set Index source";
return hr;
}
//////////////////////
D3DXMATRIX matWorld;
D3DXMATRIX matView = m_pNVDevice->GetViewTransform();
D3DXMATRIX matTemp;
// Clear to grey
// hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0xAA, 0xAA, 0xAA ), 1.0, 0);
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, m_bWireframe ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
// Increase rotation
if (!m_bPause)
{
m_fAngle = timeGetTime() * ((float)0.01f);
}
D3DXMatrixMultiply( &matWorld, &m_pUI->GetRotationMatrix(), &m_pUI->GetTranslationMatrix() );
// Load transform data.
m_pNVDevice->SetWorldTransform(&matWorld);
SetTransform();
// Create the light direction vector.
D3DXVECTOR3 vecLightDirection;
float fLightDistance = 1.1f;
vecLightDirection.x = fLightDistance * cos( D3DXToRadian(m_fAngle));
vecLightDirection.z = fLightDistance * sin( D3DXToRadian(m_fAngle));
vecLightDirection.y = fLightDistance;
// Do the rendering
DrawDirectional(vecLightDirection);
// Draw the light shape
DrawDirectionalLightObject(vecLightDirection);
return hr;
}
HRESULT CShaderDot3Directional::DrawDirectional(D3DXVECTOR3 vecLightDirection)
{
D3DXMATRIX matWorld;
D3DXMATRIX matTemp;
D3DXVec3Normalize(&vecLightDirection, &vecLightDirection);
// shader math requires that the light direction vector points towards the light.
vecLightDirection = -vecLightDirection;
// Setup the vertex shader
m_pD3DDev->SetVertexShader(m_dwDot3Shader);
m_pD3DDev->SetPixelShader(0);
// Normal map in stage 0
// DotProduct 3 the normal map with the diffuse color set in the vertex
// shader (this will be the local light vector)
m_pD3DDev->SetTexture(0, m_pCA_Water->GetOutputTexture() );
m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
m_pD3DDev->SetRenderState( D3DRS_WRAP0, 0 );
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
// If you want a base texture, put it in stage 1 and MODULATE:
// Modulate the bump output from the previous stage by the current texture
// m_pD3DDev->SetTexture(1, m_pBaseTexture );
// m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1 );
// m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
// m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
// m_pD3DDev->SetRenderState( D3DRS_WRAP1, 0 );
// m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );
// MODULATE);
// Override the setup options if the user wants to display the components
switch(m_eDisplayOption)
{
default:
case DISPLAY_RESULT:
break;
case DISPLAY_BUMPMAP:
// Show the bump texture, disable the base texture pass
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
break;
case DISPLAY_LIGHTVECTOR:
// Show the diffuse color, output from the vshader which is the texture-space
// light vector
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
break;
case DISPLAY_BASETEXTURE:
break;
}
// Not using stage 2
m_pD3DDev->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
// Load the location of the light into the vertex shader.
m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_DIRECTION, (void*)&vecLightDirection.x, 1);
// Point at the vertex data
m_pD3DDev->SetStreamSource(0, m_pSphereVertexBuffer, sizeof(Dot3Vertex));
// Point at the index data
m_pD3DDev->SetIndices(m_pSphereIndexBuffer, 0);
// Backface cull the sphere
m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
// Draw the sphere
m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumFaces);
return S_OK;
}
HRESULT CShaderDot3Directional::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
if (!(pCaps->MaxSimultaneousTextures >= 2))
{
m_strLastError = "Device cannot dual texture!";
return E_FAIL;
}
if (!(pCaps->TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3))
{
m_strLastError = "Device cannot handle dotproduct3 operation!";
return E_FAIL;
}
return S_OK;
}
void CShaderDot3Directional::MouseButton(HWND hWnd, eButtonID button, bool bDown, int x, int y)
{
if(button == MOUSE_LEFTBUTTON)
{
if(bDown)
{
m_pUI->OnLButtonDown(x, y);
}
else
{
m_pUI->OnLButtonUp(x, y);
}
}
return;
}
void CShaderDot3Directional::MouseMove(HWND hWnd, int x, int y)
{
m_pUI->OnMouseMove(x, y);
return;
}
void CShaderDot3Directional::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
eEBKeyAction Action = TranslateEffectKey(dwKey, nFlags, bDown);
/////////////////
bool res;
res = m_pCA_Water->Keyboard( dwKey, nFlags, bDown );
if( res == true )
return;
/////////////////
EBString msg;
switch ( Action )
{
case EB_HELP:
{
msg = "H or F1 for Help\n";
msg += "\n";
msg += "*** This demo is framerate limited. ***\n";
msg += " Hit 'S' to run as fast as possible!\n";
msg += "\n";
msg += "L : Toggle logo in water\n";
msg += "\n";
msg += "NUMPAD7 : Reset to initial conditions\n";
msg += "\n";
msg += "1 : Display normal map\n";
msg += "2 : Display velocity map\n";
msg += "3 : Display prev pos,pos,v,n maps\n";
msg += "\n";
msg += "W : Wireframe\n";
msg += "\n";
msg += "G : Start/stop procedural animation \n";
msg += "S : Toggle animation rate limiting\n";
msg += " L arrow : Run animation faster\n";
msg += " R arrow : Run animation slower\n";
msg += "\n";
msg += "B : Toggle texture border wrapping\n";
msg += "\n";
msg += "Up arrow : Increase droplet frequency\n";
msg += "Dwn arrow : Decrease droplet frequency\n";
msg += "\n";
msg += "Y : Decrease normal map red/green\n";
msg += "U : Increase normal map red/green\n";
msg += "\n";
msg += "C : Decrease height smoothing\n";
msg += "V : Increase height smoothing\n";
msg += "<, > : Dec/Inc velocity apply factor\n";
msg += "[, ] : Dec/Inc force apply factor\n";
msg += "Z,X : Dec/Inc equilibrium restore force\n";
msg += "\n";
msg += "\n";
MessageBoxEx( NULL, msg.c_str(), "Dynamic Reflection Map Help",
MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
}
break;
case EB_PAUSE:
{
m_bPause = !m_bPause;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_WIREFRAME:
{
m_bWireframe = !m_bWireframe;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_RESET:
{
m_pUI->Reset();
m_pUI->SetTranslationalSensitivityFactor( 0.25f );
m_bWireframe = false;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_NORMALMAP:
{
if (m_eDisplayOption != DISPLAY_BUMPMAP)
m_eDisplayOption = DISPLAY_BUMPMAP;
else
m_eDisplayOption = DISPLAY_RESULT;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
default :
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -