📄 effect_reflectivebumpdynamic.cpp
字号:
m_pD3DDev->SetVertexShaderConstant(CV_BASISTRANSFORM_2, &matBasisTransform(2, 0), 1);
D3DXMatrixTranspose(&matBasisTransform, &matBasisTransform);
return S_OK;
}
HRESULT NVEffect_DynamicReflection::Tick(EBTimer* pTimer)
{
HRESULT hr = S_OK;
if( m_bShowProceduralMaps )
{
m_pCA_Water->m_bDrawOutput = true;
}
else
{
m_pCA_Water->m_bDrawOutput = false;
// Clear to grey
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,
D3DCOLOR_XRGB( 0xAA, 0xAA, 0xAA ), 1.0, 0);
ASSERT_IF_FAILED(hr);
}
//////////////////////////////////////////
// Update dynamic normal map
assert( m_pCA_Water != NULL );
// Tick also draws the maps in background if m_bDrawOutput is on
hr = m_pCA_Water->Tick();
ASSERT_IF_FAILED(hr);
////////////////////////////////////////////////////
// Restore render state because it may have been polluted
// by water animation
RestoreRenderState();
if( m_bShowProceduralMaps )
{
// Clear z buffer if background map was drawn
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL,
D3DCOLOR_XRGB( 0xAA, 0xAA, 0xAA ), 1.0, 0);
ASSERT_IF_FAILED(hr);
}
D3DXMATRIX matWorld;
D3DXMATRIX matView = m_pNVDevice->GetViewTransform();
D3DXMATRIX matTemp;
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 NVEffect_DynamicReflection::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)
{
assert( m_pCA_Water != NULL );
IDirect3DTexture8 * pTex = m_pCA_Water->GetOutputTexture();
assert( pTex != NULL );
m_pD3DDev->SetTexture( 0, m_pCA_Water->GetOutputTexture() );
}
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] = 8.0f;
numSegs[1] = 8.0f;
numSegs[2] = 8.0f;
numSegs[3] = 8.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...
// Calculate SxT in the vertex shader
m_pD3DDev->SetVertexShaderConstant( CV_CALC_SXT, D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 0.0f), 1 );
m_pD3DDev->DrawRectPatch(1, numSegs, &info);
}
else
{
// Draw the sphere
// Don't calculate SxT in the vertex shader
m_pD3DDev->SetVertexShaderConstant( CV_CALC_SXT, D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 0.0f), 1 );
m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumFaces);
}
return S_OK;
}
void NVEffect_DynamicReflection::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);
}
}
if( button == MOUSE_LEFTBUTTON && m_bDrawModeOn == true )
{
if(bDown)
{
m_bDrawing = true;
}
else
{
// Draw the last point clicked as the mouse button
// comes up.
TryDrawDroplet( x,y );
m_bDrawing = false;
}
}
return;
}
void NVEffect_DynamicReflection::TryDrawDroplet( float x, float y )
{
// Adds droplet to the queue for later rendering
float fx,fy;
RECT winr;
float scale;
if( m_pUI->IsInWindow( x,y ))
{
winr = m_pUI->GetRECT();
fx = 1.0f - ((float)x - (float)winr.left)/((float)winr.right - winr.left);
fy = ((float)y - (float)winr.top)/((float)winr.bottom - winr.top);
scale = 14.0f;
m_pCA_Water->AddDroplet( fx, fy, scale );
}
}
void NVEffect_DynamicReflection::RestoreRenderState()
{
// call to reset render modes to those appropriate for
// rendering the reflective surface
int i;
for( i=0; i < 4; i++ )
{
m_pD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_POINT ); // nearest level
}
m_pD3DDev->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
m_pD3DDev->SetRenderState( D3DRS_ZWRITEENABLE, true );
}
void NVEffect_DynamicReflection::MouseMove(HWND hWnd, int x, int y)
{
if( m_bDrawing && m_bDrawModeOn )
{
if( m_pCA_Water != NULL )
{
TryDrawDroplet( x,y );
}
}
else if( m_pUI != NULL )
{
m_pUI->OnMouseMove(x, y);
}
return;
}
void NVEffect_DynamicReflection::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
assert( m_pCA_Water != NULL );
bool result;
result = m_pCA_Water->Keyboard( dwKey, nFlags, bDown );
if( result == true )
{
return; // no more keyboard processing!
}
if( !bDown )
{
switch( dwKey )
{
case VK_NUMPAD8:
m_pUI->Reset();
m_pUI->Translate( 0.0f, 0.0f, -0.25f );
m_pUI->OnLButtonDown( 50, 50 );
m_pUI->OnMouseMove( 67, 57 );
m_pUI->OnLButtonUp( 67, 57 );
m_pUI->SetTranslationalSensitivityFactor( 0.1f );
m_bWireframe = false;
m_pCA_Water->m_bWireframe = false;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
m_bShowProceduralMaps = false;
break;
case 'D':
m_bDrawModeOn = !m_bDrawModeOn;
FDebug("Set draw mode: %s\n", m_bDrawModeOn?"ON":"OFF");
break;
case '5':
m_bShowProceduralMaps = !m_bShowProceduralMaps;
break;
case 'P':
m_bPause = !m_bPause;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
break;
}
}
eEBKeyAction Action = TranslateEffectKey(dwKey, nFlags, bDown);
if( result == true && Action != EB_WIREFRAME )
{
return; // no more keyboard processing!
}
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 += "D : Toggle draw/move mode\n";
msg += "L : Toggle logo in water\n";
msg += "\n";
msg += "NUMPAD7 : Reset to initial conditions\n";
msg += "NUMPAD8 : Reset view\n";
msg += "\n";
msg += "5 : Display dynamic maps\n";
msg += " 1 : Display normal map\n";
msg += " 2 : Display velocity map\n";
msg += " 3 : Display initial,pos,v,n maps\n";
msg += "\n";
msg += "W : Wireframe\n";
msg += "+ : Increase bump height\n";
msg += "- : Decrease bump height\n";
msg += "\n";
msg += "SPACE : Start/stop procedural animation \n";
msg += "RETURN : Single step of 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 += "Up arrow : Increase droplet frequency\n";
msg += "Dwn arrow : Decrease droplet frequency\n";
msg += "\n";
msg += "M : Toggle normal map creation method\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 += "\n";
msg += "\n";
MessageBoxEx( NULL, msg.c_str(), "Dynamic Reflection Map 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:
{
// Reset mesh control points
m_ctrl1 = m_ctrl2 = m_ctrl3 = m_ctrl4 = 0.0f;
m_fBumpScale = INIT_BUMPSCALE;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
if( m_pCA_Water != NULL )
{
m_pCA_Water->m_bReset = true;
}
}
break;
case EB_PAUSE:
{
m_bPause = !m_bPause;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
break;
case EB_ADD:
{
m_fBumpScale += 0.01f;
if (m_fBumpScale > 2.0f)
m_fBumpScale = 2.0f;
}
break;
case EB_SUBTRACT:
{
m_fBumpScale -= 0.01f;
if (m_fBumpScale < 0.0f)
m_fBumpScale = 0.0f;
}
break;
default :
break;
}
}
void NVEffect_DynamicReflection::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);
}
else if (name == EBString(STR_MOREOPTION))
{
Keyboard(VK_F1, 0, true );
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -