2014年7月8日星期二(DEMO8-8加载3DSMAX ASCII格式模型.ASC)

来源:互联网 发布:淘宝买家具哪个品牌好 编辑:程序博客网 时间:2024/06/08 07:41

1读取物体名,顶点数和多边形数

2读取顶点列表

3读取每个多边形的定义及其RGB材质颜色信息

缺点是:不能指定多边形是单面还是双面的,不支持纹理映射信息和光照模型信息等,只提供了每个多边形的颜色。

定义了几个值

 

#defineOBJECT4DV1_MAX_VERTICES               1024

#defineOBJECT4DV1_MAX_POLYS                           1024

 

//根据坐标系改变或者朝向改变,作如下

#define VERTEX_FLAGS_INVERT_X               1    //反转X

#define VERTEX_FLAGS_INVERT_Y               2    //反转Y

#define VERTEX_FLAGS_INVERT_Z               4    //反转Z

#defineVERTEX_FLAGS_SWAP_YZ                  8    //RHS变换为LHS

#defineVERTEX_FLAGS_SWAP_XZ                  16  

#defineVERTEX_FLAGS_SWAP_XY                  32  

#defineVERTEX_FLAGS_INVERT_WINDING_ORDER64   //反转环绕顺序

 

在调用文件中,

初始化灯光,

 

#define                             AMBIENT_LIGHT_INDEX    0

#define                             INFINITE_LIGHT_INDEX   1

#define                             POINT_LIGHT_INDEX  2

#define                             SPOT_LIGHT_INDEX   3

 

改变摄像机位置

POINT4D cam_pos = {0,0,-250,1};

几个状态变量

 

int               wireframe_mode             = -1;

int               backface_mode          = 1;

int               lighting_mode          = 1;

int               help_mode              = 1;

int               zsort_mode                 = 1;

加载3DSMAX的第一个版本用到了模式匹配,希望是正确的,。

 

 

 

intddraw_liushuixian::Load_OBJECT4DV1_3DSASC(OBJECT4DV1_PTRobj, char * filename, VECTOR4D_PTR scale, VECTOR4D_PTR pos, VECTOR4D_PTR rot, int vertex_flags)

