3d对象不会在for循环中更新

时间:2013-09-09 10:46:52

标签: opengl 3d glkit

我正在尝试旋转3d对象,但在for循环中应用变换时它不会更新。

对象跳转到最后一个位置。

如果在for循环中不更新3d对象在更新序列中的位置,该如何更新?

3 个答案:

答案 0 :(得分:0)

只需调用glTranslate,glRotate等就不会改变屏幕上的内容。为什么?因为OpenGL是普通的绘图API,而不是场景图。所有它知道的是绘制到像素帧缓冲区的点,线和三角形。而已。您想要在屏幕上更改某些内容,您必须重绘它,即清除图片,然后再次使用更改进行绘制。

BTW:你不应该使用专用的循环来实现动画(既不是for,也不是while,也不是while)。而是在空闲处理程序中执行动画并发出重绘事件。

答案 1 :(得分:0)

我认为你对OpenGL为你做了什么有错误的理解。 我将尝试概述:

- Send vertex data to the GPU (once) 
      (this does only specify the (standard) shape of the object)

- Create matrices to rotate, translate or transform the object (per update)
- Send the matrices to the shader (per update)
      (The shader then calculates the screen position using the original 
       vertex position and the transformation matrix)
- Tell OpenGL to draw the bound vertices (per update)

想象一下使用OpenGL进行编程就像是一个Web客户端 - 只指定请求(更改矩阵和绑定东西)是不够的,你需要显式发送请求(发送转换数据并告诉OpenGL绘制)来接收回答(在屏幕上有对象。)

答案 2 :(得分:0)

可以从循环中绘制动画。

for ( ...) {
  edit_transformation();
  draw();
  glFlush();   // maybe glutSwapBuffers() if you use GLUT
  usleep(100); // not standard C, bad
}

你画画,你刷新/交换,以确保你刚画的东西被发送到屏幕,然后你睡觉。

但是,在交互式应用程序中执行此操作不推荐。主要原因是当你处于这个循环中时,没有别的东西可以运行。您的申请将没有反应。

这就是为什么窗口系统是基于事件的。每隔几毫秒,窗口系统会ping您的应用程序,以便您可以更新状态,例如动画。这是空闲功能。当程序状态发生变化时,告诉窗口系统您想再次绘制。然后在窗口系统上调用显示功能。当系统告诉你时,你可以进行OpenGL调用。

如果您使用GLUT与窗口系统进行通信,这看起来像下面的代码。其他库like GLFW具有相同的功能。

int main() {
  ...                       // Create window, set everything up.
  glutIdleFunc(update);     // Register idle function
  glutDisplayFunc(display); // Register display function
  glutMainLoop();           // The window system is in charge from here on.
}

void update() {
  edit_transformation();    // Update your models
  glutPostRedisplay();      // Tell the window system that something changed.
}

void display() {
    draw();                 // Your OpenGL code here.
    glFlush();              // or glutSwapBuffers();
}