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

📄 depthoffield.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSV,  D3DTADDRESS_CLAMP);
    }

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

    m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
	m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

	m_pD3DDev->SetStreamSource(0, mpQuadVertexBuffer, sizeof(tQuadVertex));

    // turn on our special filtering pixel shader
	m_pD3DDev->SetVertexShader(m_dwBlurVertexShader);
    m_pD3DDev->SetPixelShader(m_dwBlurPixelShader);	
    
    return S_OK;
}

HRESULT CDepthOfField::SetMatrices(D3DXMATRIX  const &matWorld)
{
    // set up vertex shading constants to contain proper
    // transformation matrices etc.
    D3DXMATRIX  matLookRotations;

    D3DXMatrixTranspose(&matLookRotations, &(mpMouseUI->GetRotationMatrix()));
    mCamLookDirection = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
    D3DXVec3TransformNormal(&mCamLookDirection, &mCamLookDirection, &matLookRotations);

    D3DXVECTOR3 const vLookatPt = mCamPosition + mCamLookDirection;
	D3DXVECTOR3 const vUp       = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
    float const     fieldOfView = 2.0f * atanf(.5f*kFilmDimension/mFocalLength);

    D3DXMATRIX  matView;
	D3DXMATRIX  matProj;

    D3DXMatrixLookAtLH(&matView, &mCamPosition, &vLookatPt, &vUp);
    D3DXMatrixPerspectiveFovLH( &matProj, fieldOfView, 1.0f, kCloseClip, kFarClip );

    D3DXMATRIX matWorldView;
	D3DXMATRIX matWorldViewIT;
	D3DXMATRIX matWorldViewProj;

	D3DXMatrixMultiply(&matWorldView,     &matWorld,     &matView);
	D3DXMatrixMultiply(&matWorldViewProj, &matWorldView, &matProj);
	
	// Write Projection to clip space matrix to constant memory
	D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);

	// Create a 3x3 inverse of the world matrix for the normal transformation 
    // (we transpose it as we load it into the constant store)
	D3DXMatrixInverse(&matWorldViewIT, NULL, &matWorldView);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWIT_0, &matWorldViewIT(0, 0), 3);

    // finally write the worldView matrix: it takes vertices to view-space 
	D3DXMatrixTranspose(&matWorldView, &matWorldView);
    m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEW_0, &matWorldView(0, 0), 4);

	// Create a directional light and transform it to eye-space
	// Shader math requires that the vector is to the light
	D3DXVECTOR3 vLight( 0.0f, 1.0f, 0.25f);

	// Transform direction vector into eye space
	D3DXVec3Normalize(      &vLight, &vLight);
	D3DXVec3TransformNormal(&vLight, &vLight, &matView);
	D3DXVec3Normalize(      &vLight, &vLight);

	m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_DIRECTION, &vLight, 1);
 
    // color of the light
    D3DXVECTOR4     lightDiffuse(0.9f, 0.9f, 1.0f, 0.0f);
    m_pD3DDev->SetVertexShaderConstant(CV_LIGHT_DIFFUSE, &lightDiffuse, 1);    

    return S_OK;
}
    
HRESULT CDepthOfField::Free()
{
    SAFE_RELEASE(mpTetrahedronVertices);
    SAFE_RELEASE(mpTetrahedronIndices);
	SAFE_RELEASE(mpQuadVertexBuffer);
    SAFE_RELEASE(mpWorldBoxVertices);
    SAFE_RELEASE(mpWorldBoxIndices);

	SAFE_DELETE(m_pNVDevice);
	
    if (m_pD3DDev)
	{
        // reset buffers properly
        if ((mpBackbufferColor) != NULL && (mpBackbufferDepth != NULL))
        {
            HRESULT hr = m_pD3DDev->SetRenderTarget(mpBackbufferColor, mpBackbufferDepth);
            _ASSERT(hr == S_OK);
        }
        SAFE_RELEASE(mpBackbufferColor);
		SAFE_RELEASE(mpBackbufferDepth);

		m_pD3DDev->DeletePixelShader (m_dwShowBlurrinessShader);
		m_pD3DDev->DeleteVertexShader(m_dwBlurVertexShader);
		m_pD3DDev->DeletePixelShader (m_dwBlurPixelShader );
		m_pD3DDev->DeletePixelShader (m_dwDepthOfFieldPixelShader);
		m_pD3DDev->DeleteVertexShader(m_dwWorldVertexShader);
		m_pD3DDev->DeletePixelShader (m_dwWorldNoDoFPixelShader );
		m_pD3DDev->DeletePixelShader (m_dwWorldPixelShader );
		m_pD3DDev->DeleteVertexShader(m_dwTetraVertexShader);
		m_pD3DDev->DeletePixelShader (m_dwTetraNoDoFPixelShader );
		m_pD3DDev->DeletePixelShader (m_dwTetraPixelShader );

        for (int i = 0; i < 3; ++i)
        {
            SAFE_RELEASE(mpFilterTarget[i]);
            SAFE_RELEASE(mpTextureFiltered[i]);
        }
        for (i = 0; i < 2; ++i)
        {
            SAFE_RELEASE(mpTempTexture[i]);
            SAFE_RELEASE(mpTempTarget [i]);
        }
        for (i = 0; i < 6; i++)
            SAFE_DELETE(mpWorldTextures[i]);

        SAFE_DELETE(mpObjectTexture);

        SAFE_RELEASE(mpDepthTarget);
        SAFE_RELEASE(mpCircleOfConfusionLookup);
        SAFE_RELEASE(mpVolCircleOfConfusionLookup);

        SAFE_RELEASE(m_pD3DDev);
	}	
    SAFE_DELETE(mpMouseUI);

	return S_OK;
}

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

