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

📄 shader_trees.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	{
		m_pD3DDev->DeleteVertexShader(m_dwTreeShader);
		m_pD3DDev->DeleteVertexShader(m_dwTerrainShader);
		SAFE_RELEASE(m_pD3DDev);
	}
	
	return S_OK;
}

HRESULT CShaderTrees::Start()
{

	return S_OK;
}

  
HRESULT CShaderTrees::SetTransform()
{
	D3DXMATRIX matTemp;
	D3DXMATRIX matWorldViewProj;
	D3DXMATRIX matWorldView;
	D3DXMATRIX matWorldViewIT;

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

	D3DXMatrixMultiply(&matTemp, &matWorld, &matView);
	D3DXMatrixMultiply(&matWorldViewProj, &matTemp, &matProj);
	D3DXMatrixMultiply(&matWorldView, &matWorld, &matView);
	
	// 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 from eye to projection
	D3DXMatrixTranspose(&matProj, &matProj);
	m_pD3DDev->SetVertexShaderConstant(CV_PROJ_0, &matProj(0, 0), 4);
	D3DXMatrixTranspose(&matProj, &matProj);

	// 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);

	// Sometimes we don't need the shader - just draw with the current world/view/projection matrices
	m_pD3DDev->SetTransform(D3DTS_WORLD, &matWorld);
	m_pD3DDev->SetTransform(D3DTS_VIEW, &matView);
	m_pD3DDev->SetTransform(D3DTS_PROJECTION, &matProj);
	return S_OK;

}

HRESULT CShaderTrees::DrawFishViewport()
{
    // Draw the background
    m_pD3DDev->SetTexture(0, m_pFishViewTexture);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
	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->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

    m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
    m_pD3DDev->SetStreamSource(0, m_pFishViewVB, sizeof(TLVertex));
    m_pD3DDev->SetVertexShader(D3DFVF_TLVERTEX);

    // Enable alpha testing to overdraw the outer pixels
    m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    m_pD3DDev->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_INVSRCALPHA);
    m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);

    m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
    m_pD3DDev->SetRenderState( D3DRS_ALPHAREF,        0x80);
    m_pD3DDev->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_LESS);

    m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 );

    // Restore render states
    m_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
	m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
    m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE);

	return S_OK;
}

HRESULT CShaderTrees::DrawTrees(bool bDistort)
{
	D3DXMATRIX matWorld;
	D3DXMatrixIdentity(&matWorld);

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

    // Set state for drawing trees
    m_pD3DDev->SetTexture( 0, m_pTreeTexture);
	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->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

    // Set diffuse blending for alpha set in vertices. 
    m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE,   TRUE );
    m_pD3DDev->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
    m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );

    // Enable alpha testing (skips pixels with less than a certain alpha.)
    m_pD3DDev->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
    m_pD3DDev->SetRenderState( D3DRS_ALPHAREF,        0x80);
    m_pD3DDev->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATER);

	if (bDistort)
	{
		m_pD3DDev->SetVertexShader(m_dwTreeShader);
	}
	else
	{
		m_pD3DDev->SetVertexShader(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
	}

    // Copy tree mesh into vertexbuffer
    TREEVERTEX* v;
    m_pTreeVB->Lock( 0, 0, (BYTE**)&v, D3DLOCK_DISCARD );
    for( DWORD i=0; i<NUM_TREES; i++ )
    {
        memcpy( v, m_vecTrees[i].v, 4*sizeof(TREEVERTEX) );
        v += 4;
    }
    m_pTreeVB->Unlock();
    m_pD3DDev->SetStreamSource( 0, m_pTreeVB, sizeof(TREEVERTEX) );

    // Loop through and render all trees    
    for( i=0; i<NUM_TREES; i++ )
    {
        // Translate the billboard into place
        m_matBillboardMatrix._41 = m_vecTrees[i].vPos.x;
        m_matBillboardMatrix._42 = m_vecTrees[i].vPos.y;
        m_matBillboardMatrix._43 = m_vecTrees[i].vPos.z;

		// Load values
		m_pNVDevice->SetWorldTransform(&m_matBillboardMatrix);
		SetTransform();

        // Render the billboard
        m_pD3DDev->DrawPrimitive( D3DPT_TRIANGLESTRIP, i*4, 2 );
    }

    m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
    m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

    return S_OK;
}

