CG_实验2_基本图形元素(直线)生成算法的实现
计算机图形学实验二:直线的生成算法的实现

实验二: 直线的生成算法的实现班级 08信计2班学号 20080502055 姓名分数一、实验目的和要求:1.理解直线生成的原理;2.掌握几种常用的直线生成算法;3.利用C实现直线生成的DDA算法。
二、实验内容:1.了解直线的生成原理2、掌握几种基本的直线生成算法: DDA画线法、中点画线法、Bresenham画线法。
3、仿照教材关于直线生成的DDA算法, 编译程序。
4.调试、编译、运行程序。
三、实验过程及结果分析1.直线DDA算法:算法原理:已知过端点P0(x0,y0), P1(x1,y1)的直线段L(P0,P1), 斜率为k=(y1-y0)/(x1-x0), 画线过程从x的左端点x0开始, 向x右端点步进, 步长为1个像素, 计算相应的y坐标为y=kx+B。
计算y i+1 = kx i+B=kx i +B+kx=y i +kx当x=1,yi+1=yi+k, 即当x每递增1, y递增k。
由计算过程可知, y与k可能为浮点数, 需要取y整数, 源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。
(1)程序代码:#include"stdio.h"#include"graphics.h"void linedda(int x0,int y0,int x1,int y1,int color){int x,dy,dx,y;float m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color);y+=m;setbkcolor(7);}}main(){int a,b,c,d,e;int graphdriver=DETECT;int graphmode=0;initgraph(&graphdriver,&graphmode,"");a=100;b=100;c=200;d=300;e=5;linedda(a,b,c,d,e);getch();closegraph();}运行结果:2.中点画线算法:假定所画直线的斜率为k∈[0,1], 如果在x方向上增量为1, 则y方向上的增量只能在0~1之间。
CG第3章基本图形生成算法C课件

