2014年2月7日星期五(7-3,消除了背面的3D线框立方体)
来源:互联网 发布:网络侠义游戏辅助论坛 编辑:程序博客网 时间:2024/04/28 15:49
好久没进行了,看看吧,与DEMO7-2的区别,只看不同的地方,相机类型不同,归一化平面改为2*2/ar,视口为640*480,执行了背面消除,(就是判断面元向量与面元到视点向量的点乘,>0,则可见,否则,消除)
这一步是在物体剔除后和世界坐标到相机坐标变换之前进行背面消除,
先建立4D向量,两点确定一个向量,SO EASY如下。
void ddraw_math::VECTOR4D_Build( VECTOR4D_PTR init, VECTOR4D_PTR term, VECTOR4D_PTR result )
{
result->x =term->x -init->x;
result->y =term->y - init->y;
result->z =term->z - init->z;
result->w = 1;
}
再做个准备工作,4元数之间的叉乘
void ddraw_math::VECTOR4D_CROSS( VECTOR4D_PTR va, VECTOR4D_PTR vb, VECTOR4D_PTR vn )
{
vn->x = ((va->y * vb->z) - ( va->z * vb->y));
vn->y = - ( (va->x * vb->z) - ( va->z * vb->x ));
vn->z = ( (va->x * vb->y ) - ( va->y * vb->x));
vn->w = 1;
}
四元数之间的点乘
float ddraw_math::VECTOR4D_DOT( VECTOR4D_PTR va, VECTOR4D_PTR vb )
{
return ( ( va->x * vb->x ) + (va->y * vb->y ) + ( va->z + vb->z ) );
}
背面消除函数如下
void ddraw_liushuixian::Remove_Backfaces_OBJECT4DV1(OBJECT4DV1_PTRobj, CAM4DV1_PTRcam, ddraw_mathmath)
{
//检查物体是否已经被剔除
//在执行物体提出之后和世界坐标到相机坐标变换之前进行背面消除
if ( obj->state & OBJECT4DV1_STATE_CULLED )
{
return;
}
//处理物体的每个多边形
for( int poly = 0; poly < obj->num_polys;poly ++ )
{
//获取多边形
POLY4DV1_PTR curr_poly = & obj->plist[poly];
//该多边形是否有效?
//判断该多边形是否没被裁剪掉,没有被剔除,处于活动状态,可见且不是双面的
if ( ! ( curr_poly->state & POLY4DV1_STATE_ACTIVE ) ||
( curr_poly->state &POLY4DV1_STATE_CLIPPED) ||
( curr_poly->state &POLY4DV1_ATTR_2SIDED) ||
( curr_poly->state &POLY4DV1_STATE_BACKFACE))
{
continue;
}
//获取顶点列表中的顶点索引
int vindex_0 = curr_poly->vert[0];
int vindex_1 = curr_poly->vert[1];
int vindex_2 = curr_poly->vert[2];
//计算多边形的面法线,
//顶点是按照顺时针方向排列的,u=p0->p1,v=p0->p2,n=UXV;
VECTOR4D u, v, n;
//计算u和v
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0], &obj->vlist_trans[vindex_1], &u );
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0], &obj->vlist_trans[vindex_2], &v );
//计算叉积
math.VECTOR4D_CROSS( &u, &v, &n );
//创建指向视点的向量
VECTOR4D view;
math.VECTOR4D_Build( &obj->vlist_trans[vindex_0], &cam->pos, &view );
//计算点积
float dp = math.VECTOR4D_DOT( &n, &view );
if ( dp<= 0)
{
SET_BIT( curr_poly->state, POLY4DV1_STATE_BACKFACE );
}
}
}
现在看看在主函数中怎么改动,首先,在GAME_INIT()中,加载cube2.plg,
WINDOW_HEIGHT);
//加载模型
liushuixian.Load_OBJECT4DV1_PLG( &obj, "cube2.plg", &vscale, & vpos, &vrot );
在Game_Main()中加上背面消除
。。。。。。
liushuixian.Build_CAM4DV1_Matrix_Euler( *math, &cam, CAM_ROT_SEQ_ZYX );
//Build_CAM4DV1_Matrix_Euler( & cam, CAM_ROT_SEQ_ZYX );
liushuixian.Remove_Backfaces_OBJECT4DV1( &obj, &cam, *math );
liushuixian.World_To_Camera_OBJECT4DV1( *math, &obj, &cam );
。。。。。。
如下图所示
说明背面消除没有起作用,将
if ( dp>0 )
{
SET_BIT( curr_poly->state, POLY4DV1_STATE_BACKFACE );
}
发现也是整个显示,说明没起作用。
输出到文件的方法
void Remove_Backfaces_OBJECT4DV1(OBJECT4DV1_PTRobj, CAM4DV1_PTRcam)
{
FILE * fp = fopen( "test.txt", "w");
fprintf( fp, "removebackface函数起效果了\n" );
;
//检查物体是否已经被剔除
//在执行物体提出之后和世界坐标到相机坐标变换之前进行背面消除
if ( obj->state & OBJECT4DV1_STATE_CULLED )
{
return;
}
fprintf(fp,"有不是OBJECT4DV1_STATE_CULLED的点\n");
//处理物体的每个多边形
for( int poly = 0; poly < obj->num_polys;poly ++ )
{
//获取多边形
POLY4DV1_PTR curr_poly = & obj->plist[poly];
//该多边形是否有效?
//判断该多边形是否没被裁剪掉,没有被剔除,处于活动状态,可见且不是双面的
if ( ! ( curr_poly->state & POLY4DV1_STATE_ACTIVE ) ||
( curr_poly->state &POLY4DV1_STATE_CLIPPED) ||
( curr_poly->state &POLY4DV1_ATTR_2SIDED) ||
( curr_poly->state &POLY4DV1_STATE_BACKFACE))
{
fprintf(fp,"第%d个顶点没经过计算\n",poly);
continue;
}
fprintf(fp,"有进行计算的点\n");
//获取顶点列表中的顶点索引
int vindex_0 = curr_poly->vert[0];
int vindex_1 = curr_poly->vert[1];
int vindex_2 = curr_poly->vert[2];
//计算多边形的面法线,
//顶点是按照顺时针方向排列的,u=p0->p1,v=p0->p2,n=UXV;
VECTOR4D u, v, n;
//计算u和v
VECTOR4D_Build( & obj->vlist_trans[vindex_0], &obj->vlist_trans[vindex_1], &u );
VECTOR4D_Build( & obj->vlist_trans[vindex_0], &obj->vlist_trans[vindex_2], &v );
//计算叉积
VECTOR4D_Cross( & u, &v, &n );
//创建指向视点的向量
VECTOR4D view;
VECTOR4D_Build( & obj->vlist_trans[vindex_0], &cam->pos, &view );
//计算点积
float dp =VECTOR4D_Dot( &n, &view );
if ( dp<0 )
{
SET_BIT( curr_poly->state, POLY4DV1_STATE_BACKFACE );
}
; fprintf(fp,"第%d个面法线与视线点积为%f",poly, dp );
}
fclose( fp);
}
发现test.txt的显示内容是
removebackface函数起效果了
有不是OBJECT4DV1_STATE_CULLED的点
第0个顶点没经过计算,共12个顶点
第1个顶点没经过计算,共12个顶点
第2个顶点没经过计算,共12个顶点
第3个顶点没经过计算,共12个顶点
第4个顶点没经过计算,共12个顶点
第5个顶点没经过计算,共12个顶点
第6个顶点没经过计算,共12个顶点
第7个顶点没经过计算,共12个顶点
第8个顶点没经过计算,共12个顶点
第9个顶点没经过计算,共12个顶点
第10个顶点没经过计算,共12个顶点
第11个顶点没经过计算,共12个顶点
说明全continue了,再往前看状态。
结果发现太马虎了,应该是
curr_poly->attr &POLY4DV1_ATTR_2SIDED
而不是
curr_poly->state &POLY4DV1_ATTR_2SIDED
另外点乘最后一项应该是×而不是+,即原来是
float ddraw_math::VECTOR4D_DOT( VECTOR4D_PTR va, VECTOR4D_PTR vb )
{
return ( ( va->x * vb->x ) + (va->y * vb->y ) + ( va->z + vb->z ) );
}
应改为
float ddraw_math::VECTOR4D_DOT( VECTOR4D_PTR va, VECTOR4D_PTR vb )
{
return ( ( va->x * vb->x ) + (va->y * vb->y ) + ( va->z * vb->z ) );
}
修正后结果如下所示,OK了
- 2014年2月7日星期五(7-3,消除了背面的3D线框立方体)
- 2014年2月14日星期五(DEMO7-4,3D坦克)
- 2014年1月14日星期二(DEMO7-2,加载3D线框立方体物体模型)
- 2014年3月7日星期五(DEMO8-4,实体三角形着色)
- 2013年12月20日星期五(7——1,绘制三角线框)
- 2010年3月12日星期五
- 2010年3月19日星期五
- 2010年3月26日星期五
- 2014年1月3日星期五(DEMO7_1终结)
- 2009年2月13日星期五
- 2010年4月2日星期五
- 2014年2月21日星期五(DEMO7-6战区漫步)
- 2010年5月7日(新公司入职,第五周星期五)
- 2010年6月7日(新公司入职,第十周星期五)
- 2013年6月28日星期五(7-14,离散采样理论)
- 2013年12月20日星期五(7_0,16位窗口模式)
- 2013年8月30日星期五(8-3多边形)
- 2011年12月9日星期五(oracle读书笔记)
- 几个比较好的countdown js
- 机房收费系统 实现图
- SQL Server 2008 with(nolock)的使用原因及数据库锁,隔离级别简介
- 当当网与1号店相互入驻
- 寒假获得的小知识
- 2014年2月7日星期五(7-3,消除了背面的3D线框立方体)
- 【D3DX日记】D3D与D3DX的区别
- 数据库的学习MySQL
- 制造WiFi热点&抓包
- IOS 推送消息 php做推送服务端
- backfire示例中collection add事件的触发问题
- Android编译系统环境初始化过程分析
- Citadel – An Open-Source Malware Project
- 解密中国互联网