Vulkan Tutorial (Drawing a triangle/Presentation/Image views) 日本語訳

この記事は [Image views - Vulkan Tutorial](https://vulkan-tutorial.com/Drawing_a_triangle/Presentation/Image_views) の日本語訳です。

# Image views

スワップチェイン内のものを含む、どの[`VkImage`](https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkImage.html)でも、レンダーパイプライン中で使うためには[`VkImageView`](https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkImageView.html)オブジェクトを作成する必要があります。イメージビューは文字通り画像へのビューです。これは画像へアクセスする方法と、画像のどの部分にアクセスするかを記述します。例えば、ミップマップ無しの2Dテクスチャとして扱うべき、などです[^1]。

[^1]:この部分、原文では"for example if it should be treated as a 2D texture depth texture without any mipmapping levels."となっているが、"2D texture depth texture"の意味がよくわからない。仕方がないので単に「2Dテクスチャ」と訳した。

この章では`createImageViews`関数を追加して、スワップチェインの画像全てに対してイメージビューを作成し、それらを後でカラーターゲットとして使えるようにします。

はじめに、イメージビューを格納するメンバ変数を追加します。

```cpp
std::vector<VkImageView> swapChainImageViews;
```

`createImageViews`関数を作成し、スワップチェイン作成の直後に呼び出すようにします。

```cpp
void initVulkan() {
    createInstance();
    setupDebugMessenger();
    createSurface();
    pickPhysicalDevice();
    createLogicalDevice();
    createSwapChain();
    createImageViews();
}

void createImageViews() {

}
```

最初にやらなければいけないことは、作成するイメージビューの数に合うようにリストをリサイズすることです。

```cpp
void createImageViews() {
    swapChainImageViews.resize(swapChainImages.size());

}
```

次に、スワップチェインの画像全てを巡回するように、ループを準備します。

```cpp
for (size_t i = 0; i < swapChainImages.size(); i++) {

}
```

イメージビューを作成するためのパラメータは、[`VkImageViewCreateInfo`](https://www.khronos.org/registry/vulkan/specs/1.0/man/html/VkImageViewCreateInfo.html)構造体の中で指定されます。最初のいくつかのパラメータは簡単です。

```cpp
VkImageViewCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = swapChainImages[i];
```

`viewType`と`format`フィールドは、画像データをどのように解釈するべきかを指定します。`viewType`パラメータによって、画像を1Dテクスチャ、2Dテクスチャ、3Dテクスチャ、あるいはキューブマップとして扱うことができます。

```cpp
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = swapChainImageFormat;
```

`components`フィールドでは、カラーチャンネルのスウィズルをすることができます。例えば、全てのチャンネルを赤のチャンネルにマッピングして、モノクロのテクスチャにすることができます。また、チャンネルに`0`か`1`の定数をマッピングすることもできます。私たちは、デフォルトのマッピングを採用します。

```cpp
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
```

`subresourceRange`フィールドでは、画像の目的が何なのかと、画像のどの部分にアクセスするべきかを記述します。私たちの画像は、ミップマッピング無しでマルチレイヤー無しの、カラーターゲットとして使われます。

```cpp
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.baseMipLevel = 0;
createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1;
```

もしあなたが3D立体視アプリケーションを開発しているなら、マルチレイヤーありでスワップチェインを作成しているでしょう。その場合、異なるレイヤーにアクセスすることで、左右の目の視野を表現した画像それぞれに対してイメージビューを作成することができます。

イメージビューを作成するのに、あとは[`vkCreateImageView`](https://www.khronos.org/registry/vulkan/specs/1.0/man/html/vkCreateImageView.html)を呼び出すだけです。

```cpp
if (vkCreateImageView(device, &createInfo, nullptr, &swapChainImageViews[i]) != VK_SUCCESS) {
    throw std::runtime_error("failed to create image views!");
}
```

画像とは違い、イメージビューは我々が明示的に作成したので、それらを破棄するための似たようなループを、プログラムの最後に追加する必要があります。

```cpp
void cleanup() {
    for (auto imageView : swapChainImageViews) {
        vkDestroyImageView(device, imageView, nullptr);
    }

    ...
}
```

イメージビューは、画像をテクスチャとして使いはじめるには十分ですが、レンダーターゲットとして使うためにはまだ準備が整っていません。そのためには、フレームバッファとして知られる、もう一段階の間接的なステップが必要です。しかし、その前にグラフィックスパイプラインをセットアップする必要があります。

[C++ code](https://vulkan-tutorial.com/code/07_image_views.cpp)

次の記事
前の記事