天行健 君子当自强而不息

创建游戏内核(13)【接口与实现分离版】

 

本篇是创建游戏内核(12)【接口与实现分离版】的续篇,关于该内核的细节说明请参考创建游戏内核(13),这个版本主要是按照功能划分模块的思想,并严格按照接口与实现相分离的原则来写的,没有用面向对象的思想来写,没有继承没有多态。大家可以对比两个版本,比较优劣。


接口:

/*************************************************************************
PURPOSE:
    Interface for D3D mesh and animation fucnton.
*************************************************************************/


#ifndef _CORE_MESH_ANIMATION_H_
#define _CORE_MESH_ANIMATION_H_

#include "core_common.h"
#include "core_graphics.h"

typedef 
void* MESH;
typedef MESH* MESH_PTR;

MESH create_mesh();
void destroy_mesh(MESH mesh);
BOOL load_mesh(MESH mesh, 
const char* filename, const char* texture_path);
BOOL draw_mesh(MESH mesh);

BOOL is_mesh_loaded(MESH mesh);
long get_num_frames(MESH mesh);

void get_mesh_bounds(MESH mesh,
                     
float* min_x, float* min_y, float* min_z, 
                     
float* max_x, float* max_y, float* max_z, 
                     
float* radius);

#endif
 

实现:

/***********************************************************************************
PURPOSE:
    Implement for D3D mesh and animation fucnton.
***********************************************************************************/


#include "core_common.h"
#include "core_mesh_animation.h"
#include "RmxfTmpl.h"
#include "RmxfGuid.h"

/////////////////////////////////// defines for mesh information ///////////////////////////////////

typedef 
struct _MESH_INFO
{
    
char*               name;               // name of mesh

    ID3DXMesh*          d3d_mesh;           
// D3D mesh object
    ID3DXMesh*          d3d_skin_mesh;      // D3D skin mesh object
    ID3DXSkinInfo*      d3d_skin_info;      // D3D skin mesh information

    DWORD               num_materials;      
// number of materials in mesh
    D3DMATERIAL9*       materials;          // array of materials
    LPDIRECT3DTEXTURE9* textures;           // array of texture pointers

    D3DXVECTOR3         min, max;           
// bounding box
    float               radius;             // bounding sphere radius

    _MESH_INFO*         next;               
// pointer to next mesh information
} *_MESH_INFO_PTR;

//------------------------------------------------------------------------------------
// Create a new mesh informatio object.
//------------------------------------------------------------------------------------
static _MESH_INFO_PTR _create_mesh_info()
{
    _MESH_INFO_PTR _mesh_info = (_MESH_INFO_PTR) malloc(
sizeof(_MESH_INFO));

    memset(_mesh_info, 0, 
sizeof(_MESH_INFO));

    
return _mesh_info;
}

//------------------------------------------------------------------------------------
// Destroy all mesh information object, recursively call.
//------------------------------------------------------------------------------------
static void _destroy_mesh_info(_MESH_INFO_PTR _mesh_info)
{
    
if(_mesh_info == NULL || _mesh_info->next == NULL)
        
return;

    release_com(_mesh_info->d3d_mesh);
    release_com(_mesh_info->d3d_skin_mesh);
    release_com(_mesh_info->d3d_skin_info);

    free(_mesh_info->name);
    free(_mesh_info->materials);

    
if(_mesh_info->textures)
    {
        
for(DWORD i = 0; i < _mesh_info->num_materials; i++)
            release_com(_mesh_info->textures[i]);

        free(_mesh_info->textures);
    }

    _destroy_mesh_info(_mesh_info->next);
}

//------------------------------------------------------------------------------------
// Find mesh information with specified name, call recusively.
//------------------------------------------------------------------------------------
static _MESH_INFO_PTR _find_mesh_info(const _MESH_INFO_PTR mesh_info, const char* name)
{
    
// return current mesh information if name is NULL
    if(mesh_info == NULL || name == NULL)
        
return mesh_info;

    
// compare names and return if exact match
    if(mesh_info->name && STREQ(mesh_info->name, name))
        
return mesh_info;

    
// search next in list
    if(mesh_info->next)
    {
        _MESH_INFO_PTR _mesh_info;

        
// recursively call
        if((_mesh_info = _find_mesh_info(mesh_info, name)) != NULL)
            
return _mesh_info;
    }

    
return NULL;
}