{

    CPARSERV1     parser;

    char          seps[16];

    char          token_buffer[256];         //缓冲区

    char *       token;                          //指向要分析的物体数据文本的指针

 

    int                r,g, b;

    //先找到物体描述符

 

    //第一步清空和初始化OBJ

    memset( obj, 0,sizeof(OBJECT4DV1) );

    //将物体状态设置为可见和活动的

    obj->state                                        = OBJECT4DV1_STATE_ACTIVE | OBJECT4DV1_STATE_VISIBLE;

 

    if ( pos )

    {

        //设置物体的位置

        obj->world_pos.x                         = pos->x;

        obj->world_pos.y                         = pos->y;

        obj->world_pos.z                         = pos->z;

        obj->world_pos.w                         = pos->w;

    }

    else

    {

        //设置物体的位置

        obj->world_pos.x                         = 0;

        obj->world_pos.y                         = 0;

        obj->world_pos.z                         = 0;

        obj->world_pos.w                         = 1;

    }

 

 

    //第步,读取文件

    parser.Open(filename );

    //第步,读取物体描述符

    while ( 1 )

    {

        parser.GetLine(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS );

 

 

 

        //检测模式

        if( parser.Pattern_Match(parser.buffer,"['Named']['object:']" ) )

        {

             strcpy( token_buffer,parser.buffer );

             strcpy( seps,"\"" );

             strtok( token_buffer,seps );

 

             token                  = strtok( NULL,seps );

 

             strcpy( obj->name,seps );

 

             break;

        }

    }

 

    //第步,得到我图的顶点数目

    while( 1 )

    {

 

        parser.GetLine(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS );

        //下一行,寻找Tri-Mesh,Vertices,提取顶点数目

        if( parser.Pattern_Match(parser.buffer,"['Tri-mesh,']['Vertices:'][i]['Faces:'][i]" ) )

             obj->num_vertices                   = parser.pints[0];

             obj->num_polys                           = parser.pints[1];

 

             break;

        }

    }

 

    //第步:加载顶点列表

 

    while( 1 )

    {

 

        parser.GetLine(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS );

        //下一行,寻找Tri-Mesh,Vertices,提取顶点数目

        if( parser.Pattern_Match(parser.buffer,"['Vertex']['list:']" ) )

        {

 

 

             break;

        }

    }

 

    //现在读取顶点列表,格式"Vertex:d X:d.d Y:d.d Z:d.d"

    for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )

    {

        while( 1 )

        {

             parser.GetLine(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS );

             parser.StripChars(parser.buffer,parser.buffer,":XYZ" );

             if( parser.Pattern_Match(parser.buffer,"['Vertex'][i][f][f][f]" ) )

             {

                  obj->vlist_local[vertex].x                    = parser.pfloats[0];

                  obj->vlist_local[vertex].y                    = parser.pfloats[1];

                  obj->vlist_local[vertex].z                    = parser.pfloats[2];

                  obj->vlist_local[vertex].w                    = 1;

 

                  //根据标志位来进行相应的旋转

                  float              temp_f;

 

                  if( vertex_flags &VERTEX_FLAGS_INVERT_X )

                      obj->vlist_local[vertex].x               = - obj->vlist_local[vertex].x;

                  if( vertex_flags &VERTEX_FLAGS_INVERT_Y )

                      obj->vlist_local[vertex].y               = - obj->vlist_local[vertex].y;

                  if( vertex_flags &VERTEX_FLAGS_INVERT_Z )

                      obj->vlist_local[vertex].z               = - obj->vlist_local[vertex].z;

 

                  if( vertex_flags &VERTEX_FLAGS_SWAP_YZ )

                      SWAP( obj->vlist_local[vertex].y,obj->vlist_local[vertex].z,temp_f );

 

                  if( vertex_flags &VERTEX_FLAGS_SWAP_XZ )

                      SWAP( obj->vlist_local[vertex].x,obj->vlist_local[vertex].z,temp_f );

 

                  if( vertex_flags &VERTEX_FLAGS_SWAP_XY )

                      SWAP( obj->vlist_local[vertex].x,obj->vlist_local[vertex].y,temp_f );

 

                  //放缩

                  if( scale )

                  {

                      obj->vlist_local[vertex].x      *=   scale->x;

                      obj->vlist_local[vertex].y      *=   scale->y;

                      obj->vlist_local[vertex].z      *=   scale->z;

                  }

                  break;

             }

        }

    }

 

    //计算平均和最大半径

    Compute_OBJECT4DV1_RADIUS( obj );

 

    //6,88面表

    while( 1 )

    {

        if( ! parser.GetLine(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS ) )

        {

             return ( 0 );

 

        }

 

        if( parser.Pattern_Match(parser.buffer,"['Face']['list:']" ) )

        {

 

             break;

        }

 

 

    }

 

    //格式/

    //Material:"rdddgdddbddda0"

 

    int           poly_surface_desc                   = 0;

    int           poly_num_verts                           = 0;

    char     tmp_string[8];

 

    int           poly                                = 0;

    for(  poly = 0;poly < obj->num_polys;poly++ )

    {

        while ( 1 )

        {

             if( ! parser.GetLine(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS ) )

             {

                  return ( 0 );

             }

 

             parser.StripChars(parser.buffer,parser.buffer,":ABC" );

 

             if( parser.Pattern_Match(parser.buffer,"['Face'][i][i][i][i]" ) )

             {

                  //

 

                  if( vertex_flags &VERTEX_FLAGS_INVERT_WINDING_ORDER )

                  {

                      poly_num_verts                  = 3;

                      obj->plist[poly].vert[0]   = parser.pints[3];

                      obj->plist[poly].vert[1]   = parser.pints[2];

                      obj->plist[poly].vert[2]   = parser.pints[1];

                  }

                  else

                  {

                      poly_num_verts                  = 3;

                      obj->plist[poly].vert[0]   = parser.pints[1];

                       obj->plist[poly].vert[1]   = parser.pints[2];

                      obj->plist[poly].vert[2]   = parser.pints[3];

                  }

 

                  obj->plist[poly].vlist          = obj->vlist_local;

 

                  break;

             }

        }

        //去除:ABC

        while( 1 )

        {

             if( ! parser.GetLine(PARSER_STRIP_EMPTY_LINES | PARSER_STRIP_WS_ENDS ) )

             {

                  return ( 0 );

             }

 

             //Material:"rdddgdddbddda0"

             //去掉'rgba'去掉

 

             parser.ReplaceChars(parser.buffer,parser.buffer,":\"rgba",' ' );

 

             if( parser.Pattern_Match( parser.buffer, "[i][i][i]" ) )

             {

                  r                                             = parser.pints[0];

                  g                                             = parser.pints[1];

                  b                                             = parser.pints[2];

 

 

                  SET_BIT( obj->plist[poly].attr,POLY4DV1_ATTR_RGB16 );

                  obj->plist[poly].color               = _RGB16BIT565(r, g, b );

 

 

                  SET_BIT( obj->plist[poly].attr,POLY4DV1_ATTR_SHADE_MODE_FLAT );

                  obj->plist[poly].state                   = POLY4DV1_STATE_ACTIVE;

 

                  break;

             }

        }

    }

 

    return ( 1 );

}

 

 

