⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shader_shadows.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
HRESULT CShaderShadows::Tick(EBTimer* pTimer)
{
	HRESULT hr = S_OK;
	D3DXMATRIX matWorld;
	D3DXMATRIX matView;

	m_pD3DDev->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL  );

    float const kSpeed = .25f;
	float const fKickFreq = kSpeed * pTimer->GetDuration(); 
	float const fPhase    = kSpeed * pTimer->GetDuration() / 3.0f;

    // Move the object in a circle
    D3DXMATRIX      matScale, matTrans1, matRotate1, matRotate2;
    D3DXMATRIX      matBank,  matLocalRotate;

    D3DXMatrixRotationY(   &matLocalRotate, D3DX_PI/2.0f);
    D3DXMatrixRotationX(   &matBank,        D3DX_PI/8.0f);
    D3DXMatrixRotationZ(   &matRotate1, 2*D3DX_PI); 
    D3DXMatrixRotationY(   &matRotate2, fPhase );
    D3DXMatrixScaling(     &matScale, 1.0f, 1.0f, 1.0f );
    D3DXMatrixTranslation( &matTrans1, -12*sinf(fPhase) , sinf(fKickFreq) + 4, 10-30*cosf(fPhase) );

	D3DXMatrixIdentity(&matWorld);
    D3DXMatrixMultiply( &matWorld, &matTrans1,      &matWorld);
	D3DXMatrixMultiply( &matWorld, &matScale,       &matWorld);
	D3DXMatrixMultiply( &matWorld, &matRotate2,     &matWorld);
	D3DXMatrixMultiply( &matWorld, &matRotate1,     &matWorld);	
    D3DXMatrixMultiply( &matWorld, &matBank,        &matWorld);
    D3DXMatrixMultiply( &matWorld, &matLocalRotate, &matWorld);

    m_pD3DDev->SetRenderState(D3DRS_FILLMODE, (mbWireFrame) ? D3DFILL_WIREFRAME : D3DFILL_SOLID);

    if (m_bPause)
        return hr;

	m_Models[ 0 ].mModelMatrix = matWorld;

	CreateShadowMap();

    // Camera setup
	D3DXVECTOR3 const vEyePt    = D3DXVECTOR3( 5.0f,  5.0f, 0.0f);
	D3DXVECTOR3 const vLookatPt = D3DXVECTOR3( 0.0f,  0.0f, 0.0f);
	D3DXVECTOR3 const vUp       = D3DXVECTOR3( 0.0f,  0.0f, 1.0f );

	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
	m_pNVDevice->SetViewTransform(&matView);

	hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, BACKGROUND_COLOR, 1.0, 0);

    // Projection set up
    D3DXMATRIX        matProj;
	D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
	m_pNVDevice->SetProjectionTransform(&matProj);

	D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );

	DrawSeaFloor();
	DrawObjects();

	m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT );
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_NONE );

	m_pD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT );
    m_pD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_NONE );

	unsigned int theObjectID = 0x00;
	D3DXVECTOR4 vColorCurrent( (float)( theObjectID ) / 255.0f, 0.0f, 0.0f, 0.0f );
	m_pD3DDev->SetVertexShaderConstant( CV_CURR_OBJECTID_IN_TEXELS, &vColorCurrent,  1 );

	m_pFloorMesh->SetVertexShader( m_dwDrawObjectShader );
	m_pFloorMesh->SetVertexShader( m_dwShadowShowShader );


	// Set tfactor to r = 1, g = 1, b = 1, a = 0
	m_pD3DDev->SetRenderState( D3DRS_TEXTUREFACTOR, 0x00ffffff );

	// Compare by doing ShadowGen - ShadowMap
	//
	//  Shadow Gen should always be >= ShadowMap
	//

	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );

	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT );
    m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SUBTRACT );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE );

	m_pD3DDev->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_CURRENT );
    m_pD3DDev->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3 );
	m_pD3DDev->SetTextureStageState(2, D3DTSS_COLORARG2, D3DTA_TFACTOR );

	m_pD3DDev->SetTextureStageState(2, D3DTSS_ALPHAARG1, D3DTA_CURRENT );
    m_pD3DDev->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
	m_pD3DDev->SetTextureStageState(2, D3DTSS_ALPHAARG2, D3DTA_TFACTOR );

    m_pD3DDev->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE );

	// Reject pixels that are in shadow
	m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
	m_pD3DDev->SetRenderState( D3DRS_ALPHAREF, 0x0 );
	m_pD3DDev->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_EQUAL  );

	m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	m_pD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
	m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );

	// Clamp outside of range 0..1
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );

	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );

	D3DXMATRIX tempMatrix, modelToLightMatrix;

	{
		D3DXMATRIX matView = CreateLightMatrix( 0 ); 

		// TODO: Handle case where sphere overlaps that light plane, just clamp the range...?
		D3DXMATRIX matModel;
		D3DXMatrixIdentity( &matModel );

		D3DXMatrixMultiply( &modelToLightMatrix, &matModel, &matView);

		D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &matProj );

		D3DXMATRIX temp2( 1.0f, 0.0f, 0.0f, 0.0f,
						  0.0f, 1.0f, 0.0f, 0.0f,
						  0.0f, 0.0f, 1.0f, 0.5f, 
						  0.0f, 0.0f, 0.0f, 0.5f );

		D3DXMatrixMultiply( &tempMatrix, &tempMatrix, &temp2 );

		m_pObjectMesh->SetVertexShader( m_dwShadowShowShader );
		m_pObjectMesh->SetTexture( m_pShadowGen);

		D3DXMatrixTranspose( &tempMatrix, &tempMatrix );
		m_pD3DDev->SetVertexShaderConstant( CV_CURR_WORLD2LIGHT_TXF_0, &tempMatrix,  4 );

		//   Set up projection matrix for rendering
		D3DXMATRIX matProj;
		D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
		m_pNVDevice->SetProjectionTransform(&matProj);

		D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );
		D3DXMatrixMultiply( &matView, &matView, &matProj);

		D3DXMatrixTranspose( &matView, &matView );
		m_pD3DDev->SetVertexShaderConstant( CV_MVP_TXF_0, &matView,  4 );
		D3DXMatrixTranspose( &matView, &matView);

		m_pD3DDev->SetTexture(0, m_pShadowGen);
		m_pD3DDev->SetTexture(1, m_pShadowMap);