/////////////////////////////////// defines for frame information ///////////////////////////////////

typedef 
struct _FRAME
{
    
char*           name;               // frame name
    _MESH_INFO_PTR  mesh_info;          // list of mesh information attached to this frame

    D3DXMATRIX      mat_combined;       
// combined transformation matrix
    D3DXMATRIX      mat_transformed;    // currently transformed matrix
    D3DXMATRIX      mat_original;       // original .x file matrix

    _FRAME*         parent;             
// pointer to parent frame
    _FRAME*         child;              // pointer to child frame
    _FRAME*         sibling;            // pointer to silbing frame
} *_FRAME_PTR;

//------------------------------------------------------------------------------------
// Create a new frame.
//------------------------------------------------------------------------------------
static _FRAME_PTR _create_frame()
{
    _FRAME_PTR _frame = (_FRAME_PTR) malloc(
sizeof(_FRAME));
    
    memset(_frame, 0, 
sizeof(_FRAME));

    
return _frame;
}

//------------------------------------------------------------------------------------
// Destroy frame object.
//------------------------------------------------------------------------------------
static void _destroy_frame(_FRAME_PTR frame)
{
    free(frame->name);
    free(frame->child);
    free(frame->sibling);
}

//------------------------------------------------------------------------------------
// Find frame with specified name, call recursively.
//------------------------------------------------------------------------------------
static _FRAME_PTR _find_frame(const _FRAME_PTR frame, const char* name)
{
    
// return current frame if name is NULL
    if(frame == NULL || name == NULL)
        
return frame;

    
// compare names and return if exact match
    if(frame->name && STREQ(frame->name, name))
        
return frame;

    _FRAME_PTR _frame;

    
// search child list, recursively call.
    if(frame->child)
    {
        
if((_frame = _find_frame(frame->child, name)) != NULL)
            
return _frame;
    }

    
// search sibling list, recursively call.
    if(frame->sibling)
    {
        
if((_frame = _find_frame(frame->sibling, name)) != NULL)
            
return _frame;
    }

    
return NULL;
}

//------------------------------------------------------------------------------------
// Reset frame transformed matrices to original matrices, recursively call.
//------------------------------------------------------------------------------------
static void _reset_frame_matrices(const _FRAME_PTR frame)
{
    frame->mat_transformed = frame->mat_original;

    
if(frame->child)
        _reset_frame_matrices(frame->child);

    
if(frame->sibling)
        _reset_frame_matrices(frame->sibling);
}

//------------------------------------------------------------------------------------
// Add mesh to frame.
//------------------------------------------------------------------------------------
static void _add_mesh_info_to_frame(_FRAME_PTR frame, const _MESH_INFO_PTR mesh_info)
{    
    mesh_info->next  = frame->mesh_info;
    frame->mesh_info = mesh_info;
}

/////////////////////////////////// defines for mesh ////////////////////////////////

typedef 
struct _MESH
{
    
long            num_mesh_info;  // number of mesh information
    _MESH_INFO_PTR  mesh_info;      // mesh information list

    
long            num_frame;      // number of frames
    _FRAME_PTR      frame;          // frame list

    D3DXVECTOR3     min;            
// the lower-left corner of the bounding box
    D3DXVECTOR3     max;            // the upper-right corner of the bounding box
    float           radius;         // bounding box radius
} *_MESH_PTR;

//-------------------------------------------------------------------
// Return root mesh information.
//-------------------------------------------------------------------
static _MESH_INFO_PTR _get_root_mesh_info(_MESH_PTR mesh)
{
    
return mesh->mesh_info;
}

