Direct3D中的绘制(3)

Direct3D中的绘制(3)

立方体——只比三角形稍微复杂一点,这个程序渲染一个线框立方体。

这个简单的绘制和渲染立方体的程序的运行结果如下图所示:

Direct3D中的绘制(3)_第1张图片

 

源程序:

/* *************************************************************************************
  Renders a spinning cube in wireframe mode.  Demonstrates vertex and index buffers, 
  world and view transformations, render states and drawing commands.
 *************************************************************************************
*/

#include 
" d3dUtility.h "

#pragma warning(disable : 
4100 )

const   int  WIDTH   =   640 ;
const   int  HEIGHT  =   480 ;

IDirect3DDevice9
*         g_d3d_device     =  NULL;
IDirect3DVertexBuffer9
*     g_vertex_buffer  =  NULL;
IDirect3DIndexBuffer9
*     g_index_buffer     =  NULL;

class  cVertex
{
public :
    
float  m_x, m_y, m_z;

    cVertex() {}

    cVertex(
float  x,  float  y,  float  z)
    {
        m_x 
=  x;
        m_y 
=  y;
        m_z 
=  z;
    }
};

const  DWORD VERTEX_FVF  =  D3DFVF_XYZ;

/////////////////////////////////////////////////////////////////////////////////////////////////// /

