c - OpenGL 中的无限循环绘图和断线问题

标签 c opengl graphics glut infinite-loop

无限循环问题

我想要实现如图所示的效果:

enter image description here

我通过在 glutDisplayFunct 内包含一个无限循环来生成它回调函数,这不好,因为我无法处理来自键盘的任何输入。我能想到的另一种方法可能是使用 glut 的显式窗口刷新函数。

我想知道如何插入无限循环并检查键盘输入。这是我制作的示例代码。它简单地实现了DDA算法,并尝试通过生成随机坐标和颜色来绘制无限条线。

#include <stdio.h>
#include <GL/glut.h>

int width;
int height;

void dda (int x1, int y1, int x2, int y2)
{
  int del_x, del_y, sample_steps, i = 1;
  double x_incr, y_incr, x, y;

  del_x = x2 - x1;
  del_y = y2 - y1;
  sample_steps = (abs (del_x) > abs (del_y)) ? abs (del_x) : abs (del_y);

  x_incr = del_x / (double) sample_steps;
  y_incr = del_y / (double) sample_steps;

  x = x1;
  y = y1;


  glBegin (GL_POINTS);
  while (i<=sample_steps)
  {
    glVertex2f ((2.0 * x)/width, (2.0 * y)/height);
    x += x_incr;
    y += y_incr;
    i++;
  }
  glEnd ();

  glFlush ();
}

void keypress_handler (unsigned char key, int x, int y)
{
  if (key == 'q' || key == 'Q')
  {
    glutLeaveMainLoop ();
  }
}

void init_screen (void)
{
  glMatrixMode (GL_PROJECTION);
  glClearColor (0, 0, 0, 1);
  glClear (GL_COLOR_BUFFER_BIT);
  glLoadIdentity ();
  glMatrixMode (GL_MODELVIEW);
}

void test_dda (void)
{
  int x1, y1, x2, y2;
  float r, g, b;

  int i=1;

  glClear (GL_COLOR_BUFFER_BIT);
  srand (time(NULL));
  width = glutGet (GLUT_WINDOW_WIDTH);
  height = glutGet (GLUT_WINDOW_HEIGHT);

  while (i)
  {
    x1 = rand () % width  - (width  /2);  /* Global */
    y1 = rand () % height - (height /2); /* Global */
    x2 = rand () % width  - (width  /2);  /* Global */
    y2 = rand () % height - (height /2); /* Global */

    r = rand () / (float) RAND_MAX;
    g = rand () / (float) RAND_MAX;
    b = rand () / (float) RAND_MAX;

    glColor3f (r, g, b);
    dda (x1, y1, x2, y2);
    printf ("\r%d", i);
    i++;
  }

}

void reshape (int w, int h)
{
  glViewport (0, 0, w, h);
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  gluOrtho2D (-1, 1, -1, 1);
  glMatrixMode (GL_MODELVIEW);
}

int main (int argc, char *argv[])
{
  glutInit (&argc, argv);
  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
  init_screen ();
  glutCreateWindow ("DDA");
  glutDisplayFunc (test_dda);
  glutReshapeFunc (reshape);
  glutKeyboardFunc (keypress_handler);

  glutMainLoop ();

  printf ("\n");
  return 0;
}

首次绘制时的断线

我还有一个额外的问题,如下所示:

当我取消注释 while (i) 内的无限循环( test_dda )时函数并以 1280x960 屏幕尺寸运行可执行文件,每条绘制的线都显示为虚线,它们看起来像虚线。但是,如果我不在这个函数中无限循环并用其他方式绘制线条,例如强制 OpenGL 重绘,则线条将按应显示的方式显示。我注意到第一次绘图时,线条显示为断线。我所说的断线如下所示:

enter image description here

要理解我所说的内容,请执行以下操作以获得效果。更改while (i)while (i<1000) 。这将在屏幕上绘制 1000 条线。当我以 1280x960 窗口大小运行此更改时,窗口被绘制了 2 次。第一次绘制的线条显示为断线,如上图所示。当绘制完 1000 条线时,窗口会再次被清除并再次绘制,但这次线按应有的方式显示。为什么会发生这种情况。

最佳答案

你不必这样做。无限循环已经发生在 glutMainLoop() 内部。它会一遍又一遍地调用你的显示函数,直到程序关闭。要保留先前帧的输出(即在其上绘图),请不要使用 glClear() 清除颜色缓冲区。

至于折线:不要逐像素地画线。虽然我没有仔细观察,但您很可能会因 View /投影矩阵而导致一些差异(即您绘制的点间距太大)。相反,使用 OpenGL 调用来绘制线条。

您在这里尝试做的本质上是尝试在硬件加速渲染之上进行软件渲染,这很奇怪,并不真正推荐。

关于c - OpenGL 中的无限循环绘图和断线问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9077738/

相关文章:

c - 从c中的另一个文件链接静态函数

纯 C 中的 Cocoa OpenGL 窗口?

c++ - 纯 C 语言中的 glRotatef

java - 设置 JFrame 的背景颜色

c - C中的链表,名称覆盖

C 链表初始化

C++ std::string to char 用于 OpenGL LoadBMP

python - 设置 tkinter 窗口的坐标

opengl - 在图形上下文中,术语 "rubberbanding"是什么意思?

c - 查找频繁出现元素的总数