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

📄 bumpearth.cpp

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
// File: BumpEarth.cpp
//
// Desc: Direct3D 环境贴图/凹凸贴图 实例。
//-----------------------------------------------------------------------------
#define STRICT
#include <Windows.h>
#include <commctrl.h>
#include <math.h>
#include <stdio.h>
#include <D3DX9.h>
#include "DXUtil.h"
#include "D3DEnumeration.h"
#include "D3DSettings.h"
#include "D3DApp.h"
#include "D3DFile.h"
#include "D3DFont.h"
#include "D3DUtil.h"
#include "resource.h"

//-----------------------------------------------------------------------------
// 定义,常量,全局变量声明
//-----------------------------------------------------------------------------

// Vertex 数据结构,bumpmapped environment map使用
struct BUMPVERTEX
{
    D3DXVECTOR3 p;
    D3DXVECTOR3 n;
    FLOAT       tu1, tv1;
    FLOAT       tu2, tv2;

        static const DWORD FVF;
};
const DWORD BUMPVERTEX::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2;

// 将FLOAT转换为DWORD,在SetRenderState()调用中将用到
inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }




//-----------------------------------------------------------------------------
// Name: class CMyD3DApplication
// Desc:  
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
    CD3DFont*     m_pFont;                  //用于输出文本

    CD3DArcBall   m_ArcBall;                //用于鼠标输入

    LPDIRECT3DTEXTURE9 m_pBlockTexture;    //黑,灰纹理
    LPDIRECT3DTEXTURE9 m_pEarthTexture;     //地表纹理
    LPDIRECT3DTEXTURE9 m_pEnvMapTexture;    //环境贴图
    LPDIRECT3DTEXTURE9 m_pEarthBumpTexture; //凹凸贴图资源
    LPDIRECT3DTEXTURE9 m_psBumpMap;         //实际的凹凸贴图
    CD3DMesh* m_pSkyBox;
    LPDIRECT3DTEXTURE9 m_pDispMapTexture;   //偏移贴图纹理
    IDirect3DVertexShader9* m_pDispMapBumpShader;//偏移贴图+凹凸贴图着色
    IDirect3DVertexShader9* m_pDispMapShader;    //偏移贴图+无凹凸贴图着色
    IDirect3DVertexDeclaration9*   m_pDispMapVertexDecl;


    D3DXMATRIXA16 m_matWorld;
    D3DXMATRIXA16 m_matView;
    D3DXMATRIXA16 m_matProj;

    D3DFORMAT     m_BumpMapFormat;         //凹凸贴图纹理格式
    LPDIRECT3DVERTEXBUFFER9 m_pEarthVB;   //地球几何体
    DWORD         m_dwNumSphereVertices;

    BOOL          m_bHighTesselation;      //用户选项
    BOOL          m_bTextureOn;
    BOOL          m_bBumpMapOn;
    BOOL          m_bEnvMapOn;
    BOOL          m_bDeviceValidationFailed;
    BOOL          m_bDispMapOn;            //偏移贴图开关
    BOOL          m_bCanDoDispMap;

    VOID    SetMenuStates();
    HRESULT CreateEarthVertexBuffer();
    VOID    ApplyEnvironmentMap();
    HRESULT InitBumpMap();

protected:
    HRESULT OneTimeSceneInit();
    HRESULT InitDeviceObjects();
    HRESULT RestoreDeviceObjects();
    HRESULT InvalidateDeviceObjects();
    HRESULT DeleteDeviceObjects();
    HRESULT Render();
    HRESULT FrameMove();
    HRESULT FinalCleanup();
    HRESULT ConfirmDevice( D3DCAPS9*, DWORD, D3DFORMAT, D3DFORMAT );

public:
    CMyD3DApplication();

    LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
};




//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 程序入口。进行全部的初始化工作,然后进入消息处理循环,空闲时间被用来
//       进行渲染
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
    CMyD3DApplication d3dApp;

    InitCommonControls();
    if( FAILED( d3dApp.Create( hInst ) ) )
        return 0;

    return d3dApp.Run();
}




//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: 
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
    m_strWindowTitle    = _T("BumpEarth: Direct3D BumpMapping Demo");
    m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
    m_bShowCursorWhenFullscreen = TRUE;

    m_psBumpMap         = NULL;
    m_bTextureOn        = TRUE;
    m_bBumpMapOn        = TRUE;
    m_bEnvMapOn         = TRUE;
    m_bHighTesselation  = TRUE;
    m_bDispMapOn        = FALSE;
    m_bCanDoDispMap     = FALSE;

    m_pDispMapShader    = NULL;
    m_pDispMapBumpShader= NULL;
    m_pDispMapVertexDecl= NULL;
    m_pDispMapTexture   = NULL;
    m_pBlockTexture     = NULL;
    m_pEarthTexture     = NULL;
    m_pEarthBumpTexture = NULL;
    m_pEnvMapTexture    = NULL;
    m_pSkyBox           = NULL;
    m_bDeviceValidationFailed = FALSE;


    m_pFont             = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
    m_pEarthVB          = NULL;
}




//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: 在初始程序开始时调用。此函数进行所有常设值得初始化
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
    // 设置指针使用户可以用鼠标移动目标
#ifdef _WIN64
    SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor( NULL, IDC_SIZEALL ) );
#else
    SetClassLong( m_hWnd, GCL_HCURSOR, HandleToLong( LoadCursor( NULL, IDC_SIZEALL ) ) );
