我正在尝试旋转3d对象,但在for循环中应用变换时它不会更新。
对象跳转到最后一个位置。
如果在for循环中不更新3d对象在更新序列中的位置,该如何更新?
答案 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();
}