在openGL下使用DDA动态绘制一条线

时间:2016-09-29 02:30:58

标签: c++ opengl

我是openGL的新手,我正在学习DDA算法。基本上它只是使用glVertex2i(x, y)绘制很多点甚至是一条线。

现在我想实现动态效果。所以我在每次绘制一个点后添加sleep(0.5)语句延迟0.5秒,但结果并不好。结果只是空白一段时间,突然出现了整条线。

我也尝试以下方法:

void delay(unsigned int mseconds)
{
    clock_t goal = mseconds + clock();
    while (goal > clock());
}

结果相同,画布最初会空白一段时间。

还有其他延迟方法吗?

这是我的代码:

#include <GL/glut.h>
#include <iostream>
#include <math.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include<time.h>

using namespace std;

void delay(unsigned int mseconds)
{
    clock_t goal = mseconds + clock();
    while (goal > clock());
}

float xs = 0.0;
float ys = 0.0;
float xe = 0.0;
float ye = 0.0;

void LineDDA(int x0, int y0, int x1, int y1)
{
    float x = 0.0;
    float y = 0.0;
    float m = 0.0;
    float dx = x1 - x0;
    float dy = y1 - y0;
    if (dx != 0)
    {
        m = dy/dx;
        if (m <= 1 && m >= -1)
        {
            y = y0;
            for (x = x0; x <= x1; x++)
            {
                glVertex2i(x, int(y+0.5));
                delay(2000);
                y += m;
            }
        }
        if (m>1 || m<-1)
        {
            m = 1/m;
            x = x0;
            for (y=y0; y<=y1; y++)
            {
                glVertex2i(int(x+0.5), y);
                delay(2000);
                x += m;
            }
        }
    }
    else
    {
        int x = x0;
        int y = 0;
        y = (y0 <= y1) ? y0 : y1;
        int d = fabs((double) (y0 - y1));
        while (d >= 0)
        {
            glVertex2i(x, y);
            delay(2000);
            y++;
            d--;
        }
    }
}

void lineSegment()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_POINTS);

    // Make sure changes appear onscreen
    glutSwapBuffers();

    LineDDA(xs, ys, xe, ye);
    glEnd();
    glFlush();
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
    cout << "input the start and end(range is 0-500, 0-500):";
    cin >> xs >> ys >> xe >> ye;
    glutInitWindowPosition(50, 100);
    glutInitWindowSize(500, 500);
    glutCreateWindow("DDA Algothrim");
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, 500, 0.0, 500.0);


    glutDisplayFunc(lineSegment);

    glutMainLoop();

    return 0;
}

以下是我如何运行它:

lzc@lzc-ubuntu:~/Workspace/Languages/openGL$ g++ dda.cpp -lglut -lGLU -lGL -lm
lzc@lzc-ubuntu:~/Workspace/Languages/openGL$ ./a.out 
input the start and end(range is 0-500, 0-500):0 0 200 300

我的g ++版本是:gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.2)

1 个答案:

答案 0 :(得分:0)

我假设您的意图是将线条绘制为动画。为此,您应该使用计时器。使用GLUT,我们有两种方法将计时器合并到显示代码中。

  1. glutIdleFunc
    这很简单:只需将显示功能作为参数,在您的情况下,lineSegment
    这种方法的局限性在于我们无法控制定时器的滴答频率。如果我们确实想设置自己的滴答频率,我们需要使用第二种方法。
  2. glutTimerFunc
    它需要输入频率来触发每个回调(以毫秒为单位)以及回调函数指针。
    在这两种方法中,您需要修改显示功能以增加每个滴答的值;在您的情况下,要绘制的点的索引。