C OpenGL中的无限循环绘制与断线问题 无限循环问题

C OpenGL中的无限循环绘制与断线问题 无限循环问题,c,opengl,graphics,glut,infinite-loop,C,Opengl,Graphics,Glut,Infinite Loop,我想达到如图所示的效果: 我通过在glutDisplayFunct回调函数中包含一个无限循环来生成这个函数,这不好,因为我无法处理来自键盘的任何输入。我能想到的另一种方法可能是使用glut的显式窗口刷新函数 我想知道如何插入无限循环并检查键盘输入。这是我制作的示例代码。它简单地实现了DDA算法,并试图通过生成随机坐标和颜色来绘制无限长的直线 #include <stdio.h> #include <GL/glut.h> int width; int height;

我想达到如图所示的效果:

我通过在
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;
}
#包括
#包括
整数宽度;
内部高度;
无效dda(整数x1、整数y1、整数x2、整数y2)
{
int del_x,del_y,示例步骤,i=1;
双x_增量,y_增量,x,y;
del_x=x2-x1;
del_y=y2-y1;
样本步数=(abs(delux)>abs(deluy))?abs(delux):abs(deluy);
x_incr=del_x/(双)采样步数;
y_incr=del_y/(双)采样步骤;
x=x1;
y=y1;
glBegin(总分);

while(i您不必。无限循环已经在
glutMainLoop()
中发生。它将反复调用您的显示函数,直到程序关闭。要保持前一帧的输出(即绘制在它们上面),请不要使用
glClear()
清除颜色缓冲区

至于虚线:不要一个像素一个像素地画线。虽然我没有仔细观察,但你很可能会因为你的视图/投影矩阵(即你画的点间距太大)而产生一些差异。相反,使用OpenGL调用来画线


您在这里尝试做的基本上是在硬件加速渲染的基础上进行软件渲染,这很奇怪,并不推荐使用。

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

至于虚线:不要一个像素一个像素地画线。虽然我没有仔细观察,但你很可能会因为你的视图/投影矩阵(即你画的点间距太大)而产生一些差异。相反,使用OpenGL调用来画线


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

我认为您采用的初始解决方案在概念上是错误的

不要对我不好:)

如果重点是不断地反复画线,一个可能的解决方案是以这种方式分割流程:

  • 帧1步骤1:在帧缓冲区上绘制线,该帧缓冲区映射到包含工作纹理的四边形上的纹理
  • 第1帧第2步:使用工作纹理绘制四边形
  • GLUT输入回调
  • 第2帧第1步:在帧缓冲区上绘制线,该帧缓冲区映射到包含工作纹理的四边形上的纹理
  • 第1帧第2步:绘制具有输出工作纹理的四边形
  • GLUT输入回调

等等……

我认为您采用的初始解决方案在概念上是错误的

不要对我不好:)

如果重点是不断地反复画线,一个可能的解决方案是以这种方式分割流程:

  • 帧1步骤1:在帧缓冲区上绘制线,该帧缓冲区映射到包含工作纹理的四边形上的纹理
  • 第1帧第2步:使用工作纹理绘制四边形
  • GLUT输入回调
  • 第2帧第1步:在帧缓冲区上绘制线,该帧缓冲区映射到包含工作纹理的四边形上的纹理
  • 第1帧第2步:绘制具有输出工作纹理的四边形
  • GLUT输入回调
以此类推……

每次需要重新绘制窗口时都会调用“display”函数(
test\u dda

改为使用计时器,在计时器函数中画一条线,然后调用函数强制GLUT重新绘制窗口,在窗口中“刷新”GL管道。

显示功能(
测试dda
)每次需要重新绘制窗口时都会调用。如果您在display函数中处于无限循环中,GLUT中的事件处理代码不会改变运行


相反,使用计时器,在计时器函数中画一条线,然后调用函数强制GLUT重新绘制窗口,在窗口中“刷新”GL管道。

代码的主要目标是手动实现画线算法,而不是使用内部例程。我使用的算法是非常基本的算法(DDA),并且运行良好。对于dely/delx<1的线,像素的绘制间距不会太大,在X方向上采样并获得Y,而对于>1则相反。因此绘制的线是连续的,不会有任何间隙。另一方面,显示功能不会被反复绘制,例如,当我最小化windo时w它正在被重新绘制,或者当我调整窗口大小时,它正在被重新绘制,并且绘制速度非常慢(与
while(1)
循环中的情况不同。您必须强制重新绘制,例如,只需调用
glutPostRedisplay()
完成渲染后,重新绘制下一次迭代/帧。此外,我知道您使用的算法,但我猜仍然会出现间隙,因为这种方法不适合在此处使用(例如,它更适合直接像素操作)。间隙可能是由舍入引起的(您是否尝试过
glSmooth()
?).但问题是,当我打印像素值(数字)时,它们显示为相邻的绘图。Als