bool  setup()
{    
    g_d3d_device
-> CreateVertexBuffer( 8   *   sizeof (cVertex), D3DUSAGE_WRITEONLY, VERTEX_FVF, 
                                     D3DPOOL_MANAGED, 
& g_vertex_buffer, NULL);

    g_d3d_device
-> CreateIndexBuffer( 36   *   sizeof (WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
                                    D3DPOOL_MANAGED, 
& g_index_buffer, NULL);

    
//  fill the buffers with the cube data

    cVertex
*  vertices;
    g_vertex_buffer
-> Lock( 0 0 , ( void ** ) & vertices,  0 );
    
    
//  vertices of a unit cube
    vertices[ 0 =  cVertex( - 1.0f - 1.0f - 1.0f );
    vertices[
1 =  cVertex( - 1.0f ,   1.0f - 1.0f );
    vertices[
2 =  cVertex(  1.0f ,   1.0f - 1.0f );
    vertices[
3 =  cVertex(  1.0f - 1.0f - 1.0f );
    vertices[
4 =  cVertex( - 1.0f - 1.0f ,   1.0f );
    vertices[
5 =  cVertex( - 1.0f ,   1.0f ,   1.0f );
    vertices[
6 =  cVertex(  1.0f ,   1.0f ,   1.0f );
    vertices[
7 =  cVertex(  1.0f - 1.0f ,   1.0f );

    g_vertex_buffer
-> Unlock();

    
//  define the triangles of the cube
    WORD *  indices  =  NULL;
    g_index_buffer
-> Lock( 0 0 , ( void ** ) & indices,  0 );

    
//  front side
    indices[ 0 ]   =   0 ; indices[ 1 ]   =   1 ; indices[ 2 ]   =   2 ;
    indices[
3 ]   =   0 ; indices[ 4 ]   =   2 ; indices[ 5 ]   =   3 ;

    
//  back side
    indices[ 6 ]   =   4 ; indices[ 7 ]   =   6 ; indices[ 8 ]   =   5 ;
    indices[
9 ]   =   4 ; indices[ 10 =   7 ; indices[ 11 =   6 ;

    
//  left side
    indices[ 12 =   4 ; indices[ 13 =   5 ; indices[ 14 =   1 ;
    indices[
15 =   4 ; indices[ 16 =   1 ; indices[ 17 =   0 ;

    
//  right side
    indices[ 18 =   3 ; indices[ 19 =   2 ; indices[ 20 =   6 ;
    indices[
21 =   3 ; indices[ 22 =   6 ; indices[ 23 =   7 ;

    
//  top
    indices[ 24 =   1 ; indices[ 25 =   5 ; indices[ 26 =   6 ;
    indices[
27 =   1 ; indices[ 28 =   6 ; indices[ 29 =   2 ;

    
//  bottom
    indices[ 30 =   4 ; indices[ 31 =   0 ; indices[ 32 =   3 ;
    indices[
33 =   4 ; indices[ 34 =   3 ; indices[ 35 =   7 ;

    g_index_buffer
-> Unlock();

    
//  position and aim the camera

    D3DXVECTOR3 position(
0.0f 0.0f - 5.0f );
    D3DXVECTOR3 target(
0.0f 0.0f 0.0f );
    D3DXVECTOR3 up(
0.0f 1.0f 0.0f );

    D3DXMATRIX view_matrix;
    D3DXMatrixLookAtLH(
& view_matrix,  & position,  & target,  & up);

    g_d3d_device
-> SetTransform(D3DTS_VIEW,  & view_matrix);

    
//  set the projection matrix
    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(
& proj, D3DX_PI  *   0.5f , ( float )WIDTH / HEIGHT,  1.0f 1000.0f );
    g_d3d_device
-> SetTransform(D3DTS_PROJECTION,  & proj);

    
//  set wireframe mode render state
    g_d3d_device -> SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

    
return   true ;
}

void  cleanup()
{
    safe_release
< IDirect3DVertexBuffer9 *> (g_vertex_buffer);
    safe_release
< IDirect3DIndexBuffer9 *> (g_index_buffer);
}

bool  display( float  time_delta)
{
    
//  spin the cube

    D3DXMATRIX rx, ry;

    
//  rotate 45 degree on x-axis
    D3DXMatrixRotationX( & rx,  3.14f / 4.0f );

    
//  increment y-rotation angle each frame
     static   float  y  =   0.0f ;
    D3DXMatrixRotationY(
& ry, y);
    y 
+=  time_delta;

    
//  reset angle to zero when angle reaches 2*PI
     if (y  >=   6.28f )
        y 
=   0.0f ;

    
//  combine x and y axis ratation transformations
    D3DXMATRIX rxy  =  rx  *  ry;

    g_d3d_device
-> SetTransform(D3DTS_WORLD,  & rxy);

    
//  draw the scene

    g_d3d_device
-> Clear( 0 , NULL, D3DCLEAR_TARGET  |  D3DCLEAR_ZBUFFER,  0xffffffff 1.0f 0 );

    g_d3d_device
-> BeginScene();

    g_d3d_device
-> SetStreamSource( 0 , g_vertex_buffer,  0 sizeof (cVertex));
    g_d3d_device
-> SetIndices(g_index_buffer);
    g_d3d_device
-> SetFVF(VERTEX_FVF);

    
//  draw cube
    g_d3d_device -> DrawIndexedPrimitive(D3DPT_TRIANGLELIST,  0 0 8 0 12 );

    g_d3d_device
-> EndScene();

    g_d3d_device
-> Present(NULL, NULL, NULL, NULL);

    
return   true ;
}

LRESULT CALLBACK wnd_proc(HWND hwnd, UINT msg, WPARAM word_param, LPARAM long_param)
{
    
switch (msg)
    {
    
case  WM_DESTROY:
        PostQuitMessage(
0 );
        
break ;

    
case  WM_KEYDOWN:
        
if (word_param  ==  VK_ESCAPE)
            DestroyWindow(hwnd);
        
break ;
    }

    
return  DefWindowProc(hwnd, msg, word_param, long_param);
}

int  WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line,  int  cmd_show)
{
    
if ( !  init_d3d(inst, WIDTH, HEIGHT,  true , D3DDEVTYPE_HAL,  & g_d3d_device))
    {
        MessageBox(NULL, 
" init_d3d() - failed. " 0 , MB_OK);
        
return   0 ;
    }

    
if ( !  setup())
    {
        MessageBox(NULL, 
" Steup() - failed. " 0 , MB_OK);
        
return   0 ;
    }

    enter_msg_loop(display);

    cleanup();
    g_d3d_device
-> Release();

    
return   0 ;
}

 

setup函数创建顶点和索引缓存,锁定它们,把构成立方体的顶点写入顶点缓存,以及把定义立方体的三角形的索引写入索引缓存。然后把摄象机向后移动几个单位以便我们能够看见在世界坐标系中原点处被渲染的立方体。

 

display方法有两个任务;它必须更新场景并且紧接着渲染它。既然想旋转立方体,那么我们将对每一帧增加一个角度使立方体能在这一帧旋转。对于这每一帧,立方体将被旋转一个很小的角度,这样我们看起来旋转就会更平滑。接着我们使用IDirect3DDevice9::DrawIndexedPrimitive方法来绘制立方体。

 

最后,我们释放使用过的所有内存。这意味着释放顶点和索引缓存接口。

 

下载立方体演示程序


你可能感兴趣的:(Direct3D中的绘制(3))