#endif

    m_pSkyBox      = new CD3DMesh();
    if( m_pSkyBox == NULL )
        return E_OUTOFMEMORY;

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: ApplyEnvironmentMap()
// Desc: 计算每个顶点的法向,从而决定环境贴图对应的纹理
//-----------------------------------------------------------------------------
VOID CMyD3DApplication::ApplyEnvironmentMap()
{
    D3DXMATRIXA16 matWorldView;
    D3DXMatrixMultiply( &matWorldView, &m_matWorld, &m_matView );

    
    BUMPVERTEX* vtx;
    m_pEarthVB->Lock( 0, 0, (void**)&vtx, 0 );

    DWORD dwNumSphereRings    = m_bHighTesselation ? 15 :  5;
    DWORD dwNumSphereSegments = m_bHighTesselation ? 30 : 10;
    FLOAT fDeltaRingAngle = ( D3DX_PI / dwNumSphereRings );
    FLOAT fDeltaSegAngle  = ( 2.0f * D3DX_PI / dwNumSphereSegments );

    D3DXVECTOR4 vT;
    FLOAT fScale;

   for( DWORD ring = 0; ring < dwNumSphereRings; ring++ )
    {
        FLOAT r0 = sinf( (ring+0) * fDeltaRingAngle );
        FLOAT r1 = sinf( (ring+1) * fDeltaRingAngle );
        FLOAT y0 = cosf( (ring+0) * fDeltaRingAngle );
        FLOAT y1 = cosf( (ring+1) * fDeltaRingAngle );

        for( DWORD seg = 0; seg < (dwNumSphereSegments+1); seg++ )
        {
            FLOAT x0 =  r0 * sinf( seg * fDeltaSegAngle );
            FLOAT z0 =  r0 * cosf( seg * fDeltaSegAngle );
            FLOAT x1 =  r1 * sinf( seg * fDeltaSegAngle );
            FLOAT z1 =  r1 * cosf( seg * fDeltaSegAngle );

            (*vtx).p   = (*vtx).n   = D3DXVECTOR3(x0,y0,z0);
            (*vtx).tu2 = 1.0f - ((FLOAT)seg) / dwNumSphereSegments;
            (*vtx).tv2 = (ring+0) / (FLOAT)dwNumSphereRings;
            D3DXVec3Transform( &vT, &(*vtx).n, &matWorldView );
            fScale = 1.37f / D3DXVec4Length( &vT );
            (*vtx).tu1 = 0.5f + fScale*vT.x;
            (*vtx).tv1 = 0.5f - fScale*vT.y;
            vtx++;

            (*vtx).p   = (*vtx).n   = D3DXVECTOR3(x1,y1,z1);
            (*vtx).tu2 = 1.0f - ((FLOAT)seg) / dwNumSphereSegments;
            (*vtx).tv2 = (ring+1) / (FLOAT)dwNumSphereRings;
            D3DXVec3Transform( &vT, &(*vtx).n, &matWorldView );
            fScale = 1.37f / D3DXVec4Length( &vT );
            (*vtx).tu1 = 0.5f + fScale*vT.x;
            (*vtx).tv1 = 0.5f - fScale*vT.y;
            vtx++;
        }
    }

    m_pEarthVB->Unlock();
}




//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: 
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
    static FLOAT fRotationAngle = 0.0f;
    if( FALSE == m_ArcBall.IsBeingDragged() )
        fRotationAngle += m_fElapsedTime;

    D3DXMatrixRotationY( &m_matWorld, -fRotationAngle );
    D3DXMatrixMultiply( &m_matWorld, &m_matWorld, m_ArcBall.GetRotationMatrix() );
    D3DXMatrixMultiply( &m_matWorld, &m_matWorld, m_ArcBall.GetTranslationMatrix() );

    D3DXVECTOR3 vEyePt    = D3DXVECTOR3( 0.0f, 0.0f, -3.0f );
    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &m_matView, &vEyePt, &vLookatPt, &vUpVec );

    ApplyEnvironmentMap();

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: Render()
// Desc: 
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{

    if( FAILED( m_pd3dDevice->BeginScene() ) )
        return S_OK; 

    {
        D3DXMATRIXA16 matWorldSkybox;
        D3DXMatrixScaling( &matWorldSkybox, 10.0f, 10.0f, 10.0f );
        m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorldSkybox );

        D3DXMATRIXA16 matViewSkybox = m_matView;
        matViewSkybox._41 = matViewSkybox._42 = matViewSkybox._43 = 0.0f;
        m_pd3dDevice->SetTransform( D3DTS_VIEW, &matViewSkybox );

        m_pd3dDevice->SetRenderState( D3DRS_WRAP0, 0 );
        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
        if( (m_d3dCaps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) == D3DPTADDRESSCAPS_MIRROR )
        {

            m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU,  D3DTADDRESS_MIRROR );
            m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV,  D3DTADDRESS_MIRROR );
        }
        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE );

        m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS );
        m_pSkyBox->Render( m_pd3dDevice );

        m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );
        m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matWorld );
        m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_matView );
    }


    m_pd3dDevice->SetRenderState( D3DRS_WRAP0, D3DWRAP_U | D3DWRAP_V );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );

    if( m_bTextureOn )
        m_pd3dDevice->SetTexture( 0, m_pEarthTexture );
    else
        m_pd3dDevice->SetTexture( 0, m_pBlockTexture );

    if( m_bDispMapOn )
    {
        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
        m_pd3dDevice->SetTextureStageState( 2, D3DTSS_TEXCOORDINDEX, 2 );
        m_pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

        m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
        m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
        m_pd3dDevice->SetSamplerState(D3DDMAPSAMPLER, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);

⌨️ 快捷键说明

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