int dy=yr-y1, dx=xr-x1;
int ie;
/* integer scaled error term */
x=xl; y=yl; /* start at left endpoint */
ie =dx-2 *dy; /* initialize the error term */
while (x <= xr){ /* pixel-drawing loop */
2024/2/22
16
0≤m≤1时Bresenham算法的步骤为:
1. 输入直线的两端点P0(x0,y0)和P1(x1,y1)。
2. 计算初始值△x, △y, d=Δx-2Δy , x=x0, y=y0;
3. 绘制点(x,y),根据d的符号进行如下操作: 若d<0,则(x,y)更新为(x+1,y+1),d更新为
yi1
yi yi
1
(di 0) (di 0)
Pa (xi 1, yi 1)
Q
问题:算法结束了吗? 有无优化的可能?
M (xi 1, yi 1/ 2)
P(xi , yi ) Pb (xi 1, yi )
注意:计算di 的运算量并不小.
2024/2/22
12
误差项的递推 若di<0,有
di1 F ( xi 2, yi 1.5) yi 1.5 m(xi 2) b yi 1.5 m(xi 1) b m di 1 m
M (xi 2, yi 1.5)
Q
M (xi 1, yi 0.5)
P(xi , yi )
2024/2/22
di<0
13
误差项的递推 若di≥0,有
di1 F (xi 2, yi 0.5) yi 0.5 m(xi 2) b yi 0.5 m(xi 1) b m di m
计算机图形学--直线段生成绘制的实现算法

实验二直线段生成绘制的实现算法班级 08信计(2)班学号 20080502085 姓名王景超分数一、实验目的和要求:1.理解基本图形元素光栅化的基本原理2. 掌握一种基本图形元素光栅化算法3. 利用OpenGL实现直线光栅化的DDA算法二、实验内容:1. 根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果;2. 指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告;3. 根据示范代码,将其改造为圆的光栅化算法,写入实验报告;4. 了解和使用OpenGL的生成直线的命令,来验证程序运行结果。
三、实验结果分析:1.该程序实现了三种算法的直线段绘制2.比较三种算法的结果:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法程序代码如下:/* WIN-TC BGI 图形编程模板*/#include "Conio.h"#include "graphics.h"#define closegr closegraphvoid initgr(void) /* BGI初始化*/{int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果*/registerbgidriver(EGA VGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行*/initgraph(&gd, &gm, "");}/*-----------------------------数值微分法生成直线-----------------------------*/ void LineDDA1(int x0,int y0,int x1,int y1,int color)/*假定x0<x1,直线斜率m<-1*/{int y;float dy,dx,x,m;dx=x1-x0;dy=y1-y0;m=dx/dy;x=x0;for(y=y0;y>=y1;y--){putpixel((int)(x+0.5),y,color);x-=m;}}void LineDDA2(int x0,int y0,int x1,int y1,int color)/*假定x0<x1,直线斜率-1<=m<=1*/{int x;float dy,dx,y,m;dx=x1-x0;dy=y1-y0;m=dy/dx;y=y0;for(x=x0;x<=x1;x++){putpixel(x,(int)(y+0.5),color);y+=m;}}void LineDDA3(int x0,int y0,int x1,int y1,int color)/*假定x0<x1,直线斜率m>1*/{int y;float dy,dx,x,m;dx=x1-x0;dy=y1-y0;m=dx/dy;x=x0;for(y=y0;y<=y1;y++){putpixel((int)(x+0.5),y,color);x+=m;}}/*----------------------------中点算法生成直线--------------------------------*/ void MidPointLine1(int x0,int y0,int x1,int y1,int color){ /*假定x0<x1,直线斜率m<-1*/int dx,dy,incrE,incrNE,d,x,y;dx=x1-x0;dy=y1-y0;d=-2*dx-dy;incrE=-2*dx;incrNE=-2*(dx+dy);x=x0;y=y0;putpixel(x,y,color);while(y>=y1){if(d>0)d+=incrE;else{ d+=incrNE;x++;}y--;putpixel(x,y,color);}}void MidPointLine2(int x0,int y0,int x1,int y1,int color) { /*假定x0<x1,直线斜率-1<m<0*/int dx,dy,incrE,incrNE,d,x,y;dx=x1-x0;dy=y1-y0;d=-(dx+2*dy);incrE=-2*dy;incrNE=-2*(dx+dy);x=x0;y=y0;putpixel(x,y,color);while(x<x1){if(d<=0)d+=incrE;else{ d+=incrNE;y--;}x++;putpixel(x,y,color);}}void MidPointLine3(int x0,int y0,int x1,int y1,int color) { /* 假定x0<x1,直线斜率0<=m<=1 */int dx,dy,incrE,incrNE,d,x,y;dx=x1-x0;dy=y1-y0;d=dx-2*dy;incrE=-2*dy;incrNE=2*(dx-dy);x=x0;y=y0;putpixel(x,y,color);while(x<x1){if(d>0) d+=incrE;else{d+=incrNE;y++;}x++;putpixel(x,y,color);}}void MidPointLine4(int x0,int y0,int x1,int y1,int color){ /*假定x0<x1,直线斜率m>1*/int dx,dy,incrE,incrNE,d,x,y;dx=x1-x0;dy=y1-y0;d=2*dx-dy;incrE=2*dx;incrNE=2*(dx-dy);x=x0;y=y0;putpixel(x,y,color);while(x<x1){if(d<=0)d+=incrE;else{ d+=incrNE;x++;}y++;putpixel(x,y,color);}}/*-------------------------Bresenham算法生成直线-----------------------------*/ BresenhamLine(int x0,int y0,int x1,int y1,int color){int x,y,dx,dy,i;float m,d;dx=x1-x0;dy=y1-y0;m=dy/dx;d=0;x=x0;y=y0;putpixel(x,y,color);for(i=0;i<=dx;i++){d+=m;if(d>=0.5){y+=1;d-=1;}x++;putpixel(x,y,color);}}/*-------------------------------建立坐标系----------------------------------*/ void LineH(int x0,int x1,int y0,int color){int x,y;x=x0; y=y0;while(x<x1){putpixel(x,y,color);x++;}}void LineV(int y0,int y1,int x0,int color){int x,y;x=x0; y=y0;while(y<y1){putpixel(x,y,color);y++;}}int x0,y0,x1,y1,color,dx1,dy1;float m;int main(void){initgr(); /* BGI初始化*//*****此部分添加你自己的代码,例如line(25, 25, 220, 220);circle(100, 100, 50);等等*****//*-------------------------显示各种斜率的直线--------------------------------*/ MidPointLine1(300,400,340,240,125);MidPointLine2(240,340,400,300,255);MidPointLine3(240,300,400,340,255);MidPointLine4(300,240,340,400,255);LineH(240,400,320,255);LineV(240,400,320,255);outtextxy(398,318,">");outtextxy(280,420,"MidPointLine");LineDDA1(180,280,220,120,125);LineDDA2(120,220,280,180,255);LineDDA2(120,180,280,220,255);LineDDA3(180,120,220,280,255);LineH(120,280,200,255);LineV(120,280,200,255);outtextxy(180,300,"LineDDA");BresenhamLine(322,53,430,182,255);outtextxy(330,160,"Bresenham");/*----------------------------程序输入部分-----------------------------------*/ printf("firstpoint x0,y0:\n");scanf("%d,%d",&x0,&y0);printf("lastpoint x1,y1:\n");scanf("%d,%d",&x1,&y1);printf("color:\n");scanf("%d",&color);dx1=x1-x0;dy1=y1-y0;m=dy1/dx1;if(m<-1)MidPointLine1(x0,y0,x1,y1,color);else if(m>=-1&&m<0)MidPointLine2(x0,y0,x1,y1,color) ;else if(m>=0&&m<=1)MidPointLine3(x0,y0,x1,y1,color) ;elseMidPointLine4(x0,y0,x1,y1,color) ;getch(); /* 暂停一下,看看前面绘图代码的运行结果*/ closegr(); /* 恢复TEXT屏幕模式*/return 0;}运行结果:。
计算机图形学实验二 直线的生成算法的实现

实验二直线的生成算法的实现班级 08信计二班学号 20080502086 姓名分数一、实验目的和要求:1、理解直线生成的基本原理2、熟悉直线的生成算法,掌握直线的绘制3、实现直线生成的DDA 中点画法 Bresenham算法4、了解Visual C++等编程环境中常用控件命令与绘图函数,初步掌握在试验设计集成下进行图形处理程序的设计方法二、实验内容:1、了解直线生成的原理直线DDA算法,中点画线算法,Bresenham画线算法2、编程实现DDA算法、Bresenham算法、中点画法绘制直线段三、实验结果分析1.DDA算法// 程序名称:基于 DDA 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 四舍五入int Round(float x){return (int)(x < 0 ? x - 0.5 : x + 0.5);}// 使用 DDA 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_DDA(int x1, int y1, int x2, int y2, int color){float x, y; // 当前坐标点float cx, cy; // x、y 方向上的增量int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);x = (float)x1;y = (float)y1;cx = (float)(x2 - x1) / steps;cy = (float)(y2 - y1) / steps;for(int i = 0; i < steps; i++){putpixel(Round(x), Round(y), color); // 在坐标 (x, y) 处画一个 color 颜色的点x += cx;y += cy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_DDA(100, 1, 1, 478, GREEN);Line_DDA(1, 478, 638, 1, GREEN);// 按任意键退出getch();closegraph();}2.中点算法// 程序名称:基于中点算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Midpoint(int x1, int y1, int x2, int y2, int color){int x = x1, y = y1;int a = y1 - y2, b = x2 - x1;int cx = (b >= 0 ? 1 : (b = -b, -1));int cy = (a <= 0 ? 1 : (a = -a, -1));putpixel(x, y, color);int d, d1, d2;if (-a <= b) // 斜率绝对值 <= 1{d = 2 * a + b;d1 = 2 * a;d2 = 2 * (a + b);while(x != x2){if (d < 0)y += cy, d += d2;elsed += d1;x += cx;putpixel(x, y, color);}}else // 斜率绝对值 > 1{d = 2 * b + a;d1 = 2 * b;d2 = 2 * (a + b);while(y != y2){if(d < 0)d += d1;elsex += cx, d += d2;y += cy;putpixel(x, y, color);}}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Midpoint(100, 1, 1, 478,YELLOW);Line_Midpoint(1, 478, 638, 1, YELLOW);// 按任意键退出getch();closegraph();}3. Bresenham 算法// 程序名称:基于 Bresenham 算法画任意斜率的直线#include <graphics.h>#include <conio.h>// 使用 Bresenham 算法画任意斜率的直线(包括起始点,不包括终止点)void Line_Bresenham(int x1, int y1, int x2, int y2, int color){int x = x1;int y = y1;int dx = abs(x2 - x1);int dy = abs(y2 - y1);int s1 = x2 > x1 ? 1 : -1;int s2 = y2 > y1 ? 1 : -1;bool interchange = false; // 默认不互换 dx、dyif (dy > dx) // 当斜率大于 1 时,dx、dy 互换{int temp = dx;dx = dy;dy = temp;interchange = true;}int p = 2 * dy - dx;for(int i = 0; i < dx; i++){putpixel(x, y, color);if (p >= 0){if (!interchange) // 当斜率 < 1 时,选取上下象素点y += s2;else // 当斜率 > 1 时,选取左右象素点x += s1;p -= 2 * dx;}if (!interchange)x += s1; // 当斜率 < 1 时,选取 x 为步长elsey += s2; // 当斜率 > 1 时,选取 y 为步长p += 2 * dy;}}// 主函数void main(){initgraph(640, 480);// 测试画线Line_Bresenham(100, 1, 1, 478, RED);Line_Bresenham(1, 478, 638, 1, RED);// 按任意键退出getch();closegraph();}实验结果分析三种算法运算结果比较:像素逼近效果由好到差依次为:B算法、DDA算法、中点算法执行速度由快到慢依次为:中点算法、DDA算法、B算法。
CG02图形基础算法

算法原理
选择表示直线的最佳像素的位置,即用 最靠近直线的网格点来代表这一直线。根据 直线的斜率确定或选择变量x或y每次递增一 个单位,另一个变量y或x每次增量为0或1, 这取决于理论直线段与最近像素点的距离。 避免了低效率的取整运算。
y 设直线段的斜率m∈[0,1](即倾角≦45°)其 中m=≨y/≨x,则要生成的直线的微分方程为: Yi+1,ri yi - 1
Pu(x i+1,y i)
(d1 0) (d1 0)
(3-17)
P(xi,yi)
M(x i+1,y i-0.5) Pd(x i+1,yi-1)
x
图3-13 上半部分像素点的选取
上半部分Ⅰ的递推公式
图3-13中,为了能够继续判断椭圆上的每个点,需要给 出中点偏差判别式d1的递推公式和初始值。
A(0,b)
y向分量 法矢量 C( a 2 /
a 2 b2 , b 2 / a 2 b 2
)
x向分量 B(a,0)
椭圆的中点Bresenham算法的原理:在部分Ⅰ:每次在 主位移x方向上走一步,y方向上退不退步取决于中点偏差判别 式的值;在部分Ⅱ:每次在主位移方向y上退一步,x方向上走 不走步取决于中点偏差判别式的值。
Pk(xk,yk) Pu(xk+1,yk)
M
Pb(xk+1,yk-1)
≥0
f(M)= <0
M点在圆外,取Pb
M点在圆内,取Pu
Bresenham生成圆弧算法
A 我们仍讨论第二个1/8圆。设有半径为R圆心在 坐标原点。 AB为第二个1/8圆的圆弧,圆的方程为: R
x2+y2=R2
Pi-1(xi-1,yi-1)是已选中的点,则下一个点应在 Hi(xi,yi-1)和Li(xi,yi-1-1)选取。 设有圆弧S满足: xHi2+yHi2-Rs2+ xLi2+yLi2-Rs2=0 2-18
直线生成算法的实现

实验二:直线生成算法班级 13软件+道铁1班学号 20132110050115姓名丁益1.实验目的a)通过实验,进一步理解直线段扫描转换的DDA算法、中点画线自算法及bresenham算法的基本原理,掌握以上算法生成直线段的基本过程。
b)通过编程,掌握在C/C++环境下完成用DDA算法、中点画线算法及bresenham算法对任意直线段的扫描转换,以及在C/C++环境下完成用中点画圆及椭圆的绘制方法。
2.实验内容c)阅读《openGL三维程序设计》(电子书)第二部分第四章,掌握OpenGL基本建模方法,并调试其中程序。
d)参考教材第6章,编程实现整数DDA算法、中点画线法和Bresenham画线法,绘制直线(直线宽度和线型可自定)。
2.1 DDA直线生成2.1.1算法原理已知过端点P0(x0,y0),P1(x1,y1)的直线段L(P0,P1),斜率为k=(y1-y0)/(x1-x0),画线过程从x的左端点x0开始,向x右端点步进,步长为1个像素,计算相应的y坐标为y=kx+B。
计算y i+1 = kx i+B=kx i +B+kx=y i +kx当x=1,y i+1=y i+k,即当x每递增1,y递增k。
由计算过程可知,y与k可能为浮点数,需要取y整数,源程序中round(y)=(int)(y+0.5)表示y四舍五入所得的整数值。
2.1.2 算法流程2.1.3 算法实现关键代码#include<GL/glut.h>#include<math.h>void Init(){glClearColor(1.0,1.0,1.0,0.0);glMatrixMode(GL_PROJECTION);gluOrtho2D(0.0,200.0,0.0,150.0);}void lineDDA(int x0,int y0,int xEnd,int yEnd){int dx=xEnd-x0,dy=yEnd-y0,steps,k;float xIncrement, yIncrement, x=x0, y=y0;if(fabs(dx)>fabs(dy))steps=fabs(dx);elsesteps=fabs(dy);xIncrement=float(dx)/float(steps);yIncrement=float(dy)/float(steps);for(k=0;k<steps;k++){x+=xIncrement;y+=yIncrement;glBegin(GL_POINTS);glVertex2i(x,(int)(y+0.5));glEnd();}glFlush();}void myDisplay(void){glClear(GL_COLOR_BUFFER_BIT);glColor3f(1.0,0.0,0.0);lineDDA(50,50,100,120);}int main(int argc,char** argv){glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutInitWindowPosition(100,100);glutInitWindowSize(400,400);glutCreateWindow("Hello World");Init();glutDisplayFunc(myDisplay);glutMainLoop();return 0;}2.1.4算法运行示例及中间结果2.2 Brese nham直线生成2.2.1算法原理Bresenham算法的基本原理是:过各行各列像素中心构造一组虚拟网格线,按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
精品课件-计算机图形学-第3章 基本图形元素生成算法