这里只保留16位模式,

看看MAIN()函数这里,如何调用的。

渲染列表是第一个版本的,

RENDERLIST4DV1    render_list;

 

 

//几个不同的渲染模型状态变量(虽然用不上,只进行模型加载,)

int               wireframe_mode                      = -1;

int               backface_mode                   = 1;

int               lighting_mode                   = 1;

int               help_mode                       = 1;

int               zsort_mode                          = 1;

 

int               swapyz                              = 0,

                  iwinding                        = 0;

 

char         ascfilename[256];                             //加载的文件名

在初始化GAME_INIT()里,将XYZ均扩大到5倍,

    math->VECTOR4D_INITXYZ( &vscale, 5.0, 5.0, 5.0 );

加载3DSMAX模型,

    liushuixian.Load_OBJECT4DV1_3DSASC( &obj_player, "sphere01.asc", &vscale, &vpos, &vrot,VERTEX_FLAGS_INVERT_WINDING_ORDER | VERTEX_FLAGS_SWAP_YZ );

 

在初始化时重置灯光

设置几个颜色

 

    RGBAV1                     white, gray,black, red,green, blue;

 

    white.rgba                                    = _RGBA32BIT( 255, 255, 255, 0 );

    gray.rgba                                = _RGBA32BIT( 100, 100, 100, 0 );

    black.rgba                                    = _RGBA32BIT( 0, 0, 0, 0 );

    red.rgba                                 = _RGBA32BIT( 255, 0, 0, 0 );

    green.rgba                                    = _RGBA32BIT( 0, 255, 0, 0 );

    blue.rgba                                = _RGBA32BIT( 0, 0, 255, 0 );

 

加光源:

    //环境光

   light.Init_Light_LIGHTV1( *math, lightGroup,AMBIENT_LIGHT_INDEX,LIGHTV1_STATE_ON, LIGHTV1_ATTR_AMBIENT, gray, black, black, NULL, NULL, 0, 0, 0, 0, 0, 0 );

 

    //方向光

    VECTOR4D               dlight_dir         = { -1, 0, -1, 0 };

    light.Init_Light_LIGHTV1( *math,lightGroup,INFINITE_LIGHT_INDEX,LIGHTV1_STATE_ON, LIGHTV1_ATTR_INFINITE, black, gray, black, NULL, &dlight_dir, 0, 0, 0, 0, 0, 0 );

 

    //点光源

    VECTOR4D               plight_pos         = { 0, 200, 0, 0 };

    light.Init_Light_LIGHTV1( *math,lightGroup,POINT_LIGHT_INDEX,LIGHTV1_STATE_ON, LIGHTV1_ATTR_POINT, black, green, black , &plight_pos,NULL, 0, 0.001, 0, 0, 0, 1 );

 

    //聚光灯

    VECTOR4D               slight_pos         = { 0, 200, 0, 0 };

    VECTOR4D               slight_dir         = { -1, 0, -1, 0 };

    light.Init_Light_LIGHTV1(SPOT_LIGHT_INDEX, lightGroup, SPOT_LIGHT_INDEX, LIGHTV1_STATE_ON, LIGHTV1_ATTR_SPOLIGHT2,black, red,black, &slight_pos, &slight_dir, 0, 0.001, 0, 0, 0, 1 );

Game_main()中,

intGame_Main(void *parms)

