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
截图如下:
- 2014年7月8日星期二(DEMO8-8加载3DSMAX ASCII格式模型.ASC)
- 2014年8月26日星期二(DEMO8-9加载COB模型)
- 2014年7月7日星期一(DEMO8-7使用新的模型格式)
- 2014年2月25日星期二(DEMO8-2,光照图调制)
- 2014年3月8日星期六(DEMO8-5恒定着色)
- 2014年1月14日星期二(DEMO7-2,加载3D线框立方体物体模型)
- 2014年3月7日星期五(DEMO8-4,实体三角形着色)
- 2017年8月8日 星期二
- 07年8月28日 星期二
- 2007年5月8日 星期二
- 2017年8月1日,星期二
- 2017年8月15日 星期二
- 2017年8月22日 星期二
- 2014年3月3日星期一(DEMO8-3,ALPHA混合)
- 2014年3月9日星期日(DEMO8-6,画家算法)
- 2007年8月14日 星期二 睛
- 2013年8月27日星期二(DEMO8_1,画线)
- 2014年2月22日星期六(DEMO8-1,颜色与放缩系数相乘)
- Codility上的问题 (40) Phosphorus 2014
- python杂记
- 机器视觉开源处理库汇总-介绍n款计算机视觉库/人脸识别开源库/软件 -几种图像处理类库的比较-视觉相关网站
- 2014年7月7日星期一(DEMO8-7使用新的模型格式)
- 转载:Why does MYSQL higher LIMIT offset slow the query down?
- 2014年7月8日星期二(DEMO8-8加载3DSMAX ASCII格式模型.ASC)
- poj3253 Fence Repair(哈弗曼)
- win7下VC++6.0打开多个工作区间
- 2014年8月26日星期二(DEMO8-9加载COB模型)
- 机器视觉专题
- [LeetCode] Balanced Binary Tree 平衡二叉树
- 9-2加上光照计算的GOURAUD shader多边形)
- 去学隐身术吧
- 前端开发神器 Emmet 介绍