//-------------------------------------------------------------------
// Return mesh whih spefied name.
//-------------------------------------------------------------------
static _MESH_INFO_PTR _get_mesh_info(_MESH_PTR mesh, const char* name)
{
    
if(mesh->mesh_info == NULL)
        
return NULL;

    
return _find_mesh_info(mesh->mesh_info, name);
}

//-------------------------------------------------------------------
// Parse specified xfile data, recursive function.
//-------------------------------------------------------------------
static void _parse_xfile_data(_MESH_PTR mesh, ID3DXFileData* xfile_data, 
                              _FRAME_PTR parent_frame, 
const char* texture_path)
{
    
// get the template type

    GUID _type;

    
// retrieve the globally unique identifier (GUID) of the object's template
    if(FAILED(xfile_data->GetType(&_type)))
        
return;

    
// get the template name (if any)

    DWORD _size;

    
if(FAILED(xfile_data->GetName(NULL, &_size)))
        
return;

    
char* _name = NULL;

    
if(_size != 0)
    {
        
if((_name = (char*) malloc(_size)) != NULL)
            xfile_data->GetName(_name, &_size);
    }

    
// give template a default name if none found
    if(_name == NULL)
    {
        
if((_name = (char*) malloc(9)) == NULL)
            
return;

        strcpy(_name, "$NoName$");
    }

    
// set current frame
    _FRAME_PTR _current_frame = parent_frame;

    
// process the templates

    
if(_type == TID_D3DRMFrame)     // it is a frame
    {
        
// create a new frame
        _FRAME_PTR _frame = _create_frame();

        
// store the name
        _frame->name = _name;
        _name = NULL;

        
// link to parent frame
        _frame->parent      = parent_frame;
        _frame->sibling     = parent_frame->child;
        parent_frame->child = _frame;

        
// increase frame count
        mesh->num_frame++;

        
// set current frame with new frame
        _current_frame = _frame;
    }
    
else if(_type == TID_D3DRMFrameTransformMatrix)  // it is a frame transformation matrix
    {
        D3DXMATRIX* _frame_matrix = NULL;

        
// get frame transformation matrix
        if(FAILED(xfile_data->Lock(&_size, (LPCVOID*) &_frame_matrix)))
            
return;

        
// set original matrix
        parent_frame->mat_original = *_frame_matrix;

        xfile_data->Unlock();
    }
    
else if(_type == TID_D3DRMMesh)     // it is a mesh
    {
        ID3DXBuffer*    _material_buffer = NULL;
        ID3DXBuffer*    _adjacency = NULL;
        _MESH_INFO_PTR  _mesh_info = NULL;

        
// see if mesh already loaded
        if(mesh->mesh_info == NULL || _find_mesh_info(mesh->mesh_info, _name) == NULL)
        {
            
// create a new mesh structure
            _mesh_info = _create_mesh_info();

            
// store the name
            _mesh_info->name = _name;
            _name = NULL;

            
// load mesh data
            if(FAILED(D3DXLoadSkinMeshFromXof(xfile_data, 0, g_d3d_device, &_adjacency, &_material_buffer, NULL,
                &_mesh_info->num_materials, &_mesh_info->d3d_skin_info, &_mesh_info->d3d_mesh)))
            {
                free(_name);
                free(_mesh_info);
                
return;
            }

            BYTE* _ptr;

            
// calcualte the bounding box and sphere
            if(SUCCEEDED(_mesh_info->d3d_mesh->LockVertexBuffer(D3DLOCK_READONLY, (void**) &_ptr)))
            {
                DWORD _num_vertices = _mesh_info->d3d_mesh->GetNumVertices();
                DWORD _num_bytes_per_vertex = _mesh_info->d3d_mesh->GetNumBytesPerVertex();

                
// computes a coordinate-axis oriented bouding box
                D3DXComputeBoundingBox((D3DXVECTOR3*) _ptr, _num_vertices, _num_bytes_per_vertex, 
                    &_mesh_info->min, &_mesh_info->max);

                
// computes a bounding sphere for the mesh
                D3DXComputeBoundingSphere((D3DXVECTOR3*) _ptr, _num_vertices, _num_bytes_per_vertex, 
                    &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &_mesh_info->radius);

                _mesh_info->d3d_mesh->UnlockVertexBuffer();
            }

             
// create a matching skinned mesh if bone exist
            if(_mesh_info->d3d_skin_info && _mesh_info->d3d_skin_info->GetNumBones() != 0)
            {
                
// clone a mesh using a flexible vertex format (FVF) code
                if(FAILED(_mesh_info->d3d_mesh->CloneMeshFVF(0, _mesh_info->d3d_mesh->GetFVF(), g_d3d_device,
                    &_mesh_info->d3d_skin_mesh)))
                {
                    release_com(_mesh_info->d3d_skin_info);
                }
            }

            
// load materials or create a default one if none
            if(_mesh_info->num_materials == 0)
            {
                
// create a default one
                _mesh_info->materials = (D3DMATERIAL9*) malloc(sizeof(D3DMATERIAL9));
                _mesh_info->textures  = (LPDIRECT3DTEXTURE9*) malloc(
sizeof(LPDIRECT3DTEXTURE9));

                memset(_mesh_info->materials, 0, 
sizeof(D3DMATERIAL9));

                _mesh_info->materials[0].Diffuse.r = 1.0f;
                _mesh_info->materials[0].Diffuse.g = 1.0f;
                _mesh_info->materials[0].Diffuse.b = 1.0f;
                _mesh_info->materials[0].Diffuse.a = 1.0f;
                _mesh_info->materials[0].Ambient   = _mesh_info->materials[0].Diffuse;
                _mesh_info->materials[0].Specular  = _mesh_info->materials[0].Diffuse;

                _mesh_info->textures[0] = NULL;

                _mesh_info->num_materials = 1;
            }
            
else
            {
                
// load the materials
                D3DXMATERIAL* _x_materials = (D3DXMATERIAL*) _material_buffer->GetBufferPointer();

                _mesh_info->materials = (D3DMATERIAL9*) malloc(
sizeof(D3DMATERIAL9) * _mesh_info->num_materials);

                _mesh_info->textures  = (LPDIRECT3DTEXTURE9*) 
                                        malloc(
sizeof(LPDIRECT3DTEXTURE9) * _mesh_info->num_materials);

                
char _path[MAX_PATH];

                
for(DWORD i = 0; i < _mesh_info->num_materials; i++)
                {
                    _mesh_info->materials[i] = _x_materials[i].MatD3D;
                    _mesh_info->materials[i].Ambient = _mesh_info->materials[i].Diffuse;

                    
// build a texture path and load it
                    sprintf(_path, "%s%s", texture_path, _x_materials[i].pTextureFilename);

                    
// create texture from file
                    if(FAILED(D3DXCreateTextureFromFile(g_d3d_device, _path, &_mesh_info->textures[i])))
                        _mesh_info->textures[i] = NULL;
                }
            }

            release_com(_material_buffer);
            release_com(_adjacency);

            
// link to mesh information list
            _mesh_info->next = mesh->mesh_info;
            mesh->mesh_info  = _mesh_info;
            mesh->num_mesh_info++;
        }
        
else
            
// find mesh information in list
            _mesh_info = _find_mesh_info(mesh->mesh_info, _name);

        
// add mesh information to current frame
        if(_mesh_info)
            _add_mesh_info_to_frame(_current_frame, _mesh_info);
    }   
// end if(_type == TID_D3DRMMesh)
    else if(_type == TID_D3DRMAnimationSet || _type == TID_D3DRMAnimation || _type == TID_D3DRMAnimationKey)
    {
        
// skip animation sets and animations
        free(_name);
        
return;
    }

    free(_name);

    ID3DXFileData* _child_xfile_data = NULL;
    SIZE_T _num_child;

    xfile_data->GetChildren(&_num_child);

    
// scan for embedded templates
    for(SIZE_T i = 0; i < _num_child; i++)
    {
        xfile_data->GetChild(i, &_child_xfile_data);

        
// parse child xfile data object
        _parse_xfile_data(mesh, _child_xfile_data, _current_frame, texture_path);

        release_com(_child_xfile_data);
    }
}

