📄 shader_blinnreflect.cpp
字号:
NULL,
NULL,
&m_pCubeTexture);
if (FAILED(hr))
{
m_strLastError = "Could not load texture (sky_cube_mipmap.dds)";
return hr;
}
// Setup constants
m_pD3DDev->SetVertexShaderConstant(CV_ZERO, D3DXVECTOR4(0.0f, 0.0f, 0.0f, 0.0f), 1);
m_pD3DDev->SetVertexShaderConstant(CV_ONE, D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f), 1);
// Camera stuff
D3DXMATRIX matProj;
D3DXMATRIX matView;
D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -1.0f );
D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
m_pD3DDev->SetVertexShaderConstant(CV_EYE_WORLD, D3DXVECTOR4(vEyePt.x, vEyePt.y, vEyePt.z, 0.0f), 1);
// View
D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
// Projection
D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(60.0f), 1.0f, 0.1f, 50.0f);
m_pNVDevice->SetViewTransform(&matView);
m_pNVDevice->SetProjectionTransform(&matProj);
m_pD3DDev->SetRenderState(D3DRS_SPECULARENABLE, FALSE);
if (m_pLightMesh)
m_pLightMesh->RestoreDeviceObjects(m_pNVDevice);
// Reset control points for mesh
m_ctrl1 = m_ctrl2 = m_ctrl3 = m_ctrl4 = 0.0f;
// Point at the vertex data
CreateBasisVectors(m_pVertexBuffer, m_pIndexBuffer);
// Point at the index data
hr = m_pD3DDev->SetIndices(m_pIndexBuffer, 0);
if (FAILED(hr))
{
m_strLastError = "Could not set Index source";
return hr;
}
return S_OK;
}
HRESULT CShaderBlinnReflect::Free()
{
SAFE_DELETE(m_pLightMesh);
SAFE_RELEASE(m_pPatchBuffer);
SAFE_RELEASE(m_pVertexBuffer);
SAFE_RELEASE(m_pIndexBuffer);
SAFE_RELEASE(m_pBumpMapQWVU);
SAFE_RELEASE(m_pBumpMapHILO);
SAFE_RELEASE(m_pGlossMap);
SAFE_RELEASE(m_pCubeTexture);
SAFE_DELETE(m_pUI);
SAFE_DELETE(m_pNVDevice);
if (m_pD3DDev)
{
if (m_dwBlinnPixelShader)
m_pD3DDev->DeletePixelShader(m_dwBlinnPixelShader);
if (m_dwBlinnVertexShader)
m_pD3DDev->DeleteVertexShader(m_dwBlinnVertexShader);
if (m_dwTransformShader)
m_pD3DDev->DeleteVertexShader(m_dwTransformShader);
if (m_dwBlinnPatchVertexShader)
m_pD3DDev->DeleteVertexShader(m_dwBlinnPatchVertexShader);
if (m_dwTransformPatchShader)
m_pD3DDev->DeleteVertexShader(m_dwTransformPatchShader);
m_dwBlinnPixelShader = 0;
m_dwBlinnVertexShader = 0;
m_dwTransformShader = 0;
m_dwBlinnPatchVertexShader = 0;
m_dwTransformPatchShader = 0;
SAFE_RELEASE(m_pD3DDev);
}
return S_OK;
}
HRESULT CShaderBlinnReflect::Start()
{
m_fAngle = 0.0f;
return S_OK;
}
HRESULT CShaderBlinnReflect::SetTransform()
{
D3DXMATRIX matTemp;
D3DXMATRIX matWorldViewProj;
D3DXMATRIX matWorldView;
D3DXMATRIX matWorldViewI;
D3DXMATRIX matWorldI;
D3DXMATRIX matWorld = m_pNVDevice->GetWorldTransform();
D3DXMATRIX matProj = m_pNVDevice->GetProjectionTransform();
D3DXMATRIX matView = m_pNVDevice->GetViewTransform();
D3DXMatrixMultiply(&matTemp, &matWorld, &matView);
D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProj);
D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
D3DXMatrixInverse(&matWorldI, 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(&matWorldViewI, NULL, &matWorldView);
// Projection to clip space
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
D3DXMatrixTranspose(&matWorld, &matWorld);
m_pD3DDev->SetVertexShaderConstant(CV_WORLD_0, &matWorld(0, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_WORLD_1, &matWorld(1, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_WORLD_2, &matWorld(2, 0), 1);
D3DXMatrixTranspose(&matWorld, &matWorld);
// If you are rotating the cubemap, you need to apply that transform here too
D3DXMATRIX matBasisTransform = matWorld;
D3DXMatrixTranspose(&matBasisTransform, &matBasisTransform);
m_pD3DDev->SetVertexShaderConstant(CV_BASISTRANSFORM_0, &matBasisTransform(0, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_BASISTRANSFORM_1, &matBasisTransform(1, 0), 1);
m_pD3DDev->SetVertexShaderConstant(CV_BASISTRANSFORM_2, &matBasisTransform(2, 0), 1);
D3DXMatrixTranspose(&matBasisTransform, &matBasisTransform);
return S_OK;
}
HRESULT CShaderBlinnReflect::Tick(EBTimer* pTimer)
{
HRESULT hr = S_OK;
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);
// Set the bump scale
m_pD3DDev->SetVertexShaderConstant(CV_BUMPSCALE, D3DXVECTOR4(0.0f, 0.0f, 0.0f, m_fBumpScale), 1);
AnimateSplinePatch(pTimer);
D3DXMatrixMultiply( &matWorld, &m_pUI->GetRotationMatrix(), &m_pUI->GetTranslationMatrix() );
// Load transform data.
m_pNVDevice->SetWorldTransform(&matWorld);
SetTransform();
DrawReflection();
return hr;
}
HRESULT CShaderBlinnReflect::DrawReflection()
{
D3DXMATRIX matWorld;
D3DXMATRIX matTemp;
m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
// General setup
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
m_pD3DDev->SetRenderState( D3DRS_WRAP0, D3DWRAP_U | D3DWRAP_V);
// Point at the vertex data
m_pD3DDev->SetStreamSource(0, m_bUsePatch ? m_pPatchBuffer : m_pVertexBuffer, sizeof(Dot3Vertex));
// Backface cull the sphere
m_pD3DDev->SetRenderState(D3DRS_CULLMODE, m_bUsePatch ? D3DCULL_NONE : D3DCULL_CCW);
// Point at the index data
m_pD3DDev->SetIndices(m_pIndexBuffer, 0);
m_pD3DDev->SetPixelShader(0);
if ((m_eDisplayOption == DISPLAY_BLINN8BITSIGNED) && (!m_bSupportsQWVU))
{
m_eDisplayOption = DISPLAY_BLINNHILOSIGNED;
}
if ((m_eDisplayOption == DISPLAY_BLINNHILOSIGNED) && (!m_bSupportsHILO))
{
m_eDisplayOption = DISPLAY_BLINN8BITSIGNED;
}
// 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)
if (m_eDisplayOption == DISPLAY_BLINN8BITSIGNED)
{
m_pD3DDev->SetTexture(0, m_pBumpMapQWVU);
}
else
{
m_pD3DDev->SetTexture(0, m_pBumpMapHILO);
}
m_pD3DDev->SetTexture(1, NULL);
m_pD3DDev->SetTexture(2, NULL);
m_pD3DDev->SetTexture(3, m_pCubeTexture);
// Setup the vertex shader
m_pD3DDev->SetVertexShader(m_bUsePatch ? m_dwBlinnPatchVertexShader : m_dwBlinnVertexShader);
m_pD3DDev->SetPixelShader(m_dwBlinnPixelShader);
float numSegs[4];
numSegs[0] = 20.0f;
numSegs[1] = 20.0f;
numSegs[2] = 20.0f;
numSegs[3] = 20.0f;
D3DRECTPATCH_INFO info;
info.StartVertexOffsetWidth = 0;
info.StartVertexOffsetHeight = 0;
info.Width = 4;
info.Height = 4;
info.Stride = 4; // verticies to next row of verticies
info.Basis = D3DBASIS_BEZIER;
info.Order = D3DORDER_CUBIC;
// Draw
if (m_bUsePatch)
{
// draw a single patch for now
// always tesselate from scratch...
m_pD3DDev->DrawRectPatch(1, numSegs, &info);
}
else
m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumFaces);
m_pD3DDev->SetVertexShader(m_bUsePatch ? m_dwTransformPatchShader : m_dwTransformShader);
m_pD3DDev->SetPixelShader(0);
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR);
m_pD3DDev->SetTexture(0, m_pGlossMap);
m_pD3DDev->SetTexture(3, NULL);
// Draw again
if (m_bUsePatch)
m_pD3DDev->DrawRectPatch(2, numSegs, &info);
else
m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumFaces);
return S_OK;
}
void CShaderBlinnReflect::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 CShaderBlinnReflect::MouseMove(HWND hWnd, int x, int y)
{
m_pUI->OnMouseMove(x, y);
return;
}
void CShaderBlinnReflect::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
eEBKeyAction Action = TranslateEffectKey(dwKey, nFlags, bDown);
switch ( Action )
{
case EB_HELP:
{
::MessageBoxEx( NULL, " Help : F1 - Help \n\n Home - Reset To Defaults \n\n W - Wireframe Toggle \n\n Space\\Pause - Toggle Pause/Resume \n\n Left Button & Mouse - Rotate Object\n\n Shift Left Button & Mouse - Pan Camera \n\n Ctrl Left Button & Mouse - Move Camera In & Out\n\n +\\- Change Bump Scale\n\n",
"Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
}
break;
case EB_WIREFRAME:
{
m_bWireframe = !m_bWireframe;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_RESET:
{
m_pUI->Reset();
m_bWireframe = false;
// Reset mesh control points
m_ctrl1 = m_ctrl2 = m_ctrl3 = m_ctrl4 = 0.0f;
m_fBumpScale = 0.2f;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_PAUSE:
{
m_bPause = !m_bPause;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_ADD:
{
m_fBumpScale += 0.02f;
if (m_fBumpScale > 1.0f)
m_fBumpScale = 1.0f;
}
break;
case EB_SUBTRACT:
{
m_fBumpScale -= 0.02f;
if (m_fBumpScale < 0.0f)
m_fBumpScale = 0.0f;
}
break;
default :
break;
}
}
void CShaderBlinnReflect::PropertyUpdateCallback(const EBProperty* pProperty, bool bWritten)
{
if (!bWritten)
return;
EBString name;
if (pProperty->IsKindOf(EBTYPE_TRIGGER_PROP))
{
name = pProperty->GetPropertyName();
if(name == EBString(STR_INCREASEBUMPSCALE))
{
Keyboard(VK_ADD, 0, true);
}
else if (name == EBString(STR_DECREASEBUMPSCALE))
{
Keyboard(VK_SUBTRACT, 0, true);
}
else if (name == EBString(STR_RESETPATCH))
{
Keyboard(VK_HOME, 0, true);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -