0

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

对象跳到最后一个位置。

如果 3d 对象不会在 for 循环中更新,如何在一系列更新中更新它的位置?

4

3 回答 3

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)

想象一下像 Web 客户端一样使用 OpenGL 进行编程 - 仅指定请求(更改矩阵和绑定内容)是不够的,您需要显式发送请求(发送转换数据并告诉 OpenGL 绘制)以接收答案(具有屏幕上的对象。)

于 2013-09-09T11:31:00.317 回答
0

可以从循环中绘制动画。

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

你画,你冲洗/交换以确保你刚刚画的东西被发送到屏幕上,然后你就睡觉了。

但是,不建议在交互式应用程序中执行此操作。主要原因是当你在这个循环中时,没有其他东西可以运行。您的应用程序将无响应。

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

如果您使用 GLUT 与窗口系统进行通信,则如下所示。其他库(如 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();
}
于 2013-09-09T13:59:04.647 回答
0

只是调用 glTranslate、glRotate 等不会改变屏幕上的内容。为什么?因为 OpenGL 是一个简单的绘图 API,而不是场景图。它只知道绘制到像素帧缓冲区的点、线和三角形。而已。你想改变屏幕上的某些东西,你必须重新绘制它,即清除图片,然后重新绘制它。

顺便说一句:您不应该使用专用循环来实现动画(for、while 和 do while 都不行)。而是在空闲处理程序中执行动画并发出重绘事件。

于 2013-09-09T10:49:53.507 回答