//-------------------------------------------------------------------
// Draw frame, recursively call.
//-------------------------------------------------------------------
static BOOL _draw_frame(_FRAME_PTR frame)
{
    D3DXMATRIX*     _matrices = NULL;
    ID3DXMesh*      _d3d_mesh_to_draw;
    _MESH_INFO_PTR  _mesh_info;

    
// return if no frame
    if(frame == NULL)
        
return FALSE;

    
if(frame->mesh_info)
    {
        
// draw mesh if any in frame
        if((_mesh_info = frame->mesh_info) != NULL)
        {
            
// setup pointer to mesh to draw
            _d3d_mesh_to_draw = _mesh_info->d3d_mesh;

            
// generate mesh from skinned mesh to draw with
            if(_mesh_info->d3d_skin_mesh && _mesh_info->d3d_skin_info)
            {
                DWORD _num_bones = _mesh_info->d3d_skin_info->GetNumBones();

                
// allocate an array of matrices to orient bones
                _matrices = (D3DXMATRIX *) malloc(sizeof(D3DXMATRIX) * _num_bones);

                
// set all bones to orientation to identity
                for(DWORD i = 0; i < _num_bones; i++)
                    D3DXMatrixIdentity(&_matrices[i]);

                
// lock source and destination vertex buffers

                
void* _source = NULL;
                
void* _dest = NULL;

                
// locks a vertex buffer and obtains a pointer to the vertex buffer memory
                _mesh_info->d3d_mesh->LockVertexBuffer(0, &_source);
                _mesh_info->d3d_skin_mesh->LockVertexBuffer(0, &_dest);

                
// update skinned mesh, applies software skinning to the target vertices based on the current matrices.
                _mesh_info->d3d_skin_info->UpdateSkinnedMesh(_matrices, NULL, _source, _dest);

                
// unlock buffers
                _mesh_info->d3d_mesh->UnlockVertexBuffer();
                _mesh_info->d3d_skin_mesh->UnlockVertexBuffer();

                
// pointer to skin mesh to draw
                _d3d_mesh_to_draw = _mesh_info->d3d_skin_mesh;
            }

            
// render the mesh
            for(DWORD i = 0; i < _mesh_info->num_materials; i++)
            {
                
// set the materials properties for the device
                g_d3d_device->SetMaterial(&_mesh_info->materials[i]);

                
// assign a texture to a stage for a device
                g_d3d_device->SetTexture(0, _mesh_info->textures[i]);

                
// draw a subset of a mesh
                _d3d_mesh_to_draw->DrawSubset(i);
            }

            
// free array of matrices
            free(_matrices);
            _matrices = NULL;
        }
    }

    
// draw child frames, recursively call.
    _draw_frame(frame->child);

    
return TRUE;
}

