计算机图形学实验zbuffer算法.docx

上传人:b****3 文档编号:4004266 上传时间:2022-11-27 格式:DOCX 页数:12 大小:33.80KB
下载 相关 举报
计算机图形学实验zbuffer算法.docx_第1页
第1页 / 共12页
计算机图形学实验zbuffer算法.docx_第2页
第2页 / 共12页
计算机图形学实验zbuffer算法.docx_第3页
第3页 / 共12页
计算机图形学实验zbuffer算法.docx_第4页
第4页 / 共12页
计算机图形学实验zbuffer算法.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

计算机图形学实验zbuffer算法.docx

《计算机图形学实验zbuffer算法.docx》由会员分享,可在线阅读,更多相关《计算机图形学实验zbuffer算法.docx(12页珍藏版)》请在冰豆网上搜索。

计算机图形学实验zbuffer算法.docx

计算机图形学实验zbuffer算法

计算机图形学实验z-buffer算法

实验六9-7

一、实验题目

z-buffer算法的代表性案例是绘制三个相互交叉的红绿蓝条,如图9-85所示,请使用MFC编程实现。

二、实验思想

Z-Buffer算法建立两个缓冲器:

深度缓冲器,用以存储图像空间中每一像素相应的深度值,初始化为最大深度值(zs坐标)。

帧缓冲器,用以存储图像空间中的每个像素的颜色,初始化为屏幕的背景色。

1帧缓冲器初始值置为背景色。

2确定深度缓冲器的宽度、高度和初始深度。

一般将初始深度置为最大深度值。

3对于多边形表面中的每一像素(xs,ys),计算其深度值zs(xs,ys)。

4将zs(xs,ys)与存储在z缓冲器中该位置的深度值zBuffer(xs,ys)进行比较。

5如果zs(xs,ys)≤zBuffer(xs,ys),则将此像素的颜色写入帧缓冲器,且用z(xs,ys)重置zbuffer(xs,ys)。

三、实验代码

CZBuffer:

:

~CZBuffer()

{

delete[]P;

}

voidCZBuffer:

:

SetPoint(CPi3p[],intm)

