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

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

2读取顶点列表

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

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

定义了几个值

 

#define OBJECT4DV1_MAX_VERTICES                1024

#define OBJECT4DV1_MAX_POLYS                            1024

 

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

#define  VERTEX_FLAGS_INVERT_X                1    //反转X

#define  VERTEX_FLAGS_INVERT_Y                2    //反转Y

#define  VERTEX_FLAGS_INVERT_Z                4    //反转Z

#define VERTEX_FLAGS_SWAP_YZ                   8    //RHS变换为LHS

#define VERTEX_FLAGS_SWAP_XZ                   16  

#define VERTEX_FLAGS_SWAP_XY                   32  

#define VERTEX_FLAGS_INVERT_WINDING_ORDER 64   //反转环绕顺序

 

在调用文件中,

初始化灯光,

 

#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的第一个版本用到了模式匹配,希望是正确的,。

 

 

 

int ddraw_liushuixian::Load_OBJECT4DV1_3DSASC(OBJECT4DV1_PTR obj, 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()中,

int Game_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 MATRIX4X4 mrot;   // general rotation matrix

 

     // these are used to create a circling camera

     static float view_angle = 0;

     static float camera_distance = 6000;

     static VECTOR4D pos = {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 float plight_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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值