//-------------------------------------------------------------------
// Create mesh object.
//-------------------------------------------------------------------
MESH create_mesh()
{
    _MESH_PTR _mesh = (_MESH_PTR) malloc(
sizeof(_MESH));

    memset(_mesh, 0, 
sizeof(_MESH));

    
return (MESH) _mesh;
}

//-------------------------------------------------------------------
// Destroy all meshes and frames.
//-------------------------------------------------------------------
void destroy_mesh(MESH mesh)
{
    _MESH_PTR _mesh = (_MESH_PTR) mesh;

    _destroy_mesh_info(_mesh->mesh_info);
    _destroy_frame(_mesh->frame);
}

//-------------------------------------------------------------------
// load .x file from specified filename.
//-------------------------------------------------------------------
BOOL load_mesh(MESH mesh, const char* filename, const char* texture_path)
{
    
// check condition
    if(g_d3d_device == NULL || filename == NULL)
        
return FALSE;

    _MESH_PTR _mesh = (_MESH_PTR) mesh;

    ID3DXFile* _xfile = NULL;

    
// create the file object
    if(FAILED(D3DXFileCreate(&_xfile)))
        
return FALSE;

    
// register the templates
    if(FAILED(_xfile->RegisterTemplates((LPVOID) D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES)))
    {
        _xfile->Release();
        
return FALSE;
    }
    
    ID3DXFileEnumObject* _xfile_enum = NULL;

    
// create an enumeration object
    if(FAILED(_xfile->CreateEnumObject((LPVOID) filename, DXFILELOAD_FROMFILE, &_xfile_enum)))
    {
        _xfile->Release();
        
return FALSE;
    }

    
// create a frame
    _FRAME_PTR _frame = _create_frame();

    ID3DXFileData* _xfile_data = NULL;
    SIZE_T _num_child;

    
// retrieve the number of children in this file data object
    _xfile_enum->GetChildren(&_num_child);

    
// loop through all objects looking for the frames and meshes
    for(SIZE_T i = 0; i < _num_child; i++)
    {
        
if(FAILED(_xfile_enum->GetChild(i, &_xfile_data)))
            
return FALSE;

        
// parse xfile data
        _parse_xfile_data(_mesh, _xfile_data, _frame, texture_path);

        release_com(_xfile_data);
    }
    
    release_com(_xfile_enum);
    release_com(_xfile);

    
// see if we should keep the frame as root
    if(_frame->mesh_info)
    {
        _mesh->frame = _frame;

        _mesh->frame->name = (
char*) malloc(7);
        strcpy(_mesh->frame->name, "%ROOT%");
    }
    
else
    {
        
// Ok, now there is no any mesh in this frame, assign child frame as the root frame and release this frame.

        _mesh->frame = _frame->child;
        _FRAME_PTR _frame_ptr = _mesh->frame;

        
// reset all child frames of this frame, only under one level.
        while(_frame_ptr)
        {
            _frame_ptr->parent = NULL;
            _frame_ptr = _frame_ptr->sibling;
        }

        _frame->child = NULL;
        free(_frame);
    }

    _MESH_INFO* _mesh_info;

    
// calculate bounding box and sphere
    if((_mesh_info = _mesh->mesh_info) != NULL)
    {
        
while(_mesh_info)
        {
            
// set the lower-left corner of the bounding box as the most lower-left corner 
            // of all meshes's bounding box
            _mesh->min.x = min(_mesh->min.x, _mesh_info->min.x);
            _mesh->min.y = min(_mesh->min.y, _mesh_info->min.y);
            _mesh->min.z = min(_mesh->min.z, _mesh_info->min.z);

            
// set the upper-right corner of the bounding box as the most upper-right corner 
            // of all meshes's bounding box
            _mesh->max.x = min(_mesh->max.x, _mesh_info->max.x);
            _mesh->max.y = min(_mesh->max.y, _mesh_info->max.y);
            _mesh->max.z = min(_mesh->max.z, _mesh_info->max.z);
            
            
// set bounding box radius as max radius of all meshes
            _mesh->radius = max(_mesh->radius, _mesh_info->radius);

            _mesh_info = _mesh_info->next;
        }
    }

    
return TRUE;
}

