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

📄 shadowvolume.cpp

📁 VC中使用C#作为脚本引擎编程
💻 CPP
📖 第 1 页 / 共 5 页
字号:

    V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
    V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
    // Initialize the vertex declaration
    V_RETURN( pd3dDevice->CreateVertexDeclaration( MESHVERT::Decl, &g_pMeshDecl ) );
    V_RETURN( pd3dDevice->CreateVertexDeclaration( SHADOWVERT::Decl, &g_pShadowDecl ) );
    V_RETURN( pd3dDevice->CreateVertexDeclaration( POSTPROCVERT::Decl, &g_pPProcDecl ) );

    // Initialize the font
    V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
                         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
                         L"Arial", &g_pFont ) );

    // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the 
    // shader debugger. Debugging vertex shaders requires either REF or software vertex 
    // processing, and debugging pixel shaders requires REF.  The 
    // D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the 
    // shader debugger.  It enables source level debugging, prevents instruction 
    // reordering, prevents dead code elimination, and forces the compiler to compile 
    // against the next higher available software target, which ensures that the 
    // unoptimized shaders do not exceed the shader model limitations.  Setting these 
    // flags will cause slower rendering since the shaders will be unoptimized and 
    // forced into software.  See the DirectX documentation for more information about 
    // using the shader debugger.
    DWORD dwShaderFlags = 0;
    #ifdef DEBUG_VS
        dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
    #endif
    #ifdef DEBUG_PS
        dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
    #endif

    // Read the D3DX effect file
    WCHAR str[MAX_PATH];
    V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"ShadowVolume.fx" ) );

    // If this fails, there should be debug output as to 
    // they the .fx file failed to compile
    V_RETURN( D3DXCreateEffectFromFile( pd3dDevice, str, NULL, NULL, dwShaderFlags, 
                                        NULL, &g_pEffect, NULL ) );

    // Determine the rendering techniques to use based on device caps
    D3DCAPS9 Caps;
    V_RETURN( pd3dDevice->GetDeviceCaps( &Caps ) );

    if( Caps.PixelShaderVersion >= D3DPS_VERSION( 2, 0 ) )
        g_hRenderScene = g_pEffect->GetTechniqueByName( "RenderScene" );
    else
        g_hRenderScene = g_pEffect->GetTechniqueByName( "RenderScene1x" );

    // If 2-sided stencil is supported, use it.
    if( Caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED )
    {
        g_hRenderShadow = g_pEffect->GetTechniqueByName( "RenderShadowVolume2Sided" );
        g_hShowShadow = g_pEffect->GetTechniqueByName( "ShowShadowVolume2Sided" );
    }
    else
    {
        g_hRenderShadow = g_pEffect->GetTechniqueByName( "RenderShadowVolume" );
        g_hShowShadow = g_pEffect->GetTechniqueByName( "ShowShadowVolume" );
    }

    // Load the meshes
    V_RETURN( g_Background[0].Create( pd3dDevice, L"misc\\cell.x" ) );
    g_Background[0].SetVertexDecl( pd3dDevice, MESHVERT::Decl );
    V_RETURN( g_Background[1].Create( pd3dDevice, L"misc\\seafloor.x" ) );
    g_Background[1].SetVertexDecl( pd3dDevice, MESHVERT::Decl );
    V_RETURN( g_LightMesh.Create( pd3dDevice, L"misc\\sphere0.x" ) );
    g_LightMesh.SetVertexDecl( pd3dDevice, MESHVERT::Decl );
    V_RETURN( g_Mesh.Create( pd3dDevice, DEFMESHFILENAME ) );
    g_Mesh.SetVertexDecl( pd3dDevice, MESHVERT::Decl );

    // Compute the scaling matrix for the mesh so that the size of the mesh
    // that shows on the screen is consistent.
    ComputeMeshScaling( g_Mesh, &g_mWorldScaling );

    // Setup the camera's view parameters
    D3DXVECTOR3 vecEye(0.0f, 0.0f, -5.0f);
    D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f);
    g_Camera.SetViewParams( &vecEye, &vecAt );
    g_LCamera.SetViewParams( &vecEye, &vecAt );
    g_MCamera.SetViewParams( &vecEye, &vecAt );

    // Create the 1x1 white default texture
    V_RETURN( pd3dDevice->CreateTexture( 1, 1, 1, 0, D3DFMT_A8R8G8B8,
                                         D3DPOOL_MANAGED, &g_pDefaultTex, NULL ) );
    D3DLOCKED_RECT lr;
    V_RETURN( g_pDefaultTex->LockRect( 0, &lr, NULL, 0 ) );
    *(LPDWORD)lr.pBits = D3DCOLOR_RGBA( 255, 255, 255, 255 );
    V_RETURN( g_pDefaultTex->UnlockRect( 0 ) );

    return S_OK;
}


