OpenGL 对象在 PC 上以正常速度旋转,但在笔记本电脑上非常快

Posted

技术标签:

【中文标题】OpenGL 对象在 PC 上以正常速度旋转,但在笔记本电脑上非常快【英文标题】:OpenGL Object rotatating at normal speed on PC but extremely fast on Laptop 【发布时间】:2016-02-04 16:18:01 【问题描述】:

我在处理输入以旋转屏幕上的对象时遇到了一个问题。

我在桌面上按应有的旋转位置编写了所有内容,您可以在 3D 空间中操纵对象。

然而,在我的笔记本电脑上,当我尝试旋转对象时,它实际上旋转得如此之快,以至于几乎看不到它。我说的是每秒几十次旋转。

我的问题是……为什么?为什么它在我的电脑上以正常速度旋转,但在我的笔记本电脑上却以疯狂的速度旋转?

我为每个按键使用的旋转是 0.1...太快了!我可以通过将旋转量更改为 glm::radians(1.0f) 在我的笔记本电脑上修复它,它以正常速度旋转......但在我的电脑上它比我想要的要慢。

我唯一能想到的与增量时间和渲染速度有关(我在相机控制中考虑了这一点)。

这是我的旋转功能供参考...

键盘回调函数(注意:我有一个名为 keys[] 的全局布尔数组,我用它来查看是否正在按下某个键)

// Handle the keyboard input
void keyPressed(GLFWwindow *_window, int key, int scancode, int action, int mods) 

// Close window with escape
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    glfwSetWindowShouldClose(window, GL_TRUE);
// Change render to show points only with P
if (key == GLFW_KEY_P && action == GLFW_PRESS)
    glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
// Change render to show filled in texture with T
if (key == GLFW_KEY_T && action == GLFW_PRESS)
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Change render to show "wirefram" mesh with W
if (key == GLFW_KEY_W && action == GLFW_PRESS)
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

// Array of keys, if key is being held down, sets index corresponding to appropriate integer related to key to true, and false when key is released
if (key >= 0 && key < 1024)

    if (action == GLFW_PRESS)
        keys[key] = true;
    else if (action == GLFW_RELEASE)
        keys[key] = false;

return;

还有旋转功能(注意:clicks[0] 是另一个布尔数组,我用它来查看是否按下鼠标左键):

// rotate object based on keyboard input
// Left mouse button must not be held down for this to work
// Creates a matrix containing the appriopriate transformation, and this is later multipled to the model matrix
void rotate_object(glm::mat4 &transform)

 // Rotate along z axis (left and right, like a barrel roll)
if (!click[0] && keys[GLFW_KEY_LEFT])
    transform = glm::rotate(transform, glm::radians(1.0f), glm::vec3(0.0f, 0.0f, 1.0f));
if (!click[0] && keys[GLFW_KEY_RIGHT])
    transform = glm::rotate(transform, glm::radians(-1.0f), glm::vec3(0.0f, 0.0f, 1.0f));
// Rotate along x axis (up and down, like a flip)
if (!click[0] && keys[GLFW_KEY_UP])
    transform = glm::rotate(transform, glm::radians(1.0f), glm::vec3(1.0f, 0.0f, 0.0f));
if (!click[0] && keys[GLFW_KEY_DOWN])
    transform = glm::rotate(transform, glm::radians(-1.0f), glm::vec3(1.0f, 0.0f, 0.0f));
// Rotate along y axes (make object spin)
if (!click[0] && keys[GLFW_KEY_K])
    transform = glm::rotate(transform, glm::radians(1.0f), glm::vec3(0.0f, 1.0f, 0.0f));
if (!click[0] && keys[GLFW_KEY_L])
    transform = glm::rotate(transform, glm::radians(-1.0f), glm::vec3(0.0f, 1.0f, 0.0f));

感谢您的意见!

谢谢,

【问题讨论】:

这个循环的每次迭代都有一个固定的旋转。是时候添加一些计时器了! 这就是我在写这个问题时想到的......我使用增量时间来使我的相机移动平稳,我现在意识到我必须对对象操作做同样的事情! 【参考方案1】:

您正在使用一个常数值旋转您的对象,而不考虑自上次旋转以来经过的时间量。当你在不同的机器上运行你的代码时,你最终会得到不同的旋转速度,这取决于机器处理你的绘图和更新循环的速度。

您需要跟踪时间 - 保持上次更新和当前更新的时间,并将差异称为“时间增量”。您的旋转需要乘以“时间增量”,这样即使两台机器以不同的速度处理代码,物体仍然以相同的速度旋转。

【讨论】:

谢谢...这绝对是问题所在。最糟糕的是,我在我的程序中使用了 delta time 来控制相机的移动,但我没想到将它用于对象旋转!问题是我在学会如何旋转之后才了解相机移动和增量时间!【参考方案2】:

您必须在帧之间使用时间戳。为此,GLFW 有一个便携式的glfwGetTime。你的框架deltacurrent_time - previous_time,你用它来更新你的(动画)状态。然后在下一帧之前设置previous_time = current_time,并重复该过程。

我也会考虑使用glfwSwapInterval(1) 来等待 vsync - 只要您的 GPU 驱动程序支持它。否则,您只是在浪费循环进行不必要的更新。

【讨论】:

【参考方案3】:

鉴于根本没有关于硬件或使用的系统的详细信息,我认为您在性能上的显着差异来自两者

不同的图形硬件或 上述图形硬件(或两者)的不同驱动程序

当相同的代码在两个系统上以不同的性能运行并且您的代码似乎不是原因时,这是次优的。

我假设您的输入和绘制函数是迭代执行的;这样只有在绘图函数已经返回时才处理下一个输入。在较慢的图形硬件/机器上绘图可能需要更长的时间。这就是您观察到的不同可能产生的原因。

在两者上都尝试glxgears,看看你会得到什么 FPS。如果您的 PC 比您的笔记本电脑慢得多(10^1 或更多),那么这就是您的问题。

【讨论】:

是的,这就是现在的问题,我意识到我需要对此进行调整。我觉得有趣的是,我的 PC 似乎比我的平板电脑运行得慢……我的 PC 是具有强大图形硬件的游戏 PC。难道是因为我的平板电脑屏幕是 10 英寸,而我的电脑显示器是 27 英寸?我确实注意到当我最大化我的窗口时它会变慢,无论平台如何。更大的屏幕 = 更多的绘图?

以上是关于OpenGL 对象在 PC 上以正常速度旋转,但在笔记本电脑上非常快的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL / SDL2:模板缓冲区位在 PC 上始终为 0

Open GL 在对象上添加旋转速度

opengl 围绕固定轴旋转对象

如何使用 GLM 在 OpenGL 中正确计算旋转

OpenGL Matrix Camera 控件,局部旋转无法正常工作

围绕对象中心的 2d OpenGL 旋转