Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Incorporate changes to chooseSwapExtent
  • Loading branch information
maltekliemann committed Oct 11, 2020
commit f0f4207dd7f1e14f2f3288f06542e0fc352f7fb0
38 changes: 29 additions & 9 deletions en/03_Drawing_a_triangle/01_Presentation/01_Swap_chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,28 @@ VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
```

The swap extent is the resolution of the swap chain images and it's almost
always exactly equal to the resolution of the window that we're drawing to. The
range of the possible resolutions is defined in the `VkSurfaceCapabilitiesKHR`
structure. Vulkan tells us to match the resolution of the window by setting the
width and height in the `currentExtent` member. However, some window managers do
allow us to differ here and this is indicated by setting the width and height in
`currentExtent` to a special value: the maximum value of `uint32_t`. In that
case we'll pick the resolution that best matches the window within the
`minImageExtent` and `maxImageExtent` bounds.
always exactly equal to the resolution of the window that we're drawing to _in
pixels_ (more on that in a moment). The range of the possible resolutions is
defined in the `VkSurfaceCapabilitiesKHR` structure. Vulkan tells us to match
the resolution of the window by setting the width and height in the
`currentExtent` member. However, some window managers do allow us to differ here
and this is indicated by setting the width and height in `currentExtent` to a
special value: the maximum value of `uint32_t`. In that case we'll pick the
resolution that best matches the window within the `minImageExtent` and
`maxImageExtent` bounds. But we must specify the resolution in the correct unit.

GLFW uses two units when measuring sizes: pixels and
[screen coordinates](https://www.glfw.org/docs/latest/intro_guide.html#coordinate_systems).
For example, the resolution `{WIDTH, HEIGHT}` that we specified earlier when
creating the window is measured in screen coordinates. But Vulkan works with
pixels, so the swap chain extent must be specified in pixels as well.
Unfortunately, if you are using a high DPI display (like Apple's Retina
display), screen coordinates don't correspond to pixels. Instead, due to the
higher pixel density, the resolution of the window in pixel will be larger than
the resolution in screen coordinates. So if Vulkan doesn't fix the swap extent
for us, we can't just use the original `{WIDTH, HEIGHT}`. Instead, we must use
`glfwGetFramebufferSize` to query the resolution of the window in pixel before
matching it against the minimum and maximum image extent.

```c++
#include <cstdint> // Necessary for UINT32_MAX
Expand All @@ -336,7 +350,13 @@ VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
if (capabilities.currentExtent.width != UINT32_MAX) {
return capabilities.currentExtent;
} else {
VkExtent2D actualExtent = {WIDTH, HEIGHT};
int width, height;
glfwGetFramebufferSize(window, &width, &height);

VkExtent2D actualExtent = {
static_cast<uint32_t>(width),
static_cast<uint32_t>(height)
};

actualExtent.width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actualExtent.width));
actualExtent.height = std::max(capabilities.minImageExtent.height, std::min(capabilities.maxImageExtent.height, actualExtent.height));
Expand Down
24 changes: 5 additions & 19 deletions en/03_Drawing_a_triangle/04_Swap_chain_recreation.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,25 +114,11 @@ Instead I've opted to clean up the existing command buffers with the
`vkFreeCommandBuffers` function. This way we can reuse the existing pool to
allocate the new command buffers.

To handle window resizes properly, we also need to query the current size of the framebuffer to make sure that the swap chain images have the (new) right size. To do that change the `chooseSwapExtent` function to take the actual size into account:

```c++
VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities) {
if (capabilities.currentExtent.width != UINT32_MAX) {
return capabilities.currentExtent;
} else {
int width, height;
glfwGetFramebufferSize(window, &width, &height);

VkExtent2D actualExtent = {
static_cast<uint32_t>(width),
static_cast<uint32_t>(height)
};

...
}
}
```
Note that in `chooseSwapExtent` we already query the new window resolution to
make sure that the swap chain images have the (new) right size, so there's no
need to modify `chooseSwapExtent` (remember that we already had to use
`glfwGetFramebufferSize` get the resolution of the surface in pixel when
creating the swap chain).

That's all it takes to recreate the swap chain! However, the disadvantage of
this approach is that we need to stop all rendering before creating the new swap
Expand Down