HRESULT CShaderTrees::DrawTerrain(bool bDistort)
{
	D3DXMATRIX matWorld;
	D3DXMatrixIdentity(&matWorld);
	m_pNVDevice->SetWorldTransform(&matWorld);
	SetTransform();

	// Set terrain state
	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->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

	// Draw the terrain
	if (bDistort)
	{
		m_pTerrain->SetVertexShader(m_dwTerrainShader);
	}
	else
	{
		m_pTerrain->SetVertexShader(0);
	}

	// Call the terrain object to do the work
	m_pTerrain->Render(m_pNVDevice);

    return S_OK;
}

HRESULT CShaderTrees::Tick(EBTimer* pTimer)
{
	HRESULT hr = S_OK;
	D3DXMATRIX matTemp;
	D3DXMATRIX matWorld;
	D3DXMATRIX matView;
	D3DVIEWPORT8 Viewport;
	D3DVIEWPORT8 NewViewport;

	D3DXVECTOR3 vEyePt;
	D3DXVECTOR3 vLookatPt;
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );

    m_pD3DDev->SetRenderState(D3DRS_FILLMODE, (mbWireFrame) ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
	hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0xAA, 0xAA, 0xAA ), 1.0, 0);

    float const     kSpeed = 20.0f;
	
	if (!m_bPause)
	{
		m_fDuration = pTimer->GetDuration();
	}

    // Move the camera about a large circle through the trees
    vEyePt.x = 30.0f*cosf( ((m_fDuration+0.0f)/kSpeed) * 2 * D3DX_PI );
    vEyePt.z = 30.0f*sinf( ((m_fDuration+0.0f)/kSpeed) * 2 * D3DX_PI );
    vEyePt.y = 5.5f + HeightField( vEyePt.x, vEyePt.z );

    vLookatPt.x = 30.0f*cosf( ((m_fDuration+0.5f)/kSpeed) * 2 * D3DX_PI );
    vLookatPt.z = 30.0f*sinf( ((m_fDuration+0.5f)/kSpeed) * 2 * D3DX_PI );
    vLookatPt.y = 4.2f + HeightField(vEyePt.x, vEyePt.z);

	// Identity world transform
	D3DXMatrixIdentity(&matWorld);

    // Set the app view matrix for normal viewing
    D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );

    // Set up a rotation matrix to orient the billboard towards the camera.
    D3DXVECTOR3 vDir = vLookatPt - vEyePt;
    if( vDir.x > 0.0f )
        D3DXMatrixRotationY( &m_matBillboardMatrix, -atanf(vDir.z/vDir.x)+D3DX_PI/2 );
    else
        D3DXMatrixRotationY( &m_matBillboardMatrix, -atanf(vDir.z/vDir.x)-D3DX_PI/2 );

    // Sort trees in back-to-front order
	sort(m_vecTrees.begin(), m_vecTrees.end(), CompareToEye(vEyePt) );

	// Get the current viewport
	m_pD3DDev->GetViewport(&Viewport);
	memcpy(&NewViewport, &Viewport, sizeof(D3DVIEWPORT8));
	
	// Draw fish-eye pass
	// Setup the viewport to the top half
	NewViewport.Height = Viewport.Height / 2;
	m_pD3DDev->SetViewport(&NewViewport);

	// Set the current transform
	m_pNVDevice->SetWorldTransform(&matWorld);
	m_pNVDevice->SetViewTransform(&matView);
	SetTransform();
	
	// Draw the terrain
	DrawTerrain(true);

	// Draw the trees
	DrawTrees(true);

	// Draw the fisheye view
	DrawFishViewport();

	// Draw the undistorted view of the world
	// Set viewport to be the bottom
	NewViewport.Y = (Viewport.Height / 2) + 2;
	NewViewport.Height -= 2;
	m_pD3DDev->SetViewport(&NewViewport);
	SetTransform();

	// Draw terrain
	DrawTerrain(false);

	// Draw the trees
	DrawTrees(false);

	// Restore the viewport
	m_pD3DDev->SetViewport(&Viewport);

	return hr;
}

void NVTreeDevice::SetWorldTransform(const D3DXMATRIX* pValue) 
{
	NVDevice::SetWorldTransform(pValue);
	m_pTreeShader->SetTransform();
}

HRESULT CShaderTrees::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
	return S_OK;
}

void CShaderTrees::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:
        {
            mbWireFrame = !mbWireFrame;
            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 + -