计算机图形学——基于glut的实验

该文介绍了如何在计算机图形学中使用GLUT库来创建OpenGL窗口,并通过DDA和中点Bresenham算法实现直线的绘制。文章详细阐述了安装配置GLUT的过程,以及两种直线算法的实现细节,包括不同斜率情况下的处理方法。
摘要由CSDN通过智能技术生成

计算机图像学——基于glut的实验

前期准备

安装配置glut

  1. 安装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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值