//		m_pFloorMesh->Render(m_pNVDevice);
	}
	
	for ( unsigned int i = 0; i < m_Models.size(); ++i )
	{
		D3DXMATRIX matTemp;

		// Projection set up
		D3DXMATRIX        matProj;
		D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(90.0f), 1.0f, 1.0f, 1000.0f);
		m_pNVDevice->SetProjectionTransform(&matProj);

		D3DXMatrixMultiply( &matView, &m_pMouseUI->GetRotationMatrix(), &m_pMouseUI->GetTranslationMatrix() );
		D3DXMatrixMultiply( &matTemp, &m_Models[ i ].mModelMatrix, &matView );
		D3DXMatrixMultiply( &matTemp, &matTemp, &matProj);

		D3DXMatrixTranspose( &matTemp, &matTemp);
		m_pD3DDev->SetVertexShaderConstant( CV_MVP_TXF_0, &matTemp,  4 );

		m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
		m_pD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
		m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );

		unsigned int theObjectID = 1 + i;
		D3DXVECTOR4 vColorCurrent( (float)( theObjectID ) / 255.0f, 0.0f, 0.0f, 0.0f );
		m_pD3DDev->SetVertexShaderConstant( CV_CURR_OBJECTID_IN_TEXELS, &vColorCurrent,  1 );

		D3DXMATRIX matModel = m_Models[ i ].mModelMatrix;

		matView = CreateLightMatrix( 0 );

		D3DXMatrixMultiply( &modelToLightMatrix, &matModel, &matView);

		//D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &matProj );

		// off set to texture coordinates
		D3DXMATRIX temp2( 1.0f, 0.0f, 0.0f, 0.0f,
						  0.0f, 1.0f, 0.0f, 0.0f,
						  0.0f, 0.0f, 1.0f, 0.5f, 
						  0.0f, 0.0f, 0.0f, 0.5f );

		D3DXMatrixMultiply( &tempMatrix, &modelToLightMatrix, &temp2 );

		D3DXMatrixTranspose( &tempMatrix, &tempMatrix );
		m_pD3DDev->SetVertexShaderConstant( CV_CURR_WORLD2LIGHT_TXF_0, &tempMatrix,  4 );

		m_Models[ i ].m_pNVMesh->SetTexture(m_pShadowGen);

		m_pD3DDev->SetTexture(1, m_pShadowMap);

		m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_SELECTARG2 );
		m_pD3DDev->SetTextureStageState( 2, D3DTSS_COLOROP,   D3DTOP_DISABLE );

	    m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );

		m_pD3DDev->SetVertexShader(0);
		m_Models[ i ].m_pNVMesh->SetVertexShader(m_dwShadowShowShader);
		m_Models[ i ].m_pNVMesh->Render(m_pNVDevice);
	}

	m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );

	if ( m_bShowShadowMap )
	{
		m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
		m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
		m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT );

		m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT );
		m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE );

	    m_pD3DDev->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
	    m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );

		m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
		m_pD3DDev->SetStreamSource(0, m_pShowShadowMapVB, sizeof(TLVertex));
		m_pD3DDev->SetVertexShader(TLVertex::FVF );
		m_pD3DDev->SetTexture(0, m_pShadowMap);
		m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 );

		// Restore render states
		m_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
	}

	return hr;
}

