1. 程式人生 > >Vulkan Cookbook 第二章 8 選擇交換鏈影象的大小

Vulkan Cookbook 第二章 8 選擇交換鏈影象的大小

選擇交換鏈影象的大小

通常,為交換鏈建立的影象應該適合應用程式的視窗。 支援的尺寸應該可在呈現表面的功能中使用。 但在某些作業系統上,影象的大小定義了視窗的最終大小。 我們還應該牢記這一點,並檢查交換鏈影象的適當尺寸。

怎麼做...

1.獲取呈現表面的功能(請參閱獲得呈現表面的功能)。將他們儲存在名為surface_capabilities的VkSurfaceCapabilitiesKHR型別變數中。 2.建立一個名為size_of_images的VkExtent2D的型別的變數,我們將在其中儲存所需交換鏈圖片的大小。 3.檢查surface_capabilities變數的currentExtent.width成員是否等於0xFFFFFFFF(-1轉換為uint32_t型別的無符號值)。如果是,則表示影象的大小決定了視窗的大小。在這種情況下:   ·為size_of_images變數的width和height成員分配所需的值。   ·將size_of_images變數的width變數的值限制為surface_capabilities.minImageExtent.width和surface_capabilities.maxImageExtent.width定義的範圍。   ·將size_of_images變數的height變數的值限制為surface_capabilities.minImageExtent.height和surface_capabilities.maxImageExtent.height定義的範圍。 4.如果surface_capabilities變數的currentExtent.width成員變數的值不等於0xFFFFFFFF,則在size_of_images變數中儲存surface_capabilities.currentExtent的值。

譯者注:currentExtent.width != 0xFFFFFFFF 的情況下我們可以在一定範圍內設定影象大小,因為視窗會跟著我們的影象大小改變,反之影象大小應該跟著視窗變(也許並不需要跟著視窗改變大小,比如可能可以在一個視窗中同時渲染多個不同大小的表面是否可以這樣做要看了之後的章節才能得知)。

這個怎麼運作...

交換鏈影象的大小必須符合支援的限制,這些是由表面功能決定的。在大多數典型情況下,我們希望渲染與應用程式視窗的使用者區域具有相同尺寸的影象。此值在表面功能的currentExtent成員中指定。

但是有些作業系統的視窗大小由交換鏈影象大小決定。這種情況由表面功能的currentExtent.width或currentExtent.height成員的0xFFFFFFFF值指示。在這種情況下,我們可以定義影象大小,但它仍然必須在指定範圍內:

if( 0xFFFFFFFF == surface_capabilities.currentExtent.width ) { 
  size_of_images = { 640, 480 };
  
  if( size_of_images.width < surface_capabilities.minImageExtent.width ) {   
    size_of_images.width = surface_capabilities.minImageExtent.width;
  } else if( size_of_images.width > surface_capabilities.maxImageExtent.width )   { 
    size_of_images.width = surface_capabilities.maxImageExtent.width;
  }

  if( size_of_images.height < surface_capabilities.minImageExtent.height ) {     
    size_of_images.height = surface_capabilities.minImageExtent.height;
  } else if( size_of_images.height > surface_capabilities.maxImageExtent.height ) {
    size_of_images.height = surface_capabilities.maxImageExtent.height;
  }
} else {
  size_of_images = surface_capabilities.currentExtent; 
}
return true;