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

📄 shader_morph.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	// Camera setup
	D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f);
	D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );

	// View
	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);

	// Projection
	D3DXMatrixPerspectiveFovLH(&matProj, D3DXToRadian(60.0f), 1.0f, 1.0f, 1000.0f);

	m_pNVDevice->SetViewTransform(&matView);
	m_pNVDevice->SetProjectionTransform(&matProj);
	return S_OK;

}

HRESULT CShaderMorph::Free()
{
	SAFE_RELEASE(m_pDolphinMap);

	SAFE_RELEASE(m_pDolphinIB);
	SAFE_RELEASE(m_pDolphinVB[0]);
	SAFE_RELEASE(m_pDolphinVB[1]);
	SAFE_RELEASE(m_pDolphinVB[2]);

	while(!m_vecCausticTextures.empty())
	{
		LPDIRECT3DTEXTURE8 pTexture = m_vecCausticTextures.back();
		SAFE_RELEASE(pTexture);
		m_vecCausticTextures.pop_back();
	}

	SAFE_DELETE(m_pFloorMesh);

	SAFE_DELETE(m_pNVDevice);

	if (m_pD3DDev)
	{
		m_pD3DDev->DeleteVertexShader(m_dwDolphinShader);
		m_pD3DDev->DeleteVertexShader(m_dwSeaFloorShader);
		SAFE_RELEASE(m_pD3DDev);
	}

	return S_OK;
}

HRESULT CShaderMorph::Start()
{
	return S_OK;
}

HRESULT CShaderMorph::SetTransform()
{
	D3DXMATRIX matWorld, matView, matProj;
	D3DXMATRIX matWorldView;
	D3DXMATRIX matWorldViewIT;
	D3DXMATRIX matWorldViewProj;

	matWorld = m_pNVDevice->GetWorldTransform();
	matView = m_pNVDevice->GetViewTransform();
	matProj = m_pNVDevice->GetProjectionTransform();

	D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
	D3DXMatrixMultiply(&matWorldViewProj, &matWorldView, &matProj);
	D3DXMatrixInverse(&matWorldViewIT, NULL, &matWorldView);
	
	// Projection to clip space
	D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
	D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);

	D3DXMatrixTranspose(&matWorldView, &matWorldView);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4);
	D3DXMatrixTranspose(&matWorldView, &matWorldView);

	// Worldview transform
	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;
}