//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has been 
// reset, which will happen after a lost device scenario. This is the best location to 
// create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever 
// the device is lost. Resources created here should be released in the OnLostDevice 
// callback. 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    HRESULT hr;

    V_RETURN( g_DialogResourceManager.OnResetDevice() );
    V_RETURN( g_SettingsDlg.OnResetDevice() );

    if( g_pFont )
        V_RETURN( g_pFont->OnResetDevice() );
    if( g_pEffect )
        V_RETURN( g_pEffect->OnResetDevice() );

    g_Background[0].RestoreDeviceObjects( pd3dDevice );
    g_Background[1].RestoreDeviceObjects( pd3dDevice );
    g_LightMesh.RestoreDeviceObjects( pd3dDevice );
    g_Mesh.RestoreDeviceObjects( pd3dDevice );

    // Create a sprite to help batch calls when drawing many lines of text
    V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );

    // Setup the camera's projection parameters
    float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
    g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1f, 20.0f );
    g_MCamera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
    g_LCamera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
    g_pEffect->SetFloat( "g_fFarClip", 20.0f - EXTRUDE_EPSILON );
    V( g_pEffect->SetMatrix( "g_mProj", g_Camera.GetProjMatrix() ) );

    g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
    g_HUD.SetSize( 170, 170 );
    g_SampleUI.SetLocation( 0, pBackBufferSurfaceDesc->Height-200 );
    g_SampleUI.SetSize( pBackBufferSurfaceDesc->Width, 150 );

    int iY = 10;
    g_SampleUI.GetControl( IDC_CHANGESCRIPT )->SetLocation( pBackBufferSurfaceDesc->Width - 200, iY += 24 );

    // Generate the shadow volume mesh
    GenerateShadowMesh( pd3dDevice, g_Mesh.GetMesh(), &g_pShadowMesh );

    return S_OK;
}


//--------------------------------------------------------------------------------------
// This callback function will be called once at the beginning of every frame. This is the
// best location for your application to handle updates to the scene, but is not 
// intended to contain actual rendering calls, which should instead be placed in the 
// OnFrameRender callback.  
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    // Update the camera's position based on user input 
    g_Camera.FrameMove( fElapsedTime );
    g_MCamera.FrameMove( fElapsedTime );
    g_LCamera.FrameMove( fElapsedTime );

    // Let script engine handle this
    D3DXMATRIX Matrix = *g_MCamera.GetWorldMatrix();
    UpdatePlayerRotationX(fTime, &Matrix);
    UpdatePlayerRotationY(fTime, &Matrix);
    UpdatePlayerRotationZ(fTime, &Matrix);
    UpdatePlayerPosition(fTime, (float*)&Matrix._41, (float*)&Matrix._42, (float*)&Matrix._43);
    g_MCamera.SetWorldMatrix(Matrix);
}