{

P=newCPi3[m];

for(inti=0;i

{

P[i]=p[i];

}

PNum=m;

}

voidCZBuffer:

:

CreateBucket()//创建桶表

{

intyMin,yMax;

yMin=yMax=P[0].y;

for(inti=0;i

{

if(P[i].y

{

yMin=P[i].y;//扫描线的最小值

}

if(P[i].y>yMax)

{

yMax=P[i].y;//扫描线的最大值

}

}

for(inty=yMin;y<=yMax;y++)

{

if(yMin==y)//建立桶头结点

{

HeadB=newCBucket;//建立桶的头结点

CurrentB=HeadB;//CurrentB为CBucket当前结点指针

CurrentB->ScanLine=yMin;

CurrentB->pET=NULL;//没有连接边链表

CurrentB->next=NULL;

}

else//建立桶的其它结点

{

CurrentB->next=newCBucket;

CurrentB=CurrentB->next;

CurrentB->ScanLine=y;

CurrentB->pET=NULL;

CurrentB->next=NULL;

}

}

}

voidCZBuffer:

:

CreateEdge()//创建边表

{

for(inti=0;i

{

CurrentB=HeadB;

intj=(i+1)%PNum;//边的第二个顶点,P[i]和P[j]构成边

if(P[i].y

{

Edge=newCAET;

Edge->x=P[i].x;//计算ET表的值

Edge->yMax=P[j].y;

Edge->k=(P[j].x-P[i].x)/(P[j].y-P[i].y);//代表1/k

Edge->pb=P[i];//绑定顶点和颜色

Edge->pe=P[j];

Edge->next=NULL;

while(CurrentB->ScanLine!

=P[i].y)//在桶内寻找该边的yMin

{

CurrentB=CurrentB->next;//移到yMin所在的桶结点

}

}

if(P[j].y

{

Edge=newCAET;

Edge->x=P[j].x;

Edge->yMax=P[i].y;

Edge->k=(P[i].x-P[j].x)/(P[i].y-P[j].y);

Edge->pb=P[i];

Edge->pe=P[j];

Edge->next=NULL;

while(CurrentB->ScanLine!

=P[j].y)

{

CurrentB=CurrentB->next;

}

}

if(int(P[j].y)!

=P[i].y)

{

CurrentE=CurrentB->pET;

if(CurrentE==NULL)

{

CurrentE=Edge;

CurrentB->pET=CurrentE;

}

else

{

while(CurrentE->next!

=NULL)

{

CurrentE=CurrentE->next;

}

CurrentE->next=Edge;

}

}

}

}

voidCZBuffer:

:

Gouraud(CDC*pDC)//填充多边形

{

doubleCurDeep=0.0;//当前扫描线的深度

doubleDeepStep=0.0;//当前扫描线随着x增长的深度步长

doubleA,B,C,D;//平面方程Ax+By+Cz+D=0的系数

CVectorV21(P[1],P[2]),V10(P[0],P[1]);

CVectorVN=V21*V10;

A=VN.X();B=VN.Y();C=VN.Z();

D=-A*P[1].x-B*P[1].y-C*P[1].z;

DeepStep=-A/C;//计算直线deep增量步长

CAET*T1,*T2;

HeadE=NULL;

for(CurrentB=HeadB;CurrentB!

=NULL;CurrentB=CurrentB->next)

{

for(CurrentE=CurrentB->pET;CurrentE!

=NULL;CurrentE=CurrentE->next)

{

Edge=newCAET;

Edge->x=CurrentE->x;

Edge->yMax=CurrentE->yMax;

Edge->k=CurrentE->k;

Edge->pb=CurrentE->pb;

Edge->pe=CurrentE->pe;

Edge->next=NULL;

AddEt(Edge);

}

EtOrder();

T1=HeadE;

if(T1==NULL)

{

return;

}

while(CurrentB->ScanLine>=T1->yMax)//下闭上开

{

T1=T1->next;

HeadE=T1;

if(HeadE==NULL)

return;

}

if(T1->next!

=NULL)

{

T2=T1;

T1=T2->next;

}

while(T1!

=NULL)

{

if(CurrentB->ScanLine>=T1->yMax)//下闭上开

{

T2->next=T1->next;

T1=T2->next;

}

else

{

T2=T1;

T1=T2->next;

}

}

CRGBCa,Cb,Cf;//Ca、Cb代边上任意点的颜色,Cf代表面上任意点的颜色

Ca=Interpolation(CurrentB->ScanLine,HeadE->pb.y,HeadE->pe.y,HeadE->pb.c,HeadE->pe.c);

Cb=Interpolation(CurrentB->ScanLine,HeadE->next->pb.y,HeadE->next->pe.y,HeadE->next->pb.c,HeadE->next->pe.c);

BOOLFlag=FALSE;

doublexb,xe;//扫描线的起点和终点坐标

for(T1=HeadE;T1!

=NULL;T1=T1->next)

{

if(Flag==FALSE)

{

xb=T1->x;

CurDeep=-(xb*A+CurrentB->ScanLine*B+D)/C;//z=-(Ax+By-D)/C

Flag=TRUE;

}

else

{

xe=T1->x;

for(doublex=xb;x

{

Cf=Interpolation(x,xb,xe,Ca,Cb);

if(CurDeep>=ZB[ROUND(x)+Width/2][CurrentB->ScanLine+Height/2])//如果新采样点的深度大于原采样点的深度

{

ZB[ROUND(x)+Width/2][CurrentB->ScanLine+Height/2]=CurDeep;//xy坐标与数组下标保持一致

pDC->SetPixel(ROUND(x),CurrentB->ScanLine,RGB(Cf.red*255,Cf.green*255,Cf.blue*255));

}

CurDeep+=DeepStep;

}

Flag=FALSE;

}

}

for(T1=HeadE;T1!

=NULL;T1=T1->next)//边的连续性

{

T1->x=T1->x+T1->k;

}

}

deleteHeadB;

deleteHeadE;

deleteCurrentE;

deleteCurrentB;

deleteEdge;

}

voidCZBuffer:

:

AddEt(CAET*NewEdge)//合并ET表

{

CAET*CE;

CE=HeadE;

if(CE==NULL)

{

HeadE=NewEdge;

CE=HeadE;

}

else

{

while(CE->next!

=NULL)

{

CE=CE->next;

}

CE->next=NewEdge;

}

}

voidCZBuffer:

:

EtOrder()//边表的冒泡排序算法

{

CAET*T1,*T2;

intCount=1;

T1=HeadE;

if(T1==NULL)

{

return;

}

if(T1->next==NULL)//如果该ET表没有再连ET表

{

return;//桶结点只有一条边,不需要排序

}

while(T1->next!

=NULL)//统计结点的个数

{

Count++;

T1=T1->next;

}

for(inti=1;i

{

T1=HeadE;

if(T1->x>T1->next->x)//按x由小到大排序

{

T2=T1->next;

T1->next=T1->next->next;

T2->next=T1;

HeadE=T2;

}

else

{

if(T1->x==T1->next->x)

{

if(T1->k>T1->next->k)//按斜率由小到大排序

{

T2=T1->next;

T1->next=T1->next->next;

T2->next=T1;

HeadE=T2;

}

}

}

T1=HeadE;

while(T1->next->next!

=NULL)

{

T2=T1;

T1=T1->next;

if(T1->x>T1->next->x)//按x由小到大排序

{

T2->next=T1->next;

T1->next=T1->next->next;

T2->next->next=T1;

T1=T2->next;

}

else

{

if(T1->x==T1->next->x)

{

if(T1->k>T1->next->k)//按斜率由小到大排序

{

T2->next=T1->next;

T1->next=T1->next->next;

T2->next->next=T1;

T1=T2->next;

}

}

}

}

}

}

CRGBCZBuffer:

:

Interpolation(doublet,doublet1,doublet2,CRGBc1,CRGBc2)//线性插值

{

CRGBc;

c=(t-t2)/(t1-t2)*c1+(t-t1)/(t2-t1)*c2;

returnc;

}

voidCZBuffer:

:

InitDeepBuffer(intwidth,intheight,doubledepth)//初始化深度缓冲

{

Width=width,Height=height;

ZB=newdouble*[Width];

for(inti=0;i

ZB[i]=newdouble[Height];

for(i=0;i

for(intj=0;j

ZB[i][j]=double(depth);

}

四、程序结果截图

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1