HRESULT CShaderMorph::Tick(EBTimer* pTimer)
{
	HRESULT hr = S_OK;
	D3DXMATRIX matWorld;
	D3DXMATRIX matView;
	D3DXMATRIX matTemp;

	if (m_bPause)
		return S_OK;

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

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

	float fKickFreq = pTimer->GetDuration() * 2.0f;
	float fPhase = pTimer->GetDuration() / 3.0f;

	// Select the second frame to lerp with, based on the time.
	// We have 3 meshes - the middle and the top for the up phase, the 
	// middle and the bottom for the down phase
	float fSinTheta = sin(fKickFreq);
	if (fSinTheta < 0.0f)
	{
		fSinTheta = -fSinTheta;

		hr = m_pD3DDev->SetStreamSource(1, m_pDolphinVB[0], sizeof(DolphinVertex));
		if (FAILED(hr))
			return hr;
	}
	else
	{
		hr = m_pD3DDev->SetStreamSource(1, m_pDolphinVB[2], sizeof(DolphinVertex));
		if (FAILED(hr))
			return hr;
	}
	m_pD3DDev->SetStreamSource(0, m_pDolphinVB[1], sizeof(DolphinVertex));
	m_pD3DDev->SetIndices(m_pDolphinIB, 0);
	m_pD3DDev->SetVertexShader(m_dwDolphinShader);

	// Put the weights in the vertex shader
	m_pD3DDev->SetVertexShaderConstant(CV_WEIGHT, D3DXVECTOR4(1.0f - fSinTheta, fSinTheta, 0.0f, 0.0f), 1);

    // Move the dolphin in a circle
    D3DXMATRIX matScale, matTrans1, matRotate1, matRotate2;
    D3DXMatrixRotationZ( &matRotate1, -cosf(fKickFreq)/6 );
    D3DXMatrixRotationY( &matRotate2, fPhase );
    D3DXMatrixScaling(  &matScale, 0.01f, 0.01f, 0.01f );
    D3DXMatrixTranslation( &matTrans1, -5*sinf(fPhase), sinf(fKickFreq)/2, 10-10*cosf(fPhase) );

	D3DXMatrixIdentity(&matWorld);
    D3DXMatrixMultiply( &matWorld, &matTrans1, &matWorld);
	D3DXMatrixMultiply( &matWorld, &matScale, &matWorld);
	D3DXMatrixMultiply( &matWorld, &matRotate2, &matWorld);
	D3DXMatrixMultiply( &matWorld, &matRotate1, &matWorld);	
    
	m_pNVDevice->SetWorldTransform(&matWorld);
	SetTransform();

	// Create a directional light
	D3DXVECTOR3 vLightToEye;
	D3DXVECTOR3 vLight(0.0f, -1.0f, 0.0f);
	D3DXVECTOR4 vLightEye;

	// Transform direction vector into eye space
	matView = m_pNVDevice->GetViewTransform();
	D3DXVec3Normalize(&vLightToEye, &vLight);
	D3DXVec3TransformNormal(&vLightToEye, &vLightToEye, &matView);
	D3DXVec3Normalize(&vLightToEye, &vLightToEye);

	// Shader math requires that the vector is to the light
	vLightEye.x = -vLightToEye.x;
	vLightEye.y = -vLightToEye.y;
	vLightEye.z = -vLightToEye.z;
	vLightEye.w = 1.0f;
	
	m_pD3DDev->SetVertexShaderConstant(CV_LIGHT1_DIRECTION, &vLightEye.x, 1);

	D3DXVECTOR4 vLightAmbient(0.2f, 0.2f, 0.2f, 0.0f);
	m_pD3DDev->SetVertexShaderConstant(CV_LIGHT1_AMBIENT, &vLightAmbient.x, 1);
		
	if (m_pDolphinMap)
		m_pD3DDev->SetTexture(0, m_pDolphinMap);
		
	DWORD tex = ((DWORD)(pTimer->GetDuration()*32))%32;

	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
	
	// Copy the alpha through from the vertex shader
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG2);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);

	// Note that this premodulate is possible because the vertex shader has cunningly setup
	// the alpha channel to contain the intensity of the light.
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_BLENDCURRENTALPHA);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);

	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG2);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

	if ((m_vecCausticTextures.size() > tex) && m_vecCausticTextures[tex])
		m_pD3DDev->SetTexture(1, m_vecCausticTextures[tex]);
	
	hr = m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, m_dwNumVertices, 0, m_dwNumIndices/3);

	// Sea roof
	D3DXMatrixRotationZ(&matWorld, D3DX_PI);
	matWorld._42 += 10.0f;

	m_pNVDevice->SetWorldTransform(&matWorld);
	SetTransform();

	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_MODULATE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
	
	m_pD3DDev->SetTexture(1, m_vecCausticTextures[tex]);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_MODULATE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAOP,   D3DTOP_MODULATE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);

	m_pFloorMesh->Render(m_pNVDevice);

	// Sea floor
	D3DXMatrixScaling( &matWorld, 1.0f, 1.0f, 1.0f);
	m_pNVDevice->SetWorldTransform(&matWorld);
	SetTransform();

	m_pFloorMesh->Render(m_pNVDevice);
	
	return hr;
}

HRESULT CShaderMorph::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
	if (!(pCaps->MaxSimultaneousTextures >= 2))
	{
		m_strLastError = "Device cannot dual texture!";
		return E_FAIL;
	}

	if (!(pCaps->TextureOpCaps & D3DTEXOPCAPS_BLENDCURRENTALPHA))
	{
		m_strLastError = "Device cannot handle BLENDCURRENTALPHA operation!";
		return E_FAIL;
	}

	return S_OK;

}

void CShaderMorph::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 W - Wireframe Toggle \n\n P\\Pause - Pause animation\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_PAUSE:
		{
			m_bPause = !m_bPause;
			m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
		}
		break;

		default:
		break;
    }

}

⌨️ 快捷键说明

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