介绍RenderTexture,RenderSurface和SetRenderTarget

来源:互联网 发布:保暖羽绒服知乎 编辑:程序博客网 时间:2024/05/18 21:50

转载

#include  < D3DX9.h >
#include  < string >
typedef std:: string  String;
 #define  SAFE_RELEASE(o) {if(o){o->Release();o = 0;}}
 
 
LPDIRECT3D9 g_pD3D  =   0 ;                 //  D3D Driver
 LPDIRECT3DDEVICE9 g_pd3dDevice  =   0 ;     //  D3D 设备
  D3DCAPS9 g_Caps  =    {(D3DDEVTYPE) 0 } ;     //  D3D 的帽子
 LPD3DXMESH g_pMeshTeapot  =   0 ;     //  茶壶顶点缓冲区
 LPDIRECT3DVERTEXBUFFER9 g_pVB  =   0 ;     //  顶点缓冲区
 LPDIRECT3DINDEXBUFFER9 g_pIB  =   0 ;     //  索引缓冲区
 LPDIRECT3DTEXTURE9 g_pTexture  =   0 ;     //  贴图
 LPDIRECT3DTEXTURE9 g_pRenderTexture  =   0 ;     //  渲染到贴图
 LPDIRECT3DSURFACE9 g_pRenderSurface  =   0 ;     //  渲染到贴图的表面
 //  顶点定义
 #define  D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
 struct  CUSTOMVERTEX
  {
    D3DXVECTOR3 position;
    D3DCOLOR color;
     float  u , v;
} ;

 //  错误记录
 void  D3DErr(String strMsg)
  {
    MessageBox( 0  , strMsg.c_str() ,  " 错误 "  , MB_OK);
}
 
 //  初始化顶点缓冲区
 HRESULT InitVB()
  {
     //  创建茶壶
      if (FAILED(D3DXCreateTeapot(g_pd3dDevice ,  & g_pMeshTeapot ,  0 )))
         return  E_FAIL;
     //  创建顶点缓冲区
      if (FAILED(g_pd3dDevice -> CreateVertexBuffer( 4   *   sizeof (CUSTOMVERTEX) ,  0  , D3DFVF_CUSTOMVERTEX , D3DPOOL_DEFAULT ,  & g_pVB ,  0 )))
         return  E_FAIL;

    CUSTOMVERTEX  * pVertecies;
     //  锁定缓冲区
      if (SUCCEEDED(g_pVB -> Lock( 0  ,  0  , ( void ** ) & pVertecies ,  0 )))
      {
        pVertecies[ 0 ].position  =  D3DXVECTOR3( - 1  ,  1  ,  0 );
        pVertecies[ 1 ].position  =  D3DXVECTOR3( - 1  ,  - 1  ,  0 );
        pVertecies[ 2 ].position  =  D3DXVECTOR3( 1  ,  1  ,  0 );
        pVertecies[ 3 ].position  =  D3DXVECTOR3( 1  ,  - 1  ,  0 );

        pVertecies[ 0 ].u  =   0 ;
        pVertecies[ 0 ].v  =   0 ;

        pVertecies[ 1 ].u  =   0 ;
        pVertecies[ 1 ].v  =   1 ;

        pVertecies[ 2 ].u  =   1 ;
        pVertecies[ 2 ].v  =   0 ;

        pVertecies[ 3 ].u  =   1 ;
        pVertecies[ 3 ].v  =   1 ;

        pVertecies[ 0 ].color  =   0xFFFFFFFF ;
        pVertecies[ 1 ].color  =   0xFFFFFFFF ;
        pVertecies[ 2 ].color  =   0xFFFFFFFF ;
        pVertecies[ 3 ].color  =   0xFFFFFFFF ;
        g_pVB -> Unlock();
    }
     else
       {
         return  E_FAIL;
    }
 
     //  载入纹理
      if (FAILED(D3DXCreateTextureFromFile(g_pd3dDevice ,  " ..//BRICE.JPG "  ,  & g_pTexture)))
      {
        D3DErr( " 无法载入纹理Brice.jpg " );
         return  E_FAIL;
    }
 
     //  创建渲染到贴图的表面
      if (FAILED(g_pd3dDevice -> CreateTexture( 512  ,  512  ,  1  , D3DUSAGE_RENDERTARGET , D3DFMT_A8R8G8B8 , D3DPOOL_DEFAULT ,  & g_pRenderTexture ,  0 )))
      {
        D3DErr( " 无法创建渲染贴图 " );
         return  E_FAIL;
    }
     //  获取贴图的渲染表面
      if (FAILED(g_pRenderTexture -> GetSurfaceLevel( 0  ,  & g_pRenderSurface)))
      {
         return  E_FAIL;
    }
     return  S_OK;
}
 
 //  初始化模型
 HRESULT InitGeometry()
  {
     //  创建顶点缓冲区
      if (FAILED(InitVB()))
         return  E_FAIL;
     return  S_OK;
}
 
 //  设置矩阵变换
 void  SetTransform()
  {

     //  世界变换
     D3DXMATRIX matWorld;
    D3DXMatrixIdentity( & matWorld);
     //  设置世界矩阵
     g_pd3dDevice -> SetTransform(D3DTS_WORLD ,  & matWorld);
     //  Set up our view matrix. A view matrix can be defined given an eye point,
     //  a point to lookat, and a direction for which way is up. Here, we set the
     //  eye five units back along the z-axis and up three units, look at the
     //  origin, and define "up" to be in the y-direction.
     //  视口变换
     D3DXMATRIX matView;
    D3DXMatrixLookAtLH( & matView ,  & D3DXVECTOR3( 0  ,  0  ,  - 5 )
        ,  & D3DXVECTOR3( 0  ,  0  ,  0 )
        ,  & D3DXVECTOR3( 0  ,  1  ,  0 ));
    g_pd3dDevice -> SetTransform(D3DTS_VIEW ,  & matView);
     //  For the projection matrix, we set up a perspective transform (which
     //  transforms geometry from 3D view space to 2D viewport space, with
     //  a perspective divide making objects smaller in the distance). To build
     //  a perpsective transform, we need the field of view (1/4 pi is common),
     //  the aspect ratio, and the near and far clipping planes (which define at
     //  what distances geometry should be no longer be rendered).
     D3DXMATRIXA16 matProj;
    D3DXMatrixPerspectiveFovLH(  & matProj, D3DX_PI / 4 ,  800.0f   /   600.0f ,  1.0f ,  100.0f  );
    g_pd3dDevice -> SetTransform( D3DTS_PROJECTION,  & matProj );


}
 
 //  渲染场景
 void  Render()
  {
     if (g_pd3dDevice)
      {
        LPDIRECT3DSURFACE9 pRenderTarget;
         //  保存渲染表面
         g_pd3dDevice -> GetRenderTarget( 0  ,  & pRenderTarget);
         //  设置我们的贴图表面
         g_pd3dDevice -> SetRenderTarget( 0  , g_pRenderSurface);
         //  清空场景,渲染到贴图的背景是蓝色的
         g_pd3dDevice -> Clear( 0  ,  0  , D3DCLEAR_TARGET  |  D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB( 0  ,  0  ,  0xFF ) ,  1  ,  0 );
         //  开始渲染到贴图
          if (SUCCEEDED(g_pd3dDevice -> BeginScene()))
          {
             //  设置通常的矩阵
             SetTransform();
            D3DXMATRIX matWorld;
             //  旋转茶壶
             D3DXMatrixRotationAxis( & matWorld ,  & D3DXVECTOR3( 1  ,  0  , 1 ) , D3DX_PI  *   2.0f   *  (timeGetTime()  %   5000 )  /   5000.0f );
            g_pd3dDevice -> SetTransform(D3DTS_WORLD ,  & matWorld);

             //  设置渲染到表面的投影矩阵(这里可有可无,因为我们的窗口创建是512×512的)
             D3DXMATRIXA16 matProj;
            D3DXMatrixPerspectiveFovLH(  & matProj, D3DX_PI / 4 ,  1.0f ,  1.0f ,  100.0f  );
            g_pd3dDevice -> SetTransform( D3DTS_PROJECTION,  & matProj );

             //  设置贴图
             g_pd3dDevice -> SetTexture( 0  , g_pTexture);
            g_pd3dDevice -> SetSamplerState( 0  , D3DSAMP_ADDRESSU , D3DTADDRESS_MIRROR);
            g_pd3dDevice -> SetSamplerState( 0  , D3DSAMP_ADDRESSV , D3DTADDRESS_MIRROR);
             //  自动生成纹理坐标
             g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
            g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_SPHEREMAP);
            g_pd3dDevice -> SetRenderState(D3DRS_LIGHTING , FALSE);
             //  渲染茶壶
             g_pMeshTeapot -> DrawSubset( 0 );
            g_pd3dDevice -> EndScene();
        }
 
 
         //  恢复渲染表面为显示器
         g_pd3dDevice -> SetRenderTarget( 0  , pRenderTarget);

         //  清空场景,真实场景是红色背景的
         g_pd3dDevice -> Clear( 0  ,  0  , D3DCLEAR_TARGET  |  D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB( 0xFF  ,  0xFF  ,  0 ) ,  1  ,  0 );
         //  开始渲染真实场景
          if (SUCCEEDED(g_pd3dDevice -> BeginScene()))
          {
            SetTransform();
            D3DXMATRIX matWorld;
             //  旋转表面
             D3DXMatrixRotationAxis( & matWorld ,  & D3DXVECTOR3( 1  ,  1  , 0 ) , sinf(D3DX_PI  *   2.0f   *  (timeGetTime()  %   5000 )  /   5000.0f ));
             //  设置世界矩阵
             g_pd3dDevice -> SetTransform(D3DTS_WORLD ,  & matWorld);
             //  设置已经渲染到表面的贴图
             g_pd3dDevice -> SetTexture( 0  , g_pRenderTexture);
            g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2);
            g_pd3dDevice -> SetTextureStageState( 0 , D3DTSS_TEXCOORDINDEX,  0 );

            g_pd3dDevice -> SetSamplerState( 0  , D3DSAMP_ADDRESSU , D3DTADDRESS_MIRROR);
            g_pd3dDevice -> SetSamplerState( 0  , D3DSAMP_ADDRESSV , D3DTADDRESS_MIRROR);
            g_pd3dDevice -> SetRenderState(D3DRS_LIGHTING , FALSE);
             // g_pd3dDevice->SetRenderState(D3DRS_FILLMODE , D3DFILL_WIREFRAME);
             g_pd3dDevice -> SetStreamSource( 0  , g_pVB ,  0  ,  sizeof (CUSTOMVERTEX));
            g_pd3dDevice -> SetFVF(D3DFVF_CUSTOMVERTEX);
            g_pd3dDevice -> DrawPrimitive(D3DPT_TRIANGLESTRIP ,  0  ,  2 );
            g_pd3dDevice -> EndScene();
        }
         //  显示
         g_pd3dDevice -> Present( 0  ,  0  ,  0  ,  0 );
    }
}
 
 //  初始化 D3D 设备
 HRESULT InitD3D(HWND hWnd)
  {
     //  创建 D3D Driver
      if (NULL  ==  (g_pD3D  =  Direct3DCreate9(D3D_SDK_VERSION)))
      {
        D3DErr( " 无法创建Direct3D9设备 " );
         return  E_FAIL;
    }
     //  获取当前显示模式
     D3DDISPLAYMODE d3ddm;
     if (FAILED(g_pD3D -> GetAdapterDisplayMode(D3DADAPTER_DEFAULT ,  & d3ddm)))
      {
        D3DErr( " 无法获取D3D显示器模式 " );
         return  E_FAIL;
    }
 
    RECT rect;
    ::GetClientRect(hWnd ,  & rect);

     //  填充参数
     D3DPRESENT_PARAMETERS d3dpp;
    memset( & d3dpp ,  0  ,  sizeof (d3dpp));
    d3dpp.BackBufferFormat  =  d3ddm.Format;
    d3dpp.BackBufferWidth  =  rect.right;
    d3dpp.BackBufferHeight  =  rect.bottom;
    d3dpp.SwapEffect  =  D3DSWAPEFFECT_DISCARD;
    d3dpp.Windowed  =   true ;
    d3dpp.AutoDepthStencilFormat  =  D3DFMT_D16;
    d3dpp.EnableAutoDepthStencil  =  TRUE;

     //  获取帽子
      if (FAILED(g_pD3D -> GetDeviceCaps(D3DADAPTER_DEFAULT , D3DDEVTYPE_HAL ,  & g_Caps)))
      {
        D3DErr( " 获取D3D 帽子时发生错误 " );
         return  E_FAIL;
    }
 
     //  创建D3D设备
      if (FAILED(g_pD3D -> CreateDevice(D3DADAPTER_DEFAULT
        , D3DDEVTYPE_HAL
        , hWnd
         //  检查是否支持硬件顶点处理
         , g_Caps.DevCaps  &  D3DDEVCAPS_HWTRANSFORMANDLIGHT  ?  D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING
        ,  & d3dpp
        ,  & g_pd3dDevice
        )
        ))
      {
        D3DErr( " 创建D3D设备时发生错误 " );
         return  E_FAIL;
    }
    g_pd3dDevice -> SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
    g_pd3dDevice -> SetRenderState( D3DRS_ZENABLE, TRUE );

     if (FAILED(InitGeometry()))
         return  E_FAIL;
     return  S_OK;
}
 
 //  清空所有占用的资源
 void  CleanUp()
  {
    SAFE_RELEASE(g_pTexture);
    SAFE_RELEASE(g_pIB);
    SAFE_RELEASE(g_pVB);
    SAFE_RELEASE(g_pd3dDevice);
    SAFE_RELEASE(g_pD3D);
}
 
 
 //  消息处理
 LRESULT WINAPI MsgProc(HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
  {
     switch (message)
      {
     case  WM_DESTROY:
        CleanUp();
        PostQuitMessage( 0 );
         break ;
    }
     return  ::DefWindowProc(hWnd, message , wParam , lParam);
}
 
 //  Windows 入口
 int  WINAPI WinMain(IN HINSTANCE hInstance, IN HINSTANCE hPrevInstance, IN LPSTR lpCmdLine, IN  int  nShowCmd )
  {
    WNDCLASS wndClass;
    memset( & wndClass ,  0  ,  sizeof (wndClass));
    wndClass.hInstance  =  hInstance;
    wndClass.lpszClassName  =   " 渲染到纹理 " ;
    wndClass.lpfnWndProc  =  MsgProc;
    RegisterClass( & wndClass);

     //  创建窗口
     HWND hWnd  =  CreateWindow( " 渲染到纹理 "  ,  " 渲染到纹理! " 
        ,  0  ,  0  ,  0  ,  640  , 480  , GetDesktopWindow()
        ,  0  , wndClass.hInstance ,  0 );
     //  显示窗口
     ShowWindow(hWnd , SW_SHOWDEFAULT);
    UpdateWindow(hWnd);

     //  初始化 D3D 设备
      if (SUCCEEDED(InitD3D(hWnd)))
      {
         //  消息处理循环
         MSG msg;
        memset( & msg ,  0  ,  sizeof (msg));
         while (msg.message  !=  WM_QUIT)
          {
             if (PeekMessage( & msg ,  0  ,  0  ,  0  , PM_REMOVE))
              {
                TranslateMessage( & msg);
                DispatchMessage( & msg);
            }
             else
               {
                Render();
            }
        }
    }
     //  清空场景
     CleanUp();

    UnregisterClass( " 渲染到纹理 "  , wndClass.hInstance);

     return   0 ;
}

原创粉丝点击