初めてのVulkanプログラミング step6 パイプラインの固定機能

## 頂点入力

頂点バッファーを使用して、グラフィックスを表現するときに使います。今回は、ハードコーディングするので、ロードするデータは、ないことを伝えます。

```cpp
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo;
	vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
	vertexInputCreateInfo.pNext = nullptr;
	vertexInputCreateInfo.flags = 0;
	vertexInputCreateInfo.vertexBindingDescriptionCount = 0;
	vertexInputCreateInfo.pVertexBindingDescriptions = nullptr;
	vertexInputCreateInfo.vertexAttributeDescriptionCount = 0;
	vertexInputCreateInfo.pVertexAttributeDescriptions = nullptr;
```

## 入力アッセンブリ
頂点ジオメトリーの種類と、プリミティブリスタートを有効にするかを指定します。

- topology...頂点のまとめる方法  
一つ一つの点でまとめる。線でまとめる、三角形でまとめる、三角形を円にした形でまとめる。

```cpp
	VkPipelineInputAssemblyStateCreateInfo inputAssemblyCreateInfo;
	inputAssemblyCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
	inputAssemblyCreateInfo.pNext = nullptr;
	inputAssemblyCreateInfo.flags = 0;
	inputAssemblyCreateInfo.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
	inputAssemblyCreateInfo.primitiveRestartEnable = VK_FALSE;
```
## ビューポート
ビューポートは、フレームバッファが出力される領域のサイズを記述します。

```cpp
VkViewport viewport;
	viewport.x = 0.0f;
	viewport.x = 0.0f;
	viewport.width = 800;
	viewport.height = 600;
	viewport.minDepth = 0.0f;
	viewport.maxDepth = 1.0f;


```

scissorは、レンダーバッファーで書き込む部分を指定します。

```cpp
	VkRect2D scissor;
	scissor.offset = { 0,0 };
	scissor.extent = { 800,600 };
```

ビューポートと、scissorを**ViewportState**に結合します。

```cpp
	VkPipelineViewportStateCreateInfo viewportStateCreateInfo;
	viewportStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
	viewportStateCreateInfo.pNext = nullptr;
	viewportStateCreateInfo.flags = 0;
	viewportStateCreateInfo.viewportCount = 1;
	viewportStateCreateInfo.pViewports = &viewport;
	viewportStateCreateInfo.scissorCount = 1;
	viewportStateCreateInfo.pScissors = &scissor;
```

## ラスタライザー

頂点情報から、ピクセルに変換されます。また深度テスト、フェースカーリングを実行し、ポリゴン全体または、エッジのみを埋めます。(ワイヤーフレームレンダリング)

```cpp
	VkPipelineRasterizationStateCreateInfo rasterizationCreateinfo;
	rasterizationCreateinfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
	rasterizationCreateinfo.pNext = nullptr;
	rasterizationCreateinfo.flags = 0;
	rasterizationCreateinfo.depthClampEnable = VK_FALSE;
	rasterizationCreateinfo.rasterizerDiscardEnable = VK_FALSE;
	rasterizationCreateinfo.polygonMode = VK_POLYGON_MODE_FILL;
	rasterizationCreateinfo.cullMode = VK_CULL_MODE_BACK_BIT;
	rasterizationCreateinfo.frontFace = VK_FRONT_FACE_CLOCKWISE;
	rasterizationCreateinfo.depthBiasEnable = VK_FALSE;
	rasterizationCreateinfo.depthBiasConstantFactor = 0.0f;
	rasterizationCreateinfo.depthBiasClamp = 0.0f;
	rasterizationCreateinfo.depthBiasSlopeFactor = 0.0f;
	rasterizationCreateinfo.lineWidth = 1.0f;
```

- depthClamp.....近いオブジェクトと、遠いオブジェクトは、クランプされます。シャドウマッピングの時に約に立ちます。
- rasterizerDiscardEnable......TRUEにした場合ラスタライズしません。
- polygonMode......ジオメトリーのフラグメント生成方法 
 - VK_POLYGON_MODE_FILL......ポリゴンを塗りつぶすします。
 - VK_POLYGON_MODE_LINE......ポリゴンエッジを描写します。
 - VK_POLYGON_MODE_POINT......頂点だけを描写します。