HRESULT CDepthOfField::Tick(EBTimer* pTimer)
{
	HRESULT hr;
    int     i, j, k;

    // update view-state from the keyboard
    SetViewFromKeyboardInput(pTimer);

    // set a bunch of render-state for rendering the world
    m_pD3DDev->SetRenderState(D3DRS_FILLMODE, (mbWireFrame) ? D3DFILL_WIREFRAME : D3DFILL_SOLID);

    m_pD3DDev->SetTexture(0, mpObjectTexture->GetTexture());
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP);
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );

    if (mbUsesVolumes) 
        m_pD3DDev->SetTexture(1, mpVolCircleOfConfusionLookup);
    else
        m_pD3DDev->SetTexture(1, mpCircleOfConfusionLookup);

	m_pD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_NONE);
    m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSW, D3DTADDRESS_CLAMP);

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

    m_pD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
    m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

    // first render the world "normally" but into a texture
    hr = m_pD3DDev->SetRenderTarget(mpFilterTarget[0], mpDepthTarget);
	hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0x0, 0x0, 0x0, 0x60 ), 1.0, 0);

    // draw lots of tetrahedra here
    D3DXVECTOR4     ambientLight(0.3f, 0.3f, 0.15f, 1.0f);
    m_pD3DDev->SetVertexShaderConstant(CV_AMBIENT_LIGHT, &ambientLight, 1);

    m_pD3DDev->SetVertexShader(m_dwTetraVertexShader);
    if (meDisplayOption != SHOW_DEPTH)
        m_pD3DDev->SetPixelShader (m_dwTetraPixelShader);
    else
        m_pD3DDev->SetPixelShader (m_dwTetraNoDoFPixelShader);


    m_pD3DDev->SetStreamSource(0, mpTetrahedronVertices, sizeof(tTetrahedronVertex));
	m_pD3DDev->SetIndices(mpTetrahedronIndices, 0);

	D3DXVECTOR3 const   vUp       = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
	D3DXMATRIX          matWorld;
	D3DXMATRIX          matTemp;
    float               x, z, s, r;
    float               cr, cg, cb;
    float const         kRandMax  = static_cast<float>(RAND_MAX);

    // init random number generator (we need to get the same sequence every frame)
    srand( 3 );

    for (i = 0; i < kNumTetrahedra; ++i)
    {
        s = 1.0f + 0.5f * static_cast<float>(rand())/kRandMax;
        r = 2.0f * D3DX_PI * static_cast<float>(rand())/kRandMax;
        x = mWorldBoxDimensions.x * (0.5f - static_cast<float>(rand())/kRandMax);
        z = mWorldBoxDimensions.z * (0.5f - static_cast<float>(rand())/kRandMax);

        D3DXMatrixScaling     (&matWorld, s, s, s);
        D3DXMatrixRotationAxis(&matTemp,  &vUp, r);
        D3DXMatrixMultiply    (&matWorld, &matWorld, &matTemp);
        D3DXMatrixTranslation (&matTemp,  x, 0.0f, z);
        D3DXMatrixMultiply    (&matWorld, &matWorld, &matTemp);

        hr = SetMatrices( matWorld );

        cr = 0.7f + 0.5f * static_cast<float>(rand())/kRandMax;
        cg = 0.7f + 0.5f * static_cast<float>(rand())/kRandMax;
        cb = 0.7f + 0.5f * static_cast<float>(rand())/kRandMax;

        D3DXVECTOR4     materialColor(cr, cg, cb, 1.0f);
        m_pD3DDev->SetVertexShaderConstant(CV_MATERIAL, &materialColor, 1);       

	    m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 12, 0, 4);
    }

    // draw the floor next
	// Scale the world box and put it outside the world
	D3DXVECTOR3 const vecScale = mWorldBoxDimensions;
	D3DXMatrixScaling(&matWorld, vecScale.x, vecScale.y, vecScale.z);

    hr = SetMatrices( matWorld );

    m_pD3DDev->SetVertexShader(m_dwWorldVertexShader);
    if (meDisplayOption != SHOW_DEPTH)
        m_pD3DDev->SetPixelShader (m_dwWorldPixelShader);
    else
        m_pD3DDev->SetPixelShader (m_dwWorldNoDoFPixelShader);

    m_pD3DDev->SetStreamSource(0, mpWorldBoxVertices, sizeof(tQuadVertex));
	m_pD3DDev->SetIndices(mpWorldBoxIndices, 0);

    // change the color texture, but all other stages and settings stay the same
    m_pD3DDev->SetTexture(0, mpWorldTextures[1]->GetTexture());

    m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    // draw the floor a bit different
    for (j = 0; j < kNumQuadsPerSide; ++j)   // for each strip
	    m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, kNumVertices, 
                                        kNumIndicesPerFace + j*2*(kNumQuadsPerSide+1), 
                                        kNumTrisPerStrip);

    // draw the walls and ceiling
    m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
	m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
    m_pD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	m_pD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );

    for (i = 0; i < 6; ++i)         // for each cube face, except the floor
        if (i != 1)
        {
            m_pD3DDev->SetTexture(0, mpWorldTextures[i]->GetTexture());
            for (j = 0; j < kNumQuadsPerSide; ++j)   // for each strip
                m_pD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, kNumVertices, 
                                                i*kNumIndicesPerFace + j*2*(kNumQuadsPerSide+1), 
                                                kNumTrisPerStrip);
        }

    // then take the just rendered texture and generate blurred versions
    D3DXMATRIX matView;
	D3DXMATRIX matProj;
	D3DXMATRIX matViewProj;
	D3DXMATRIX matWorldViewProj;

    hr = SetBlurRenderState();

	D3DXVECTOR3 const vEyePt    = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
	D3DXVECTOR3 const vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );

	// Set World, View, Projection, and combination matrices.
	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
	D3DXMatrixOrthoLH(&matProj, 4.0f, 4.0f, 0.2f, 20.0f);

    D3DXMatrixMultiply(&matViewProj, &matView, &matProj);

    // draw a single quad to texture: the quad covers the whole "screen" exactly
	D3DXMatrixScaling(&matWorld, 2.0f, 2.0f, 1.0f);
	D3DXMatrixMultiply(&matWorldViewProj, &matWorld, &matViewProj);
    D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);

    // write to constant memory to use the box9-filter
    D3DXVECTOR4     offset(1.0f, 0.0f, 0.0f, 0.0f);
    m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);

    // mpFilterTarget[0] is the full-res texture
    // make mpFilterTarget[1] = blur^kNumOfFilterSteps( mpFilterTarget[0] )
    // make mpFilterTarget[2] = blur^kNumOfFilterSteps( mpFilterTarget[1] )
    IDirect3DTexture8       *pSource;
    IDirect3DSurface8       *pDestination;

    for (i = 1; i < 3; ++i)     // this loop is for generating mpFilterTarget[i]
    {
        for (j = 0; j < kNumOfFilterSteps; ++j) // this loop does several blur passes
        {
            // alternate source and destination
            pSource      = mpTempTexture[ j   %2];
            pDestination = mpTempTarget [(j+1)%2]; 
            if (j == 0)                         // first time thru
                pSource = mpTextureFiltered[i-1];
            else if (j == kNumOfFilterSteps-1)  // last time thru
                pDestination = mpFilterTarget[i]; 
            
            // using the source and destination pointers set-up the render-state
            hr = m_pD3DDev->SetRenderTarget(pDestination, NULL);
            for (k = 0; k < 4; ++k)
                m_pD3DDev->SetTexture(k, pSource);
    
            // no need to clear the buffer: z-test is off: thus everything is overwritten
            // now just draw the quad with displaced texture coordinates
            hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
        }
    }

    // then render a single quad to the back-buffer.
    // this quad uses a special depth of field blend pixel filter
    hr = m_pD3DDev->SetRenderTarget(mpBackbufferColor, NULL);
	// again, z-test is still off, so all is overwritten -- no need to clear

	m_pD3DDev->SetVertexShader(m_dwBlurVertexShader);

    if (meDisplayOption == SHOW_COLORS)
        m_pD3DDev->SetPixelShader(m_dwDepthOfFieldPixelShader);	
    else
        m_pD3DDev->SetPixelShader(m_dwShowBlurrinessShader);	

    m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

    // use the original and blurred textures
    for (i = 0; i < 3; ++i)
    {
        m_pD3DDev->SetTexture(i, mpTextureFiltered[i]);
        m_pD3DDev->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_NONE   );
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
    }
    m_pD3DDev->SetTexture(3, NULL);

	D3DXMatrixScaling(&matWorld, 2.0f, 2.0f, 1.0f);
	D3DXMatrixMultiply(&matWorldViewProj, &matWorld, &matViewProj);
    D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);

⌨️ 快捷键说明

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