当前位置:嗨网首页>书籍在线阅读

15-预先计算透视矩阵

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

4.11.2 预先计算透视矩阵

可以减少display()函数开销的另一个优化是将透视矩阵的计算移动到init()函数中。我们在4.5节中提到了这种可能性(在脚注中)。虽然这很容易做到,但可能会有一点轻微的复杂情况。虽然通常并不需要重新计算透视矩阵,但是如果运行应用程序的用户调整窗口大小(例如通过拖动窗口角大小调整手柄),则重新计算就是必要的。

幸运的是,GLFW可以配置在调整窗口大小时自动回调指定的函数。在调用init()之前,我们将以下内容添加到main():

glfwSetWindowSizeCallback(window, window_reshape_callback);

第一个参数是GLFW窗口,第二个参数是GLFW在调整窗口大小时调用的函数的名称。然后,我们将计算透视矩阵的代码移动到init()中,同时将其复制到名为window_reshape_callback()的新函数中。

在程序4.1的例子中,如果我们重新组织代码,从display()中删除透视矩阵的计算,那么main()、init()、display()和新函数window_reshape_callback()修改后的版本将如下所示。

void init(GLFWwindow* window) {
   . . .
   // 和之前版本一样,再加上以下三行代码:
   glfwGetFramebufferSize(window, &width, &height);    aspect = (float)width / (float)height;    pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);     // 1.0472 radians = 60 degrees
}
void display(GLFWwindow* window, double currentTime) {
   . . .
   // 和之前版本一样,再移除以下几行代码:
     // build perspective matrix    glfwGetFramebufferSize(window, &width, &height);    aspect = (float)width / (float)height;    pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f);    // 函数余下部分没有变化
   . . .
}
void window_reshape_callback(GLFWwindow* window, int newWidth, int newHeight) {    aspect = (float)newWidth / (float)newHeight;    // 回调提供的新的宽度、高度
   glViewport(0, 0, newWidth, newHeight);          // 设置和帧缓冲区相关的屏幕区域
   pMat = glm::perspective(1.0472f, aspect, 0.1f, 1000.0f); }
int main(void) {
   . . .
   // 和之前版本一样,再加上以下调用:
   glfwSetWindowSizeCallback(window, window_reshape_callback);    init(window)
   while (!glfwWindowShouldClose(window)) {
      // 余下和以前一样
   }

本书配套资源中的程序,与透视矩阵计算有关的实现都是以这种方式组织的,从程序4.1的颜色插值版本开始。