//-----------------------------------------------------------------------------
// Draw mesh, call recursively.
//-----------------------------------------------------------------------------
BOOL draw_mesh(MESH mesh)
{
    
return _draw_frame(((_MESH_PTR) mesh)->frame);
}

//-------------------------------------------------------------------
// Judge whether the mesh has been loaded successfully.
//-------------------------------------------------------------------
BOOL is_mesh_loaded(MESH mesh)
{
    _MESH_PTR _mesh = (_MESH_PTR) mesh;

    
return (_mesh->mesh_info && _mesh->frame);
}

//-------------------------------------------------------------------
// Get number of frame.
//-------------------------------------------------------------------
long get_num_frames(MESH mesh)
{
    
return ((_MESH_PTR) mesh)->num_frame;
}

//-------------------------------------------------------------------
// Get bound box coordiante and radius.
//-------------------------------------------------------------------
void get_mesh_bounds(MESH mesh,
                     
float* min_x, float* min_y, float* min_z, 
                     
float* max_x, float* max_y, float* max_z, 
                     
float* radius)
{
    _MESH_PTR _mesh = (_MESH_PTR) mesh;

    
if(min_x != NULL)   *min_x = _mesh->min.x;
    
if(min_y != NULL)   *min_y = _mesh->min.y;
    
if(min_z != NULL)   *min_z = _mesh->min.z;

    
if(max_x != NULL)   *max_x = _mesh->max.x;
    
if(max_y != NULL)   *max_y = _mesh->max.z;
    
if(max_z != NULL)   *max_z = _mesh->max.z;

    
if(radius != NULL)  *radius = _mesh->radius;
}
 