HRESULT CShaderShadows::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
    // check vertex shading support

    // check simultaneous texture support (only need 2...)
    if(pCaps->MaxSimultaneousTextures < 2)
	{
		m_strLastError = "Device does not support 4 simultaneous textures!";
		return E_FAIL;
	}

    // only need very few, simple register combiners...
	if(pCaps->MaxTextureBlendStages < 2)
	{
		m_strLastError = "Device does not support 2 register combiners!";
		return E_FAIL;
	}

	return S_OK;
}

void CShaderShadows::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 Pause/Space - Toggle pausing the animation \n\n +/- - Lengthen/Shorten Blur Length",
				   "Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
		}
		break;

		case EB_WIREFRAME:
        {
            mbWireFrame = !mbWireFrame;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
        }
		break;

        case EB_PAUSE:
        {
            m_bPause = !m_bPause;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
        }
        break;

		break;

        case EB_RESET :
        {
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
            m_pMouseUI->Reset();
            break;
        }

        case VK_LEFT :
        {
            m_pMouseUI->Translate( -1.0f, 0.0f, 0.0f );
            break;
        }

        case VK_RIGHT :
        {
            m_pMouseUI->Translate(  1.0f, 0.0f, 0.0f );
            break;
        }

        case VK_UP :
        {
            m_pMouseUI->Translate(  0.0f, 0.0f, -1.0f );
            break;
        }

        case VK_DOWN :
        {
            m_pMouseUI->Translate( 0.0f, 0.0f, 1.0f );
            break;
        }

        case EB_PAGEUP :
        {
            m_pMouseUI->Translate(  0.0f, 1.0f, 0.0f );
            break;
        }
        case EB_PAGEDOWN :
        {
            m_pMouseUI->Translate(  0.0f, -1.0f, 0.0f );
            break;
        }

        case EB_ADD :
        {
            m_pMouseUI->Translate( 0.0f, 0.0f, 1.0f );
            break;
        }
        case EB_SUBTRACT :
        {
            m_pMouseUI->Translate( 0.0f, 0.0f, -1.0f );
            break;
        }

        default:
            break;
    }
}


void CShaderShadows::MouseButton(HWND hWnd, eButtonID button, bool bDown, int x, int y)
{
	if(button == MOUSE_LEFTBUTTON)
	{
		if(bDown)
		{
			m_pMouseUI->OnLButtonDown(x, y);
		}
		else
		{
			m_pMouseUI->OnLButtonUp(x, y);
		}
	}
	return;
}

void CShaderShadows::MouseMove(HWND hWnd, int x, int y)
{
	m_pMouseUI->OnMouseMove(x, y);
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -