计算机图形学(光栅显示系统、基于GLUT的OpenGL程序框架、基本图元光栅化)

1.光栅显示系统
图形显示设备–CRT光栅扫描显示器(阴极射线管显示器)
电子束轰击屏幕表面的荧光物质,从而产生不同亮度的光点,这些光点是显示器可以控制的最小单位,称为像素。光点会逐渐变暗,需要不断刷新,一次刷新出现的完整显示画面称为一帧画面。
CRT光栅扫描显示器缺点:
显示器由离散像素构成,显示一条直线只能通过一组像素去逼近,根据图形确定逼近像素的过程称为扫描转换(也称为图元光栅化或图元的生成)。另外,用像素逼近图形会出现锯齿状的走样。
为了反复绘制屏幕,需要存储屏幕像素亮度或颜色的存储区,称为帧缓冲存储区,也称为帧缓存,帧缓存单元与屏幕像素一 一对应,单元的数值决定了对应像素的颜色。
将帧缓存中存储的数字信号转换成控制电子枪电压的模拟信号需要借助于视频控制器。
绘制图形的过程就是先进行扫描转换,确定用哪些像素近似图形,并将每个像素写入帧缓存对应的单元,然后由视频控制器将每个单元的数据转换成模拟信号去控制电子束的攻击位置和强度。
在光栅显示系统中,需要足够大的帧缓冲存储区才能反映图形的颜色和灰度等级。帧缓存容量与显示器分辨率m*n以及每个像素的表示颜色数k(若一个RGB颜色由三个字节组成,则颜色个数为2的24次方)之间的关系:
在这里插入图片描述
早期的光栅显示系统结构简单,主存的一部分作为帧缓存,视频控制器通过总线访问帧缓存完成屏幕的刷新。后来,帧缓存采用固定的内存区域或者采用专用的显示内存。但是扫描转换由CPU完成,CPU负担重,于是出现了GPU(图形显示处理器),他分担了CPU的图形扫描转换工作,加速了图形的渲染。
在这里插入图片描述
2.基于GLUT的OpenGL程序框架
(1)glut头文件
在这里插入图片描述
(2)main()函数
在这里插入图片描述
其中注册函数的参数display函数是自定义显示回调函数函数名,负责在窗口中绘制图形。注意,自定义的显示回调函数没有参数和返回值。
glutMainLoop()表示进入glut事件处理循环,窗口会一直显示并等待键盘以及其他事件的发生,一旦有事件发生,程序自动进行相应的注册回调函数,事件循环会一值执行直到用户关闭窗口。
(3)自定义显示回调函数
在这里插入图片描述
glClear函数清空原来颜色缓冲区中存储的数据,默认用黑色作为清楚颜色,一般作为显示回调函数的第一句,放在图形绘制指令之前,必须有;
glFlush函数用于清空命令缓冲区,OpenGL指令不是立刻执行,而是被送到指令缓冲区,当存储的指令达到一定数量才传到cpu执行,单缓存模式下必须调用,一般作为显示回调函数的最后一句;
图形绘制指令,glBegin与glEnd函数配对使用,glBegin的参数指定绘制图形的类型。glVertex2f用于放置顶点坐标,放于glBegin和glEnd之间。glLineWidth执行绘制颜色宽度。也可以用glPointSize指定每个点占像素个数。

添加其他内容的实例:
在这里插入图片描述
glutInitDisplayMode中的GLUT_SINGLE表示使用单缓存,GLUT_RGB表示显示RGB颜色模式而不是索引模式。
补充:这里的glutInitDisplayMode也可以使用双缓存:
在这里插入图片描述
双缓存分为前台缓存和后台缓存,前台缓存负责显示,而后台缓存缓存绘制结果,当一帧画面绘制完成后再快速交换前后台缓存,双缓存绘制的画面稳定不闪烁,所以绘制动画时一般用双缓存。使用双缓存时,在init()函数中不需要调用glFlush(),而需改用glutSwapBuffers()来交换前后台缓存。
在这里插入图片描述
glutReshapeFunc为注册窗口大小改变时的回调函数,窗口大小变化时程序会自动调用自定义函数reshape:
在这里插入图片描述
视口大小为绘制图形在窗口中的显示区域。
另一个自定义函数reshape(该函数通过窗口变化后的宽高,使用gluOrtho2D函数来改变裁剪窗体大小,从而放置图像变形):
在这里插入图片描述
3.图元光栅化
在这里插入图片描述
在这里插入图片描述
(1)直线光栅化
绘制直线时,给定起点坐标和终点坐标,利用y=kx+b来实现直线光栅化:
3.1.1公式直接绘制法
在这里插入图片描述
setpixel函数的作用是设置指定位置像素的颜色,实验中由OpenGL函数实现该功能。
3.1.2
进一步改进算法,将浮点乘法转化为加法(DDA算法):
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
以上两个单项式称为x方向和y方向上的步长或间隔,步长不能超过一个像素,步长设置原则为在坐标变化较快的方向上设置步长为1,另一个方向上步长小于1。
在这里插入图片描述
在这里插入图片描述
实例代码:
在这里插入图片描述
运行结果显示:
在这里插入图片描述
解释:以上实例并没有达到绘制直线的效果,这是资料的参考代码,笔者刚学,暂不知如何完善,可能后期修改。
在这里插入图片描述
3.1.3.中点Hresenham算法
首先讲述判断一个点与一条直线的关系的方法:
设直线方程为y-k
x-b=0,将点的坐标代入直线方程的左半部分得到结果di,若di=0,则该点位于直线上;若di>0,则该点位于直线上方;若di<0,则该点位于直线下方。
若一条直线经过两个像素之间,根据直线与两个像素的中点M之间的位置关系来选择光栅化的像素,即若中点M位于直线上方,则直线里下方的像素较近,选择下方像素为光栅化像素,否则选择上方像素。特殊情况中点M位于直线上,则任意选择一个像素,一般选择前一个光栅化像素的正右方的像素。
如下图讲述:
在这里插入图片描述
算法改进,上一次选择像素时的di值可以用于下一次的判断,即用增量的方法而不是又将中点坐标带入直线表达式:
在这里插入图片描述

进一步解释:上图中当选择了Pu像素后,由于直线斜率0<k<1,所以直线与P1,P2所在直线的交点只可能位于红线所框范围,所以只需考虑直线交点与P1,P2像素的位置,下图同理:
在这里插入图片描述

在这里插入图片描述
绘制任意斜率的直线可以计算增量表达式,也可以将直线做x=0,y=0,y=x,y=-x的对称图形将直线斜率转化为0~1,求出光栅化像素后在通过对称转化得到所需结果。
(2)圆的光栅化
中点Hresenham算法(考虑圆心在原点的圆)
因为圆具有对称性,所以只需考虑从y轴正向顺时针旋转45度的1/8圆弧,再利用对称性得出其他部分。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值