测试代码:

/***********************************************************************************
PURPOSE:
    Test for mesh function.
***********************************************************************************/


#include <windows.h>
#include "core_framework.h"
#include "core_graphics.h"
#include "core_tool.h"
#include "core_mesh_animation.h"

MESH g_mesh;

//--------------------------------------------------------------------------------
// Initialize data for game.
//--------------------------------------------------------------------------------
BOOL game_init()
{
    
// Create Direct3D and Direct3DDevice object
    if(! create_display(g_hwnd, get_client_width(g_hwnd), get_client_height(g_hwnd), 16, TRUE, FALSE))
        
return FALSE;    

    
// set perspective projection transform matrix
    set_perspective(D3DX_PI/4.0f, 1.33333f, 1.0f, 1000.0f);

    D3DXMATRIX _mat_view;

    
// create and set the view matrix
    D3DXMatrixLookAtLH(&_mat_view,
                       &D3DXVECTOR3(0.0, 50.0, -150.0),
                       &D3DXVECTOR3(0.0, 50.0,  0.0), 
                       &D3DXVECTOR3(0.0, 1.0,   0.0));

    g_d3d_device->SetTransform(D3DTS_VIEW, &_mat_view);

    g_mesh = create_mesh();

    
if(! load_mesh(g_mesh, "warrior.x", ".\\"))
        
return FALSE;

    
return TRUE;
}

//--------------------------------------------------------------------------------
// Render every game frame.
//--------------------------------------------------------------------------------
BOOL game_frame()
{
    clear_display_buffer(D3DCOLOR_RGBA(0, 0, 0, 255));

    
if(SUCCEEDED(g_d3d_device->BeginScene()))
    {
        D3DXMATRIX _mat_world;

        
// create and set the world transformation matrix
        // rotate object along z-axis
        D3DXMatrixRotationY(&_mat_world, (float) (timeGetTime() / 1000.0));

        g_d3d_device->SetTransform(D3DTS_WORLD, &_mat_world);

        
// draw mesh
        draw_mesh(g_mesh);        

        g_d3d_device->EndScene();
    }

    present_display();

    
return TRUE;
}

//--------------------------------------------------------------------------------
// Release all game resources.
//--------------------------------------------------------------------------------
BOOL game_shutdown()
{
    destroy_mesh(g_mesh);

    release_com(g_d3d_device);
    release_com(g_d3d);

    
return TRUE;
}

//--------------------------------------------------------------------------------
// Main function, routine entry.
//--------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE inst, HINSTANCE pre_inst, LPSTR cmd_line, int cmd_show)
{    
    
if(! build_window(inst, "MainClass", "MainWindow", WS_OVERLAPPEDWINDOW, 0, 0, 640, 480))
        
return FALSE;

    run_game(game_init, game_frame, game_shutdown);
    
    
return 0;
}
 

点击下载源码和工程

程序截图:


posted on 2007-10-05 01:14 lovedday 阅读(385) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

导航

统计

常用链接

随笔分类(178)

3D游戏编程相关链接

搜索

最新评论