Chinaunix首页 | 论坛 | 博客
  • 博客访问: 375210
  • 博文数量: 37
  • 博客积分: 6000
  • 博客等级: 准将
  • 技术积分: 1266
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-16 19:52
文章分类

全部博文(37)

文章存档

2011年(1)

2010年(7)

2009年(12)

2008年(17)

我的朋友

分类: C/C++

2008-06-20 16:12:44

 #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 ;
}
阅读(2072) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~