Array texture for mat caps in spherical environment mapping example, toggle via keys

This commit is contained in:
saschawillems 2016-03-02 21:15:00 +01:00
parent 10afc74051
commit c32373857f

View file

@ -1,5 +1,5 @@
/* /*
* Vulkan Example - Spherical Environment Mapping * Vulkan Example - Spherical Environment Mapping, using different mat caps
* *
* Based on https://www.clicktorelease.com/blog/creating-spherical-environment-mapping-shader * Based on https://www.clicktorelease.com/blog/creating-spherical-environment-mapping-shader
* *
@ -15,6 +15,7 @@
#include <vector> #include <vector>
#define GLM_FORCE_RADIANS #define GLM_FORCE_RADIANS
#define GLM_DEPTH_ZERO_TO_ONE
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_inverse.hpp> #include <glm/gtc/matrix_inverse.hpp>
@ -49,7 +50,7 @@ public:
} meshes; } meshes;
struct { struct {
vkTools::VulkanTexture matCap; vkTools::VulkanTexture matCapArray;
} textures; } textures;
struct { struct {
@ -61,6 +62,7 @@ public:
glm::mat4 model; glm::mat4 model;
glm::mat4 normal; glm::mat4 normal;
glm::mat4 view; glm::mat4 view;
int32_t texIndex = 0;
} uboVS; } uboVS;
struct { struct {
@ -93,15 +95,18 @@ public:
vkTools::destroyUniformData(device, &uniformData.vertexShader); vkTools::destroyUniformData(device, &uniformData.vertexShader);
textureLoader->destroyTexture(textures.matCap); textureLoader->destroyTexture(textures.matCapArray);
} }
void loadTextures() void loadTextures()
{ {
textureLoader->loadTexture( // Several mat caps are stored in a single texture array
"./../data/textures/matcaps/jade.dds", // so they can easily be switched inside the shader
// just by updating the index in a uniform buffer
textureLoader->loadTextureArray(
"./../data/textures/matcap_array_rgba.ktx",
VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM,
&textures.matCap); &textures.matCapArray);
} }
void buildCommandBuffers() void buildCommandBuffers()
@ -158,16 +163,6 @@ public:
vkCmdEndRenderPass(drawCmdBuffers[i]); vkCmdEndRenderPass(drawCmdBuffers[i]);
VkImageMemoryBarrier prePresentBarrier = vkTools::prePresentBarrier(swapChain.buffers[i].image);
vkCmdPipelineBarrier(
drawCmdBuffers[i],
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
VK_FLAGS_NONE,
0, nullptr,
0, nullptr,
1, &prePresentBarrier);
err = vkEndCommandBuffer(drawCmdBuffers[i]); err = vkEndCommandBuffer(drawCmdBuffers[i]);
assert(!err); assert(!err);
} }
@ -197,6 +192,8 @@ public:
err = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); err = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE);
assert(!err); assert(!err);
submitPrePresentBarrier(swapChain.buffers[currentBuffer].image);
err = swapChain.queuePresent(queue, currentBuffer); err = swapChain.queuePresent(queue, currentBuffer);
assert(!err); assert(!err);
@ -328,8 +325,8 @@ public:
// Color map image descriptor // Color map image descriptor
VkDescriptorImageInfo texDescriptorColorMap = VkDescriptorImageInfo texDescriptorColorMap =
vkTools::initializers::descriptorImageInfo( vkTools::initializers::descriptorImageInfo(
textures.matCap.sampler, textures.matCapArray.sampler,
textures.matCap.view, textures.matCapArray.view,
VK_IMAGE_LAYOUT_GENERAL); VK_IMAGE_LAYOUT_GENERAL);
std::vector<VkWriteDescriptorSet> writeDescriptorSets = std::vector<VkWriteDescriptorSet> writeDescriptorSets =
@ -404,11 +401,11 @@ public:
// Load shaders // Load shaders
std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages; std::array<VkPipelineShaderStageCreateInfo, 2> shaderStages;
#ifdef USE_GLSL #ifdef USE_GLSL
shaderStages[0] = loadShaderGLSL("./../data/shaders/sem.vert", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[0] = loadShaderGLSL("./../data/shaders/sphericalenvmapping/sem.vert", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShaderGLSL("./../data/shaders/sem.frag", VK_SHADER_STAGE_FRAGMENT_BIT); shaderStages[1] = loadShaderGLSL("./../data/shaders/sphericalenvmapping/sem.frag", VK_SHADER_STAGE_FRAGMENT_BIT);
#else #else
shaderStages[0] = loadShader("./../data/shaders/sem.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[0] = loadShader("./../data/shaders/sphericalenvmapping/sem.vert.spv", VK_SHADER_STAGE_VERTEX_BIT);
shaderStages[1] = loadShader("./../data/shaders/sem.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); shaderStages[1] = loadShader("./../data/shaders/sphericalenvmapping/sem.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT);
#endif #endif
VkGraphicsPipelineCreateInfo pipelineCreateInfo = VkGraphicsPipelineCreateInfo pipelineCreateInfo =
@ -434,8 +431,6 @@ public:
void prepareUniformBuffers() void prepareUniformBuffers()
{ {
VkResult err;
// Vertex shader uniform buffer block // Vertex shader uniform buffer block
createBuffer( createBuffer(
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
@ -450,7 +445,7 @@ public:
void updateUniformBuffers() void updateUniformBuffers()
{ {
uboVS.projection = glm::perspective(deg_to_rad(45.0f), (float)width / (float)height, 0.1f, 256.0f); uboVS.projection = glm::perspective(glm::radians(45.0f), (float)width / (float)height, 0.1f, 256.0f);
uboVS.view = glm::lookAt( uboVS.view = glm::lookAt(
glm::vec3(0, 0, -zoom), glm::vec3(0, 0, -zoom),
@ -459,9 +454,9 @@ public:
); );
uboVS.model = glm::mat4(); uboVS.model = glm::mat4();
uboVS.model = glm::rotate(uboVS.model, deg_to_rad(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
uboVS.model = glm::rotate(uboVS.model, deg_to_rad(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
uboVS.model = glm::rotate(uboVS.model, deg_to_rad(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
uboVS.normal = glm::inverseTranspose(uboVS.view * uboVS.model); uboVS.normal = glm::inverseTranspose(uboVS.view * uboVS.model);
@ -501,6 +496,20 @@ public:
updateUniformBuffers(); updateUniformBuffers();
} }
void changeMatCapIndex(uint32_t delta)
{
uboVS.texIndex += delta;
if (uboVS.texIndex < 0)
{
uboVS.texIndex = 0;
}
if (uboVS.texIndex > textures.matCapArray.layerCount)
{
uboVS.texIndex = textures.matCapArray.layerCount;
}
updateUniformBuffers();
}
}; };
VulkanExample *vulkanExample; VulkanExample *vulkanExample;
@ -512,6 +521,18 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (vulkanExample != NULL) if (vulkanExample != NULL)
{ {
vulkanExample->handleMessages(hWnd, uMsg, wParam, lParam); vulkanExample->handleMessages(hWnd, uMsg, wParam, lParam);
if (uMsg == WM_KEYDOWN)
{
switch (wParam)
{
case VK_ADD:
vulkanExample->changeMatCapIndex(1);
break;
case VK_SUBTRACT:
vulkanExample->changeMatCapIndex(-1);
break;
}
}
} }
return (DefWindowProc(hWnd, uMsg, wParam, lParam)); return (DefWindowProc(hWnd, uMsg, wParam, lParam));
} }