- cullMode......フェースカーリングのタイプを指定します。(3Dオブジェクトの表側をを描写しない。3Dオブジェクトの裏側を描写しない。)
- frontFace......頂点の順番を指定します。
- depthBias......フラグメントの傾きによる深度を指定します。
- lineWidth......線の太さを指定

## マルチサンプリング

アンチエイリアシングを実行する方法の一つです。１つのポリゴンがピクセルにマップされる場合フラグメントシェーダーを複数回実行する必要がないため、高解像度にレンダリングしてから、ダウンスケールするよりも大幅に軽いです。

```cpp
	VkPipelineMultisampleStateCreateInfo multisampleCreateInfo;
	multisampleCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
	multisampleCreateInfo.pNext = nullptr;
	multisampleCreateInfo.flags = 0;
	multisampleCreateInfo.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
	multisampleCreateInfo.sampleShadingEnable = VK_FALSE;
	multisampleCreateInfo.minSampleShading = 1.0f;
	multisampleCreateInfo.pSampleMask = nullptr;
	multisampleCreateInfo.alphaToCoverageEnable = VK_FALSE;
	multisampleCreateInfo.alphaToOneEnable = VK_FALSE;
```

## カラーブレンディング

フラグメントシェーダが色を返した後、表示する媒体に合わせて、カラーブレンディングを行います。
紙に描写するのか、モニターに出力するのか、プロジェクターで出すのか、決めます。
カラーブレンディングを構成する構造体は、2つあります。**VkPipelineColorBlendAttachmentState**は、フレームバッファーごとの構成が含まれています。
**VkPipelineColorBlendStateCreateInfo**は、カラーブレンディングの設定です。

```cpp
	VkPipelineColorBlendAttachmentState colorBlendAttachment;
	colorBlendAttachment.blendEnable = VK_TRUE;
	colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
	colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
	colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
	colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
	colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
	colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
	colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
```

BlendOpで、フレームバッファーごとの操作を指定しています。

```cpp
	VkPipelineColorBlendStateCreateInfo colorBlendCreateInfo;
	colorBlendCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
	colorBlendCreateInfo.pNext = nullptr;
	colorBlendCreateInfo.flags = 0;
	colorBlendCreateInfo.logicOpEnable = VK_FALSE;
	colorBlendCreateInfo.logicOp = VK_LOGIC_OP_NO_OP;
	colorBlendCreateInfo.attachmentCount = 1;
	colorBlendCreateInfo.pAttachments = &colorBlendAttachment;
	colorBlendCreateInfo.blendConstants[0] = 0.0f;
	colorBlendCreateInfo.blendConstants[1] = 0.0f;
	colorBlendCreateInfo.blendConstants[2] = 0.0f;
	colorBlendCreateInfo.blendConstants[3] = 0.0f;

```

logicOpでVK_LOGIC_OP_NO_OPと書いているのでAttachmentStateで書いた絵を入れます。

## pipelineLayoutの作成

パイプラインから記述子セットにアクセスするには、パイプラインレイアウトを使用します。

```cpp
	VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo;
	pipelineLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
	pipelineLayoutCreateInfo.pNext = nullptr;
	pipelineLayoutCreateInfo.flags = 0;
	pipelineLayoutCreateInfo.setLayoutCount=0;
	pipelineLayoutCreateInfo.pSetLayouts = nullptr;
	pipelineLayoutCreateInfo.pushConstantRangeCount = 0;
	pipelineLayoutCreateInfo.pPushConstantRanges = nullptr;

	auto err = vkCreatePipelineLayout(_device, &pipelineLayoutCreateInfo, nullptr , &_pipelineLayout);
	if (VK_SUCCESS != err) {
		assert(0 && "Vulkan ERROR: Create Pipeline Layout failed!!");
		std::exit(-1);
	}
```

## まとめ
すべての固定機能については、以上です。すべてを設定するのは、大変ですが、グラフィクスパイプラインで行われているすべてのことを完全理解できます.