0

我现在的程序中有什么: - 单击鼠标时,会创建一个形状对象并将其存储在一个数组中。构造函数还将刚刚创建的对象绘制到屏幕上。第一次单击创建一个矩形,第二次单击创建一个圆形,第三次单击返回一个矩形,等等。 - 数组是圆形的,所以当它达到最大值时它会返回并用下一个形状替换第一个形状。

我的程序是我尝试使用 for 循环一次显示 25 个这些形状,如下所示:

for (int i = 0; i < obj_count; i++) {
  if (objects[i].type == 0) {
      objects[i].drawRect();
  } else if (objects[i].type == 1) {
      objects[i].drawCirc();
  }
}

但是当我运行它时,有很多闪烁,一次只出现一个矩形和一些圆圈。如果我只尝试使用 if 语句一次显示一个形状来绘制数组中的最后一个形状,那么它工作正常,所以我不确定问题出在哪里。

其余相关代码在这里:

void my_display(void) {
glClear(GL_COLOR_BUFFER_BIT) ;

for (int i = 0; i < obj_count; i++) {
      if (objects[i].type == 0) {
      objects[i].drawRect();
     } else if (objects[i].type == 1) {
      objects[i].drawCirc();
     }
 }  

glutSwapBuffers();  
return ;
}

void my_TimeOut(int id) { 
time += 1;
my_display();
glutTimerFunc(25, my_TimeOut, 0);
}

(计时器最终将用于使形状移动)

在对象类中:

void A1_Object::drawRect() {
//   glClear(GL_COLOR_BUFFER_BIT) ;
         glColor3f(0,0,1) ;
         glRectf(vertices[0], vertices[1], vertices[2], vertices[3]);
         glutSwapBuffers();
}

void A1_Object::drawCirc() {
//   glClear(GL_COLOR_BUFFER_BIT) ;
         glColor3f(1,0,0) ;

         int triangles = 50;
         GLfloat radius = 0.05; 
         GLfloat twoPi = 2 * 3.14159f;

         glBegin(GL_TRIANGLE_FAN);
            glVertex2f(center_x, center_y); 

            for (int i = 0; i <= triangles; i++) {
                glVertex2f(center_x + radius*cos(i*twoPi/triangles),     center_y + radius*sin(i*twoPi/triangles));
            }

        glEnd();            
//      glutSwapBuffers();
}

如果有人能指出我正确的方向,那就太好了!如果需要,我也可以发布完整的代码。

4

1 回答 1

2

更新和绘制场景是两件非常不同的事情。您需要了解每个框架如何处理这两个应用程序事件。在某些情况下,OpenGL 在它自己的线程中运行,从另一个线程调用任何“gl”方法都会中断调用。

但我离题了。这是我关于你的冲突问题的 0.02 美元:

顺序、结构和形式很重要!

glutTimerFunc - 为循环的 UPDATE 部分设计 - 在那里调用 glutSwapBuffers 充其量是有问题的。

通常使用 GLUT 时的回调订阅就像

glutDisplayFunc(display);           // opengl drawing goes here
glutTimerFunc(33, update_world, 0); // physics, ai, other stuff here

// .. callbacks ..

glutMainLoop();

在更新方法结束时调用glutPostRedisplay()

void update_world(int data) 
{
    glutTimerFunc(33, update, 69); // call update() every 33ms

    // code to update the world

    // ..

    glutPostRedisplay(); // <== !
}

glutPostRedisplay()通过设置一个标志来告诉glutMainLoop在下一个迭代步骤中执行注册的display()方法。如果没有明确指定,GLUT 不会正确绘制下一帧。

想象一下,在示例中省略了 update_world(data) 中的 glutPostRedisplay。即使您的向量/缓冲区的位置会发生变化,您的世界也会出现冻结,没有动画!(我听到一分钱下降了吗?:))

glutPostRedisplay 使展开的 glutMainLoop 像

update_world(69);
display();
update_world(69);
display();
update_world(69);
display();

没有它, glutMainLoop 只会调用

update_world(69);
update_world(69);
update_world(69);
于 2016-02-12T22:17:01.920 回答