计算机图像学——基于glut的实验
前期准备
安装配置glut
- 安装GLUT工具包
下载地址:http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip
Windows环境下安装GLUT的步骤:
<1>将下载的压缩包解压,得到5个文件。

<2> 在VS的include文件夹中新建GL文件夹,将glut.h放到GL文件夹中。上述include文件夹的路径为VS的安装路径\Community\VC\Tools\MSVC
14.29.30133\include”。
3)glut.lib和glut32.lib放到VS的lib文件夹中的x86文件夹中。上述lib\x86文件夹的路径为VS的安装路径\Community\VC\Tools\MSVC\14.29.30133\lib\x86”。
4)glut.dll和glut32.dll放到操作系统目录下面的system32文件夹内。64位Windows系统的位置为:C:\Windows\SysWOW64。别忘记在VS中运行glut程序需要设置为X86

#include <GL/glut.h>
#include<cstdio>
#include<cmath>
#include<cstdlib>
void Reshape(int w, int h)//进行视口和窗口的转换,这一步十分重要!没有这一步,使用glVertex2i(x,y)时将可能在窗口内显示不到。
{//左下角的坐标为(0,0),右上角坐标为(w,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);//对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较固定,一般都是glutInit(&argc, argv)就行;
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色已过时)。GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("Hello Opengl!");// 根据前述设置的信息创建窗口。参数将被作为窗口的标题。注意:窗口被创建后,并不立即显示到屏幕上。需要调用glutMainLoop才能看到窗口;
glutDisplayFunc(myDisplay);//设置一个函数,当需要进行画图时,这个函数就会被调用。
glutReshapeFunc(Reshape);//进行视口和窗口的转换
glutMainLoop();//这个函数可以显示窗口,并且等待窗口关闭后才会返回
return 0;
}
①使用DDA算法画直线
在display函数中调用的DDA程序如下:
void DDA(int x0, int y0, int x1, int y1) {
glBegin(GL_POINTS);//点模式
glColor3f(1.0f, 0.0f, 0.0f);
int dx, dy, epsl, k;
float x, y, xIncre, yIncre;//xIncre:x每次走的距离
dx = x1 - x0; dy = y1 - y0;
x = x0;
y = y0;
if (abs(dx) < abs(dy)) {
epsl = abs(dx);
}
else
{
epsl = abs(dy);
}
xIncre = (float)dx / (float)epsl;
yIncre = (float)dy / (float)epsl;
for (k = 0; k <= epsl; k++) {
glVertex2i((int)(x + 0.5), (int)(y + 0.5));
x += xIncre;
y += yIncre;
}
glEnd();
glFlush();
}
②使用中点Bresenham算法
书上只给出了0<=k<=1的直线A生成算法
对于k>1直线B,我们可以根据A的算法通过交换x,y坐标轴得到。
一个简单的做法是将输入的起始点和终点坐标(x0,y0)、(x1,y1)转换为(y0,x0)、(y1,x1).这样便转化成了k<1,但这还不够,这样会画出k<1的直线,所以我们在要画点时将glVertex2i(x, y)换成glVertex2i(y, x);具体细节见代码。
对于-1<=k<0,得自己推 UpInc = -2 * dx - 2 * dy;DownInc = -2 * dy;同时注意k<-1的情况不能像k>1那样直接转换成-1<=k<0.
void MidBre(int x0, int y0, int x1, int y1) {
int UpInc, DownInc, x, y;
if (x0 > x1) {//起点在右边?交换起始点
int v = x1;
x1 = x0, x0 = v;
v = y1, y1 = y0, y0 = v;
}
int dy = y1 - y0, dx = x1 - x0;
int k = -1;
if (abs(dy) > abs(dx)) {//若|k|>1,起点和终点坐标转为(y0,x0)、(y1,x1),这样就0<=|k|<=1了,但是这样如果斜率小于-1,将会导致起始点x大于终点x改变,所以在@处交换起始点坐标并更新相关变量
int v = x0;
x0 = y0, y0 = v;
v = x1, x1 = y1, y1 = v;
dy = y1 - y0, dx = x1 - x0;//更新dx、dy;否则UpInc、DownInc不准!!
k = 1;//标记|k|>1
}
x = x0; y = y0;
if (k > 0) {
printf("h%d %d %d %d %dh\n", dx, dy, x1, y1,dx*dy);
}
glBegin(GL_POINTS);
glColor3f(1.0f, 0.0f, 0.0f);
if (dy * dx < 0) {//如果斜率<0,
if (k > 0) {//@k<-1,再次交换起始点,更新dx,dy
int v = x1;
x1 = x0, x0 = v;
v = y1, y1 = y0, y0 = v;
dy = y1 - y0, dx = x1 - x0;
x = x0; y = y0;
}
int d = -dx - 2 * dy;
UpInc = -2 * dx - 2 * dy;//如果d<0,y+=1
DownInc = -2 * dy;
while (x <= x1) {//描点完
if (k < 0) {//-1-0
glVertex2i(x, y);
}
else {
glVertex2i(y, x);
}
x++;//不管怎样,推进
if (d < 0) {
d += DownInc;
}
else {
y--;
d += UpInc;
}
}
}
else {
int d = dx - 2 * dy;//设置起始点d
UpInc = 2 * dx - 2 * dy;//如果d<0,y+=1
DownInc = -2 * dy;
while (x <= x1) {//描点完
if (k < 0) //0<=k<=1
glVertex2i(x, y);
else {
glVertex2i(y, x);
}
x++;//不管怎样,向前推进
if (d < 0) {
y++;
d += UpInc;
}
else {
d += DownInc;
}
}
}
glEnd();
glFlush();
}
该文介绍了如何在计算机图形学中使用GLUT库来创建OpenGL窗口,并通过DDA和中点Bresenham算法实现直线的绘制。文章详细阐述了安装配置GLUT的过程,以及两种直线算法的实现细节,包括不同斜率情况下的处理方法。
1万+

被折叠的 条评论
为什么被折叠?