//--------------------------------------------------------------------------------------
// Simply renders the entire scene without any shadow handling.
void RenderScene( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, bool bRenderLight )
{
    HRESULT hr;
    D3DXMATRIXA16 mWorldView;
    D3DXMATRIXA16 mViewProj;
    D3DXMATRIXA16 mWorldViewProjection;

    // Get the projection & view matrix from the camera class
    D3DXMatrixMultiply( &mViewProj, g_Camera.GetViewMatrix(), g_Camera.GetProjMatrix() );

    // Render the lights if requested
    if( bRenderLight )
    {
        D3DXHANDLE hCurrTech;
        hCurrTech = g_pEffect->GetCurrentTechnique();  // Save the current technique
        V( g_pEffect->SetTechnique( "RenderSceneAmbient" ) );
        V( g_pEffect->SetTexture( "g_txScene", g_pDefaultTex ) );
        D3DXVECTOR4 vLightMat( 1.0f, 1.0f, 1.0f, 1.0f );
        V( g_pEffect->SetVector( "g_vMatColor", &vLightMat ) );
        UINT cPasses;
        ID3DXMesh *pMesh = g_LightMesh.GetMesh();
        V( g_pEffect->Begin( &cPasses, 0 ) );
        for( UINT p = 0; p < cPasses; ++p )
        {
            V( g_pEffect->BeginPass( p ) );
            for( int i = 0; i < g_nNumLights; ++i )
            {
                for( UINT m = 0; m < g_LightMesh.m_dwNumMaterials; ++m )
                {
                    mWorldView = g_aLights[i].m_mWorld * *g_LCamera.GetWorldMatrix() * *g_Camera.GetViewMatrix();
                    mWorldViewProjection = mWorldView * *g_Camera.GetProjMatrix();
                    V( g_pEffect->SetMatrix( "g_mWorldView", &mWorldView ) );
                    V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
                    V( g_pEffect->SetVector( "g_vAmbient", &g_aLights[i].m_Color ) );

                    // The effect interface queues up the changes and performs them 
                    // with the CommitChanges call. You do not need to call CommitChanges if 
                    // you are not setting any parameters between the BeginPass and EndPass.
                    V( g_pEffect->CommitChanges() );

                    V( pMesh->DrawSubset( m ) );
                }
            }
            V( g_pEffect->EndPass() );
        }
        V( g_pEffect->End() );
        V( g_pEffect->SetTechnique( hCurrTech ) ); // Restore the old technique
        D3DXVECTOR4 vAmb( AMBIENT, AMBIENT, AMBIENT, 1.0f );
        V( g_pEffect->SetVector( "g_vAmbient", &vAmb ) );
    }

    // Render the background mesh
    V( pd3dDevice->SetVertexDeclaration( g_pMeshDecl ) );
    mWorldView = g_mWorldBack[g_nCurrBackground] * *g_Camera.GetViewMatrix();
    mWorldViewProjection = g_mWorldBack[g_nCurrBackground] * mViewProj;
    V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
    V( g_pEffect->SetMatrix( "g_mWorldView", &mWorldView ) );
    UINT cPasses;
    V( g_pEffect->Begin( &cPasses, 0 ) );
    for( UINT p = 0; p < cPasses; ++p )
    {
        V( g_pEffect->BeginPass( p ) );
        ID3DXMesh *pMesh = g_Background[g_nCurrBackground].GetMesh();
        for( UINT i = 0; i < g_Background[g_nCurrBackground].m_dwNumMaterials; ++i )
        {
            V( g_pEffect->SetVector( "g_vMatColor", (D3DXVECTOR4*)&g_Background[g_nCurrBackground].m_pMaterials[i].Diffuse ) );
            if( g_Background[g_nCurrBackground].m_pTextures[i] )
                V( g_pEffect->SetTexture( "g_txScene", g_Background[g_nCurrBackground].m_pTextures[i] ) )
            else
                V( g_pEffect->SetTexture( "g_txScene", g_pDefaultTex ) );
            // The effect interface queues up the changes and performs them 
            // with the CommitChanges call. You do not need to call CommitChanges if 
            // you are not setting any parameters between the BeginPass and EndPass.
            V( g_pEffect->CommitChanges() );
            V( pMesh->DrawSubset( i ) );
        }
        V( g_pEffect->EndPass() );
    }
    V( g_pEffect->End() );

    // Render the mesh
    V( pd3dDevice->SetVertexDeclaration( g_pMeshDecl ) );
    mWorldView = g_mWorldScaling * *g_MCamera.GetWorldMatrix() * *g_Camera.GetViewMatrix();
    mWorldViewProjection = mWorldView * *g_Camera.GetProjMatrix();
    V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &mWorldViewProjection ) );
    V( g_pEffect->SetMatrix( "g_mWorldView", &mWorldView ) );
    V( g_pEffect->Begin( &cPasses, 0 ) );
    for( UINT p = 0; p < cPasses; ++p )
    {
        V( g_pEffect->BeginPass( p ) );
        ID3DXMesh *pMesh = g_Mesh.GetMesh();
        for( UINT i = 0; i < g_Mesh.m_dwNumMaterials; ++i )
        {
            V( g_pEffect->SetVector( "g_vMatColor", (D3DXVECTOR4*)&g_Mesh.m_pMaterials[i].Diffuse ) );
            if( g_Mesh.m_pTextures[i] )
                V( g_pEffect->SetTexture( "g_txScene", g_Mesh.m_pTextures[i] ) )
            else
                V( g_pEffect->SetText

⌨️ 快捷键说明

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