{

    // this is the workhorse of your game it will be called

    // continuously in real-time this is like main() in C

    // all the calls for you game go here!

 

    static MATRIX4X4mrot;   // general rotation matrix

 

    // these are used to create a circling camera

    static floatview_angle = 0;

    static floatcamera_distance = 6000;

    static VECTOR4Dpos = {0,0,0,0};

    char work_string[256];// temp string

    int index;// looping var

 

    // start the timing clock

    srand( mytool.Start_Clock() );

 

    ddraw->DDraw_Fill_Surface(ddraw->getbackSurface(), 0 );

    liushuixian.Reset_RENDERLIST4DV1( &rend_list );

    // allow user to move camera

 

    if (obj_player.dir.y > 360)

        obj_player.dir.y-=360;

 

    if (obj_player.dir.y < 0)

        obj_player.dir.y+=360;

 

    // ambient rotation

    obj_player.dir.y++;

 

 

    // modes and lights

 

 

    static floatplight_ang = 0, slight_ang = 0;// angles for light motion

 

    // move point light source in ellipse around game world

    lightGroup[POINT_LIGHT_INDEX].pos.x = 300*cosf(plight_ang);

    lightGroup[POINT_LIGHT_INDEX].pos.y = 200;

    lightGroup[POINT_LIGHT_INDEX].pos.z = 300*sinf(plight_ang);

 

    if ((plight_ang+=3) > 360)

        plight_ang = 0;

 

    // move spot light source in ellipse around game world

    lightGroup[SPOT_LIGHT_INDEX].pos.x = 200*cosf(slight_ang);

    lightGroup[SPOT_LIGHT_INDEX].pos.y = 200;

    lightGroup[SPOT_LIGHT_INDEX].pos.z = 200*sinf(slight_ang);

 

    if ((slight_ang-=5) < 0)

        slight_ang = 360;

 

 

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

 

    // generate camera matrix

    liushuixian.Build_CAM4DV1_Matrix_Euler( *math, &cam, CAM_ROT_SEQ_ZYX );

 

    // insert the player into the world

    // reset the object (this only matters for backface and object removal)

    liushuixian.Reset_OBJECT4DV1( &obj_player );

 

    // generate rotation matrix around y axis

//  Build_XYZ_Rotation_MATRIX4X4(0, obj_player.dir.y, 0, &mrot);

    math->Build_XYZ_Rotation_MATRIX4x4( 0,obj_player.dir.y, 0, &mrot );

 

    // rotate the local coords of the object

    liushuixian.Transform_OBJECT4DV1( &obj_player, &mrot,TRANSFORM_LOCAL_TO_TRANS, 1, *math );

 

    // perform world transform

    liushuixian.Model_To_World_OBJECT4DV1( &obj_player,*math, TRANSFORM_TRANS_ONLY );

 

 

    // perform lighting

    if (lighting_mode==1)

        liushuixian.Light_OBJECT4DV1_World16( *math,DD_PIXEL_FORMAT565, &obj_player, &cam, lightGroup, 4 );

 

    // insert the object into render list

    liushuixian.Insert_OBJECT4DV1_RENDERLIST4DV12( *math, &rend_list, &obj_player, 0, lighting_mode );

 

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

 

    // remove backfaces

    if (backface_mode==1)

        liushuixian.Remove_Backfaces_RENDERLIST4DV1( &rend_list, &cam, * math );

 

    

    // apply world to camera transform

//  World_To_Camera_RENDERLIST4DV1(&rend_list, &cam);

    liushuixian.World_To_Camera_RENDERLIST4DV1( *math, &rend_list, &cam );

 

    // sort the polygon list (hurry up!)

    if (zsort_mode == 1)

        Sort_RENDERLIST4DV1(&rend_list, SORT_POLYLIST_AVGZ);

 

    liushuixian.Camera_To_Perspective_RENDERLIST4DV1( &rend_list, &cam );

    liushuixian.Perspective_To_Screen_RENDERLIST4DV1( &rend_list, &cam );

 

    // lock the back buffer

    //DDraw_Lock_Back_Surface();

    ddraw->DDraw_Lock_Back_Surface();

 

 

 

    

    liushuixian.Draw_RENDERLIST4DV1_Solid16( *math, &rend_list,ddraw->getbackbuffer(),ddraw->getbacklpitch() );

 

    ddraw->DDraw_Unlock_Back_Surface();

 

    ddraw->DDraw_Flip();

    // sync to 30ish fps

//  Wait_Clock(30);

    mytool.Wait_Clock( 30 );

 

 

    // return success

    return(1);

 

}// end Game_Main

截图如下:

0 0
原创粉丝点击