第 3 章 基本图形元素生成算法
图3.1 中点画线示意图
第 3 章 基本图形元素生成算法
设Q是理想直线与垂直线x=xP+1的交点。 若M 在Q的下方, 则P2离理想直线近, 应取为下一个像素; 否 则应取P1。 为此, 我们构造判别式
d=F(M)=F(xP+1,yP+0.5)=a(xP+1)+b(yP+0.5)+c 当d<0时, M在直线下方, 应取右上方的P2作为下 一个像素; 当d>0时, M在直线上方, 则应取正右方的P1; 当d=0时, 约定取正右方的P1。
根据以上分析, 可得中点画圆法算法如下: void MidPoint -Circle(r, color) int r, clor; { int x, y;
float d; x=0; y=r; d=1.25-r; putpixel(x, y, color); while(x<y)
{ if(d<0) { d+=2*x+3; x++; }
float k, e; dx=x1-x0; dy=y1-y0; k=dy/dx; e=-0.5; x=x0; y=y0;
第 3 章 基本图形元素生成算法
for(i=0; i<=dy; i++) { putpixel(x, y, color); x=x+1; e=e+k; if(e>=0){ y=y+1; e=e-1; } }
第 3 章 基本图形元素生成算法
x++; }
else { e+=(deltax+deltay); deltax+=2; deltay+=2; x++; y--; }
基本图形元素的生成算法

计 算 机 图 形 学
第三章 基本图形元素的生成算法
计 算 机 图 形 学
光栅显示器上显示的图形,称之为光栅图形。光 栅显示器可以看作是一个象素矩阵,在光栅显 示器上显示的任何一个图形,实际上都是一些 像素的集合。由于对一个具体的光栅显示器来 说,象素个数是有限的,象素的颜色和灰度等 级也是有限的,象素是有大小的,所以光栅图 形只是近似的实际图形。如何使光栅图形最完 美地逼近实际图形,便是光栅图形学要研究的 内容。确定最佳逼近图形的像素集合的过程称 为图形的扫描转换或光栅化。
计 算 机 图 形 学
第三章 基本图形元素的生成算法
a)
b)
图3.2 直线的生成
c)
计 算 机 图 形 学
直线的绘制首先要考虑的是绘制的质量。怎样才算高质量? 当然,看上去要象直线。 : 1. 画的直线应是直的 2. 线的端点位置应正确 3. 线的浓度应均匀 4. 直线生成的速度要快
第三章 基本图形元素的生成算法
(X1,Y1)的像素点,对应的显示缓冲器地址为: 字节地址= S + ( H / 8 ) * Y1 + ( X1 / 8 ) 的整数部分 字节内的位地址= X1 / 8 的余数 计 算 机 图 形 学
第三章 基本图形元素的生成算法
3.1.2 直线段的生成
数学上的直线是由无数个点构成的集合,显 然,光栅显示器只能近地似显示直线。对 于水平、垂直和45°斜线是可以达到较为 满意的效果的。当我们对直线进行光栅化 时,需要确定最佳逼近该直线的一组象素。 扫描转换直线段就是计算出落在直线段上 或充分靠近它的一串像素,并以此像素近 似代替原连续直线段在屏幕上显示的过程。
第三章 基本图形元素的生成算法
3.1直线的生成算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二基本图形元素(直线)生成算法的实现
1.实验目的:
理解基本图形元素光栅化的基本原理,掌握一种基本图形元素光栅化算法,利用OpenGL实现直线光栅化的DDA算法。
2.实验内容:
(1)根据所给的直线光栅化的示范源程序,在计算机上编译运行,输出正确结果;
(2)指出示范程序采用的算法,以此为基础将其改造为中点线算法或Bresenham算法,写入实验报告;
(3)根据示范代码,将其改造为圆的光栅化算法,写入实验报告;
(4)了解和使用OpenGL的生成直线的命令,来验证程序运行结果。
3.实验原理:
示范代码原理参见教材直线光栅化一节中的DDA算法。
下面介绍下OpenGL画线的一些基础知识和glutReshapeFunc()函数。
(1)数学上的直线没有宽度,但OpenGL的直线则是有宽度的。
同时,OpenGL的直线必须是有限长度,而不是像数学概念那样是无限的。
可以认为,OpenGL的“直线”概念与数学上的“线段”接近,它可以由两个端点来确定。
这里的线由一系列顶点顺次连结而成,有闭合和不闭合两种。
前面的实验已经知道如何绘“点”,那么OpenGL是如何知道拿这些顶点来做什么呢?是一个一个的画出来,还是连成线?或者构成一个多边形?或是做其它事情呢?为了解决这一问题,OpenGL要求:指定顶点的命令必须包含在glBegin函数之后,glEnd函数之前(否则指定的顶点将被忽略),并由glBegin来指明如何使用这些点。
例如:
glBegin(GL_POINTS);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.5f, 0.0f);
glEnd();
则这两个点将分别被画出来。
如果将GL_POINTS替换成GL_LINES,则两个点将被认为是直线的两个端点,OpenGL将会画出一条直线。
还可以指定更多的顶点,然后画出更复杂的图形。
另一方面,glBegin 支持的方式除了GL_POINTS和GL_LINES,还有GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,
GL_TRIANGLE_FAN等,每种方式的大致效果见下图:
图B-2 OpenGL几何图元类型
(2)首次打开窗口、移动窗口和改变窗口大小时,窗口系统都将发送一个事件,以通知程序员。
如果使用的是GLUT,通知将自动完成,并调用向glutReshapeFunc()注册的函数。
该函数必须完成下列工作:Ÿ 重新建立用作新渲染画布的矩形区域;
Ÿ 定义绘制物体时使用的坐标系。
如:
void Reshape(int w, int h)
{// 设置视口大小为整个窗口大小
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
// 单位化投影矩阵。
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// 定义二维正视投影矩阵
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
在GLUT内部,将给该函数传递两个参数:窗口被移动或修改大小后的宽度和高度,单位为像素。
glViewport()调整像素矩形,用于绘制整个窗口。
接下来三个函数调整绘图坐标系,使左下角位置为(0,0),右上角为(w, h)。
4.实验代码:
#include <GL/glut.h>
void LineDDA(int x0,int y0,int x1,int y1/*,int color*/)
{ //
int x, dy, dx, y;
float m;
dx=x1-x0;
dy=y1-y0;
m=dy/dx;
y=y0;
glColor3f (1.0f, 1.0f, 0.0f);
glPointSize(1);
for(x=x0;x<=x1; x++)
{
glBegin (GL_POINTS);
glVertex2i (x, (int)(y+0.5));
glEnd ();
y+=m;
}
}
void myDisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f (1.0f, 0.0f, 0.0f);
glRectf(25.0, 25.0, 75.0, 75.0);
glPointSize(5);
glBegin (GL_POINTS);
glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.0f, 0.0f); glEnd ();
LineDDA(0, 0, 200, 300);
glBegin (GL_LINES);
glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (100.0f, 0.0f);
glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (180.0f, 240.0f);
glEnd ();
glFlush();
}
void Init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
void Reshape(int w, int h)
{// 设置视口大小为整个窗口大小
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
// 单位化投影矩阵。
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("Hello World!");
Init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(Reshape);
glutMainLoop();
return 0;
}
注:glShadeModel选择平坦或光滑渐变模式。
GL_SMOOTH为缺省值,为光滑渐变模式,GL_FLAT为平坦渐变模式。
5.思考题
示范代码有个小错误,能否指出并改正?请将结果写入实验报告。