计算机图形学实验z-buffer算法
更新时间:2024-05-18 23:28:01 阅读量: 综合文库 文档下载
- 计算机图形学实验总结推荐度:
- 相关推荐
实验六 9-7
一、实验题目
z-buffer算法的代表性案例是绘制三个相互交叉的红绿蓝条,如图9-85所示,请使用MFC编程实现。
二、实验思想
Z-Buffer算法建立两个缓冲器:
深度缓冲器,用以存储图像空间中每一像素相应的深度值,初始化为最大深度值(zs坐标)。
帧缓冲器,用以存储图像空间中的每个像素的颜色,初始化为屏幕的背景色。
① 帧缓冲器初始值置为背景色。
② 确定深度缓冲器的宽度、高度和初始深度。一般将初始深度置为最大深度值。 ③ 对于多边形表面中的每一像素(xs,ys),计算其深度值zs(xs,ys)。
④ 将zs(xs,ys)与存储在z缓冲器中该位置的深度值zBuffer(xs,ys)进行比较。 ⑤ 如果zs(xs,ys)≤zBuffer(xs,ys),则将此像素的颜色写入帧缓冲器,且用z(xs,ys)
重置zbuffer(xs,ys)。
三、实验代码
CZBuffer::~CZBuffer() { }
void CZBuffer::SetPoint(CPi3 p[],int m) {
P=new CPi3[m]; delete []P;
for(int i=0;i void CZBuffer::CreateBucket()//创建桶表 { { } PNum=m; P[i]=p[i]; } int yMin,yMax; yMin=yMax=P[0].y; for(int i=0;i for(int y=yMin;y<=yMax;y++) { } if(yMin==y)//建立桶头结点 { } else//建立桶的其它结点 { } CurrentB->next=new CBucket; CurrentB=CurrentB->next; CurrentB->ScanLine=y; CurrentB->pET=NULL; CurrentB->next=NULL; HeadB=new CBucket;//建立桶的头结点 CurrentB=HeadB;//CurrentB为CBucket当前结点指针 CurrentB->ScanLine=yMin; CurrentB->pET=NULL;//没有连接边链表 CurrentB->next=NULL; if(P[i].y if(P[i].y>yMax) { } yMax=P[i].y;//扫描线的最大值 yMin=P[i].y;//扫描线的最小值 void CZBuffer::CreateEdge()//创建边表 { for(int i=0;i CurrentB=HeadB; int j=(i+1)%PNum;//边的第二个顶点,P[i]和P[j]构成边 if(P[i].y if(P[j].y if(int(P[j].y)!=P[i].y) { Edge=new CAET; 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; Edge=new CAET; 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所在的桶结点 } } } CurrentE=CurrentB->pET; if(CurrentE==NULL) { } else { } while(CurrentE->next!=NULL) { } CurrentE->next=Edge; CurrentE=CurrentE->next; CurrentE=Edge; CurrentB->pET=CurrentE; void CZBuffer::Gouraud(CDC *pDC)//填充多边形 { double CurDeep=0.0;//当前扫描线的深度 double DeepStep=0.0;//当前扫描线随着x增长的深度步长 double A,B,C,D;//平面方程Ax+By+Cz+D=0的系数 CVector V21(P[1],P[2]),V10(P[0],P[1]); CVector VN=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=new CAET; } 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)//下闭上开 { } if(T1->next!=NULL) { } while(T1!=NULL) { if(CurrentB->ScanLine>=T1->yMax)//下闭上开 { } else { T2->next=T1->next; T1=T2->next; T2=T1; T1=T2->next; T1=T1->next; HeadE=T1; if(HeadE==NULL) return; } } T2=T1; T1=T2->next; CRGB Ca,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); BOOL Flag=FALSE; double xb,xe;//扫描线的起点和终点坐标 for(T1=HeadE;T1!=NULL;T1=T1->next) { if(Flag==FALSE) { } else { xe=T1->x; for(double x=xb;x Cf=Interpolation(x,xb,xe,Ca,Cb); if(CurDeep>=ZB[ROUND(x)+Width/2][CurrentB->ScanLine+Height/2])//xb=T1->x; CurDeep=-(xb*A+CurrentB->ScanLine*B+D)/C;//z=-(Ax+By-D)/C Flag=TRUE; 如果新采样点的深度大于原采样点的深度 { 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; delete HeadB; delete HeadE; delete CurrentE; delete CurrentB; delete Edge; void CZBuffer::AddEt(CAET *NewEdge)//合并ET表 { } CAET *CE; CE=HeadE; if(CE==NULL) { } else { } while(CE->next!=NULL) { } CE->next=NewEdge; CE=CE->next; HeadE=NewEdge; CE=HeadE; void CZBuffer::EtOrder()//边表的冒泡排序算法 { CAET *T1,*T2; int Count=1; T1=HeadE; if(T1==NULL) { } if(T1->next==NULL)//如果该ET表没有再连ET表 { } while(T1->next!=NULL)//统计结点的个数 { } for(int i=1;i T1=HeadE; if(T1->x>T1->next->x)//按x由小到大排序 { } else { if(T1->x==T1->next->x) { if(T1->k>T1->next->k)//按斜率由小到大排序 { T2=T1->next; T2=T1->next; T1->next=T1->next->next; T2->next=T1; HeadE=T2; Count++; T1=T1->next; return;//桶结点只有一条边,不需要排序 return; } } } } } 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由小到大排序 { } 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; T2->next=T1->next; T1->next=T1->next->next; T2->next->next=T1; T1=T2->next; CRGB CZBuffer::Interpolation(double t,double t1,double t2,CRGB c1,CRGB c2)//线性插值 { } void CZBuffer::InitDeepBuffer(int width,int height,double depth)//初始化深度缓冲 { } Width=width,Height=height; ZB=new double *[Width]; for(int i=0;i ZB[i]=new double[Height]; CRGB c; c=(t-t2)/(t1-t2)*c1+(t-t1)/(t2-t1)*c2; return c; for(i=0;i for(int j=0;j ZB[i][j]=double(depth); 四、程序结果截图
正在阅读:
计算机图形学实验z-buffer算法05-18
现场工程签证管理流程1.1104-23
最新九年级物理全册17-1电流与电压和电阻的关系学案新人教版 - 图文03-13
学校发展,我的责任国旗下讲话10-10
2016年CLSI M100S (第26版)主要更新内容解读--韩东升08-10
《班主任专业基本功》读书摘抄10-17
公司车辆使用管理规定范文3篇05-02
女性内衣市场调研报告模板02-25
蓦然回首,尽是长久的美10-28
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 算法
- 图形
- 实验
- 计算机
- buffer
- 层叠式蒸发器通用技术标准
- CAD技巧160个绝对实用技巧
- 2019-2020年六年级下册浙教版语文全册完整教案及教学设计
- 2014-2015(1)A练习答案
- 初中化学综合实践活动课教学设计
- 文献研读报告
- 信息检索大作业
- MAPGIS67教程(制图详细步骤讲解)
- C语言基础知识归纳
- 信息化建设和软件项目招标评分方法
- 最新的文案策划实习报告范文
- 2018高中化学专题二物质性质的探究1单元综合测试苏教版6
- 山东省烟台市黄务中学八年级化学全册 3.3 物质加热教案(新版)
- 有机化学复习题(1)
- 人教版小学语文六年级下册第五单元课堂作业本答案(更新)
- 2017年中考写作备考指要1
- 特种设备安全员考试试题库
- 2018-2023年中国蜡烛行业市场与投资规划分析报告(目录)
- B.3.1 施工进度计划报审表
- 金融法规案例