2016-02-16 15:07:25 +01:00
/*
* Vulkan Example - Parallax Mapping
*
* Copyright ( C ) 2016 by Sascha Willems - www . saschawillems . de
*
* This code is licensed under the MIT license ( MIT ) ( http : //opensource.org/licenses/MIT)
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <assert.h>
# include <vector>
# define GLM_FORCE_RADIANS
2016-03-08 21:52:40 +01:00
# define GLM_FORCE_DEPTH_ZERO_TO_ONE
2016-02-16 15:07:25 +01:00
# include <glm/glm.hpp>
# include <glm/gtc/matrix_transform.hpp>
# include <glm/gtc/matrix_inverse.hpp>
# include <vulkan/vulkan.h>
# include "vulkanexamplebase.h"
2017-02-12 10:44:51 +01:00
# include "VulkanBuffer.hpp"
2017-02-11 14:18:24 +01:00
# include "VulkanTexture.hpp"
# include "VulkanModel.hpp"
2016-02-16 15:07:25 +01:00
# define VERTEX_BUFFER_BIND_ID 0
# define ENABLE_VALIDATION false
class VulkanExample : public VulkanExampleBase
{
public :
struct {
2017-02-09 21:55:35 +01:00
vks : : Texture2D colorMap ;
2017-03-24 17:58:25 +01:00
// Normals and height are combined into one texture (height = alpha channel)
2017-02-09 21:55:35 +01:00
vks : : Texture2D normalHeightMap ;
2016-02-16 15:07:25 +01:00
} textures ;
2017-02-11 14:18:24 +01:00
// Vertex layout for the models
vks : : VertexLayout vertexLayout = vks : : VertexLayout ( {
vks : : VERTEX_COMPONENT_POSITION ,
vks : : VERTEX_COMPONENT_UV ,
vks : : VERTEX_COMPONENT_NORMAL ,
vks : : VERTEX_COMPONENT_TANGENT ,
vks : : VERTEX_COMPONENT_BITANGENT ,
} ) ;
2016-02-16 15:07:25 +01:00
struct {
2017-02-11 14:18:24 +01:00
vks : : Model quad ;
} models ;
2016-02-16 15:07:25 +01:00
struct {
2017-02-12 10:44:51 +01:00
vks : : Buffer vertexShader ;
vks : : Buffer fragmentShader ;
2016-12-24 12:48:01 +01:00
} uniformBuffers ;
2016-02-16 15:07:25 +01:00
struct {
struct {
glm : : mat4 projection ;
2017-03-24 17:58:25 +01:00
glm : : mat4 view ;
2016-02-16 15:07:25 +01:00
glm : : mat4 model ;
2017-03-24 17:58:25 +01:00
glm : : vec4 lightPos = glm : : vec4 ( 0.0f , - 2.0f , 0.0f , 1.0f ) ;
2016-02-16 15:07:25 +01:00
glm : : vec4 cameraPos ;
} vertexShader ;
struct {
2017-03-24 17:58:25 +01:00
float heightScale = 0.1f ;
// Basic parallax mapping needs a bias to look any good (and is hard to tweak)
float parallaxBias = - 0.02f ;
// Number of layers for steep parallax and parallax occlusion (more layer = better result for less performance)
float numLayers = 48.0f ;
// (Parallax) mapping mode to use
int32_t mappingMode = 4 ;
2016-02-16 15:07:25 +01:00
} fragmentShader ;
} ubos ;
VkPipelineLayout pipelineLayout ;
2017-03-24 17:58:25 +01:00
VkPipeline pipeline ;
2016-02-16 15:07:25 +01:00
VkDescriptorSetLayout descriptorSetLayout ;
2017-03-24 17:58:25 +01:00
VkDescriptorSet descriptorSet ;
2016-02-16 15:07:25 +01:00
VulkanExample ( ) : VulkanExampleBase ( ENABLE_VALIDATION )
{
title = " Vulkan Example - Parallax Mapping " ;
2017-03-24 17:58:25 +01:00
enableTextOverlay = true ;
timerSpeed * = 0.5f ;
camera . type = Camera : : CameraType : : firstperson ;
camera . setPosition ( glm : : vec3 ( 0.0f , 1.25f , 1.5f ) ) ;
camera . setRotation ( glm : : vec3 ( - 45.0f , 180.0f , 0.0f ) ) ;
camera . setPerspective ( 60.0f , ( float ) width / ( float ) height , 0.1f , 256.0f ) ;
2016-02-16 15:07:25 +01:00
}
~ VulkanExample ( )
{
2017-03-24 17:58:25 +01:00
vkDestroyPipeline ( device , pipeline , nullptr ) ;
2016-02-16 15:07:25 +01:00
vkDestroyPipelineLayout ( device , pipelineLayout , nullptr ) ;
vkDestroyDescriptorSetLayout ( device , descriptorSetLayout , nullptr ) ;
2017-02-11 14:18:24 +01:00
models . quad . destroy ( ) ;
2016-12-24 12:48:01 +01:00
uniformBuffers . vertexShader . destroy ( ) ;
uniformBuffers . fragmentShader . destroy ( ) ;
2016-02-16 15:07:25 +01:00
2017-02-09 21:55:35 +01:00
textures . colorMap . destroy ( ) ;
textures . normalHeightMap . destroy ( ) ;
2016-02-16 15:07:25 +01:00
}
2017-02-09 21:55:35 +01:00
void loadAssets ( )
2016-02-16 15:07:25 +01:00
{
2017-02-11 14:18:24 +01:00
models . quad . loadFromFile ( getAssetPath ( ) + " models/plane_z.obj " , vertexLayout , 0.1f , vulkanDevice , queue ) ;
2017-03-24 17:58:25 +01:00
2017-03-17 18:49:29 +01:00
// Textures
2017-02-09 21:55:35 +01:00
textures . normalHeightMap . loadFromFile ( getAssetPath ( ) + " textures/rocks_normal_height_rgba.dds " , VK_FORMAT_R8G8B8A8_UNORM , vulkanDevice , queue ) ;
2017-03-17 18:49:29 +01:00
if ( vulkanDevice - > features . textureCompressionBC ) {
textures . colorMap . loadFromFile ( getAssetPath ( ) + " textures/rocks_color_bc3_unorm.dds " , VK_FORMAT_BC3_UNORM_BLOCK , vulkanDevice , queue ) ;
}
else if ( vulkanDevice - > features . textureCompressionASTC_LDR ) {
textures . colorMap . loadFromFile ( getAssetPath ( ) + " textures/rocks_color_astc_8x8_unorm.ktx " , VK_FORMAT_ASTC_8x8_UNORM_BLOCK , vulkanDevice , queue ) ;
}
else if ( vulkanDevice - > features . textureCompressionETC2 ) {
textures . colorMap . loadFromFile ( getAssetPath ( ) + " textures/rocks_color_etc2_unorm.ktx " , VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK , vulkanDevice , queue ) ;
}
else {
vks : : tools : : exitFatal ( " Device does not support any compressed texture format! " , " Error " ) ;
}
2016-02-16 15:07:25 +01:00
}
void buildCommandBuffers ( )
{
2017-02-12 11:12:42 +01:00
VkCommandBufferBeginInfo cmdBufInfo = vks : : initializers : : commandBufferBeginInfo ( ) ;
2016-02-16 15:07:25 +01:00
VkClearValue clearValues [ 2 ] ;
clearValues [ 0 ] . color = defaultClearColor ;
clearValues [ 1 ] . depthStencil = { 1.0f , 0 } ;
2017-02-12 11:12:42 +01:00
VkRenderPassBeginInfo renderPassBeginInfo = vks : : initializers : : renderPassBeginInfo ( ) ;
2016-02-16 15:07:25 +01:00
renderPassBeginInfo . renderPass = renderPass ;
renderPassBeginInfo . renderArea . offset . x = 0 ;
renderPassBeginInfo . renderArea . offset . y = 0 ;
renderPassBeginInfo . renderArea . extent . width = width ;
renderPassBeginInfo . renderArea . extent . height = height ;
renderPassBeginInfo . clearValueCount = 2 ;
renderPassBeginInfo . pClearValues = clearValues ;
for ( int32_t i = 0 ; i < drawCmdBuffers . size ( ) ; + + i )
{
// Set target frame buffer
renderPassBeginInfo . framebuffer = frameBuffers [ i ] ;
2016-06-05 20:58:58 +02:00
VK_CHECK_RESULT ( vkBeginCommandBuffer ( drawCmdBuffers [ i ] , & cmdBufInfo ) ) ;
2016-02-16 15:07:25 +01:00
vkCmdBeginRenderPass ( drawCmdBuffers [ i ] , & renderPassBeginInfo , VK_SUBPASS_CONTENTS_INLINE ) ;
2017-03-24 17:58:25 +01:00
VkViewport viewport = vks : : initializers : : viewport ( ( float ) width , ( float ) height , 0.0f , 1.0f ) ;
2016-02-16 15:07:25 +01:00
vkCmdSetViewport ( drawCmdBuffers [ i ] , 0 , 1 , & viewport ) ;
2017-02-12 11:12:42 +01:00
VkRect2D scissor = vks : : initializers : : rect2D ( width , height , 0 , 0 ) ;
2016-02-16 15:07:25 +01:00
vkCmdSetScissor ( drawCmdBuffers [ i ] , 0 , 1 , & scissor ) ;
vkCmdBindDescriptorSets ( drawCmdBuffers [ i ] , VK_PIPELINE_BIND_POINT_GRAPHICS , pipelineLayout , 0 , 1 , & descriptorSet , 0 , NULL ) ;
VkDeviceSize offsets [ 1 ] = { 0 } ;
2017-02-11 14:18:24 +01:00
vkCmdBindVertexBuffers ( drawCmdBuffers [ i ] , VERTEX_BUFFER_BIND_ID , 1 , & models . quad . vertices . buffer , offsets ) ;
vkCmdBindIndexBuffer ( drawCmdBuffers [ i ] , models . quad . indices . buffer , 0 , VK_INDEX_TYPE_UINT32 ) ;
2016-02-16 15:07:25 +01:00
vkCmdSetViewport ( drawCmdBuffers [ i ] , 0 , 1 , & viewport ) ;
2017-03-24 17:58:25 +01:00
vkCmdBindPipeline ( drawCmdBuffers [ i ] , VK_PIPELINE_BIND_POINT_GRAPHICS , pipeline ) ;
2017-02-11 14:18:24 +01:00
vkCmdDrawIndexed ( drawCmdBuffers [ i ] , models . quad . indexCount , 1 , 0 , 0 , 1 ) ;
2016-02-16 15:07:25 +01:00
vkCmdEndRenderPass ( drawCmdBuffers [ i ] ) ;
2016-06-05 20:58:58 +02:00
VK_CHECK_RESULT ( vkEndCommandBuffer ( drawCmdBuffers [ i ] ) ) ;
2016-02-16 15:07:25 +01:00
}
}
void setupDescriptorPool ( )
{
// Example uses two ubos and two image sampler
std : : vector < VkDescriptorPoolSize > poolSizes =
{
2017-02-12 11:12:42 +01:00
vks : : initializers : : descriptorPoolSize ( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , 2 ) ,
vks : : initializers : : descriptorPoolSize ( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , 2 )
2016-02-16 15:07:25 +01:00
} ;
VkDescriptorPoolCreateInfo descriptorPoolInfo =
2017-03-24 17:58:25 +01:00
vks : : initializers : : descriptorPoolCreateInfo ( poolSizes , 2 ) ;
2016-02-16 15:07:25 +01:00
2016-06-05 20:58:58 +02:00
VK_CHECK_RESULT ( vkCreateDescriptorPool ( device , & descriptorPoolInfo , nullptr , & descriptorPool ) ) ;
2016-02-16 15:07:25 +01:00
}
void setupDescriptorSetLayout ( )
{
2017-03-24 17:58:25 +01:00
std : : vector < VkDescriptorSetLayoutBinding > setLayoutBindings = {
vks : : initializers : : descriptorSetLayoutBinding ( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , VK_SHADER_STAGE_VERTEX_BIT , 0 ) , // Binding 0: Vertex shader uniform buffer
vks : : initializers : : descriptorSetLayoutBinding ( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , VK_SHADER_STAGE_FRAGMENT_BIT , 1 ) , // Binding 1: Fragment shader color map image sampler
vks : : initializers : : descriptorSetLayoutBinding ( VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , VK_SHADER_STAGE_FRAGMENT_BIT , 2 ) , // Binding 2: Fragment combined normal and heightmap
vks : : initializers : : descriptorSetLayoutBinding ( VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , VK_SHADER_STAGE_FRAGMENT_BIT , 3 ) , // Binding 3: Fragment shader uniform buffer
2016-02-16 15:07:25 +01:00
} ;
VkDescriptorSetLayoutCreateInfo descriptorLayout =
2017-03-24 17:58:25 +01:00
vks : : initializers : : descriptorSetLayoutCreateInfo ( setLayoutBindings ) ;
2016-02-16 15:07:25 +01:00
2016-06-05 20:58:58 +02:00
VK_CHECK_RESULT ( vkCreateDescriptorSetLayout ( device , & descriptorLayout , nullptr , & descriptorSetLayout ) ) ;
2016-02-16 15:07:25 +01:00
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo =
2017-02-12 11:12:42 +01:00
vks : : initializers : : pipelineLayoutCreateInfo (
2016-02-16 15:07:25 +01:00
& descriptorSetLayout ,
1 ) ;
2016-06-05 20:58:58 +02:00
VK_CHECK_RESULT ( vkCreatePipelineLayout ( device , & pPipelineLayoutCreateInfo , nullptr , & pipelineLayout ) ) ;
2016-02-16 15:07:25 +01:00
}
void setupDescriptorSet ( )
{
VkDescriptorSetAllocateInfo allocInfo =
2017-02-12 11:12:42 +01:00
vks : : initializers : : descriptorSetAllocateInfo (
2016-02-16 15:07:25 +01:00
descriptorPool ,
& descriptorSetLayout ,
1 ) ;
2016-06-05 20:58:58 +02:00
VK_CHECK_RESULT ( vkAllocateDescriptorSets ( device , & allocInfo , & descriptorSet ) ) ;
2016-02-16 15:07:25 +01:00
2017-03-24 17:58:25 +01:00
std : : vector < VkWriteDescriptorSet > writeDescriptorSets = {
vks : : initializers : : writeDescriptorSet ( descriptorSet , VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , 0 , & uniformBuffers . vertexShader . descriptor ) , // Binding 0: Vertex shader uniform buffer
vks : : initializers : : writeDescriptorSet ( descriptorSet , VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , 1 , & textures . colorMap . descriptor ) , // Binding 1: Fragment shader image sampler
vks : : initializers : : writeDescriptorSet ( descriptorSet , VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER , 2 , & textures . normalHeightMap . descriptor ) , // Binding 2: Combined normal and heightmap
vks : : initializers : : writeDescriptorSet ( descriptorSet , VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER , 3 , & uniformBuffers . fragmentShader . descriptor ) , // Binding 3: Fragment shader uniform buffer
2016-02-16 15:07:25 +01:00
} ;
2017-03-24 17:58:25 +01:00
vkUpdateDescriptorSets ( device , static_cast < uint32_t > ( writeDescriptorSets . size ( ) ) , writeDescriptorSets . data ( ) , 0 , NULL ) ;
2016-02-16 15:07:25 +01:00
}
void preparePipelines ( )
{
VkPipelineInputAssemblyStateCreateInfo inputAssemblyState =
2017-03-24 17:58:25 +01:00
vks : : initializers : : pipelineInputAssemblyStateCreateInfo ( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST , 0 , VK_FALSE ) ;
2016-02-16 15:07:25 +01:00
VkPipelineRasterizationStateCreateInfo rasterizationState =
2017-03-24 17:58:25 +01:00
vks : : initializers : : pipelineRasterizationStateCreateInfo ( VK_POLYGON_MODE_FILL , VK_CULL_MODE_NONE , VK_FRONT_FACE_COUNTER_CLOCKWISE ) ;
2016-02-16 15:07:25 +01:00
VkPipelineColorBlendAttachmentState blendAttachmentState =
2017-03-24 17:58:25 +01:00
vks : : initializers : : pipelineColorBlendAttachmentState ( 0xf , VK_FALSE ) ;
2016-02-16 15:07:25 +01:00
VkPipelineColorBlendStateCreateInfo colorBlendState =
2017-03-24 17:58:25 +01:00
vks : : initializers : : pipelineColorBlendStateCreateInfo ( 1 , & blendAttachmentState ) ;
2016-02-16 15:07:25 +01:00
VkPipelineDepthStencilStateCreateInfo depthStencilState =
2017-03-24 17:58:25 +01:00
vks : : initializers : : pipelineDepthStencilStateCreateInfo ( VK_TRUE , VK_TRUE , VK_COMPARE_OP_LESS_OR_EQUAL ) ;
2016-02-16 15:07:25 +01:00
VkPipelineViewportStateCreateInfo viewportState =
2017-02-12 11:12:42 +01:00
vks : : initializers : : pipelineViewportStateCreateInfo ( 1 , 1 , 0 ) ;
2016-02-16 15:07:25 +01:00
VkPipelineMultisampleStateCreateInfo multisampleState =
2017-03-24 17:58:25 +01:00
vks : : initializers : : pipelineMultisampleStateCreateInfo ( VK_SAMPLE_COUNT_1_BIT ) ;
2016-02-16 15:07:25 +01:00
std : : vector < VkDynamicState > dynamicStateEnables = {
VK_DYNAMIC_STATE_VIEWPORT ,
VK_DYNAMIC_STATE_SCISSOR
} ;
VkPipelineDynamicStateCreateInfo dynamicState =
2017-03-24 17:58:25 +01:00
vks : : initializers : : pipelineDynamicStateCreateInfo ( dynamicStateEnables ) ;
2016-02-16 15:07:25 +01:00
// Load shaders
std : : array < VkPipelineShaderStageCreateInfo , 2 > shaderStages ;
VkGraphicsPipelineCreateInfo pipelineCreateInfo =
2017-03-24 17:58:25 +01:00
vks : : initializers : : pipelineCreateInfo ( pipelineLayout , renderPass ) ;
2016-02-16 15:07:25 +01:00
pipelineCreateInfo . pInputAssemblyState = & inputAssemblyState ;
pipelineCreateInfo . pRasterizationState = & rasterizationState ;
pipelineCreateInfo . pColorBlendState = & colorBlendState ;
pipelineCreateInfo . pMultisampleState = & multisampleState ;
pipelineCreateInfo . pViewportState = & viewportState ;
pipelineCreateInfo . pDepthStencilState = & depthStencilState ;
pipelineCreateInfo . pDynamicState = & dynamicState ;
2017-03-24 17:58:25 +01:00
pipelineCreateInfo . stageCount = static_cast < uint32_t > ( shaderStages . size ( ) ) ;
2016-02-16 15:07:25 +01:00
pipelineCreateInfo . pStages = shaderStages . data ( ) ;
2017-03-24 17:58:25 +01:00
// Vertex bindings an attributes
std : : vector < VkVertexInputBindingDescription > vertexInputBindings = {
vks : : initializers : : vertexInputBindingDescription ( 0 , vertexLayout . stride ( ) , VK_VERTEX_INPUT_RATE_VERTEX ) ,
} ;
std : : vector < VkVertexInputAttributeDescription > vertexInputAttributes = {
vks : : initializers : : vertexInputAttributeDescription ( VERTEX_BUFFER_BIND_ID , 0 , VK_FORMAT_R32G32B32_SFLOAT , 0 ) , // Location 0: Position
vks : : initializers : : vertexInputAttributeDescription ( VERTEX_BUFFER_BIND_ID , 1 , VK_FORMAT_R32G32_SFLOAT , sizeof ( float ) * 3 ) , // Location 1: Texture coordinates
vks : : initializers : : vertexInputAttributeDescription ( VERTEX_BUFFER_BIND_ID , 2 , VK_FORMAT_R32G32B32_SFLOAT , sizeof ( float ) * 5 ) , // Location 2: Normal
vks : : initializers : : vertexInputAttributeDescription ( VERTEX_BUFFER_BIND_ID , 3 , VK_FORMAT_R32G32B32_SFLOAT , sizeof ( float ) * 8 ) , // Location 3: Tangent
vks : : initializers : : vertexInputAttributeDescription ( VERTEX_BUFFER_BIND_ID , 4 , VK_FORMAT_R32G32B32_SFLOAT , sizeof ( float ) * 11 ) , // Location 4: Bitangent
} ;
VkPipelineVertexInputStateCreateInfo vertexInputState = vks : : initializers : : pipelineVertexInputStateCreateInfo ( ) ;
vertexInputState . vertexBindingDescriptionCount = static_cast < uint32_t > ( vertexInputBindings . size ( ) ) ;
vertexInputState . pVertexBindingDescriptions = vertexInputBindings . data ( ) ;
vertexInputState . vertexAttributeDescriptionCount = static_cast < uint32_t > ( vertexInputAttributes . size ( ) ) ;
vertexInputState . pVertexAttributeDescriptions = vertexInputAttributes . data ( ) ;
2016-02-16 15:07:25 +01:00
2017-03-24 17:58:25 +01:00
pipelineCreateInfo . pVertexInputState = & vertexInputState ;
// Parallax mapping modes pipeline
shaderStages [ 0 ] = loadShader ( getAssetPath ( ) + " shaders/parallax/parallax.vert.spv " , VK_SHADER_STAGE_VERTEX_BIT ) ;
shaderStages [ 1 ] = loadShader ( getAssetPath ( ) + " shaders/parallax/parallax.frag.spv " , VK_SHADER_STAGE_FRAGMENT_BIT ) ;
VK_CHECK_RESULT ( vkCreateGraphicsPipelines ( device , pipelineCache , 1 , & pipelineCreateInfo , nullptr , & pipeline ) ) ;
2016-02-16 15:07:25 +01:00
}
void prepareUniformBuffers ( )
{
2016-12-24 12:48:01 +01:00
// Vertex shader uniform buffer
VK_CHECK_RESULT ( vulkanDevice - > createBuffer (
2016-02-16 15:07:25 +01:00
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ,
2016-06-05 20:58:58 +02:00
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ,
2016-12-24 12:48:01 +01:00
& uniformBuffers . vertexShader ,
sizeof ( ubos . vertexShader ) ) ) ;
// Fragment shader uniform buffer
VK_CHECK_RESULT ( vulkanDevice - > createBuffer (
2016-02-16 15:07:25 +01:00
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ,
2016-06-05 20:58:58 +02:00
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ,
2016-12-24 12:48:01 +01:00
& uniformBuffers . fragmentShader ,
sizeof ( ubos . fragmentShader ) ) ) ;
// Map persistent
VK_CHECK_RESULT ( uniformBuffers . vertexShader . map ( ) ) ;
VK_CHECK_RESULT ( uniformBuffers . fragmentShader . map ( ) ) ;
2016-02-16 15:07:25 +01:00
updateUniformBuffers ( ) ;
}
void updateUniformBuffers ( )
{
// Vertex shader
2017-03-24 17:58:25 +01:00
ubos . vertexShader . projection = camera . matrices . perspective ;
ubos . vertexShader . view = camera . matrices . view ;
ubos . vertexShader . model = glm : : rotate ( glm : : mat4 ( ) , glm : : radians ( 90.0f ) , glm : : vec3 ( 1.0f , 0.0f , 0.0f ) ) ; ;
ubos . vertexShader . model = glm : : rotate ( ubos . vertexShader . model , glm : : radians ( 180.0f ) , glm : : vec3 ( 0.0f , 0.0f , 1.0f ) ) ; ;
if ( ! paused ) {
ubos . vertexShader . lightPos . x = sin ( glm : : radians ( timer * 360.0f ) ) * 1.5f ;
ubos . vertexShader . lightPos . z = cos ( glm : : radians ( timer * 360.0f ) ) * 1.5f ;
2016-02-16 15:07:25 +01:00
}
2017-03-24 17:58:25 +01:00
ubos . vertexShader . cameraPos = glm : : vec4 ( camera . position , - 1.0f ) * - 1.0f ;
2016-02-16 15:07:25 +01:00
2016-12-24 12:48:01 +01:00
memcpy ( uniformBuffers . vertexShader . mapped , & ubos . vertexShader , sizeof ( ubos . vertexShader ) ) ;
2016-02-16 15:07:25 +01:00
// Fragment shader
2016-12-24 12:48:01 +01:00
memcpy ( uniformBuffers . fragmentShader . mapped , & ubos . fragmentShader , sizeof ( ubos . fragmentShader ) ) ;
2016-02-16 15:07:25 +01:00
}
2016-06-05 20:58:58 +02:00
void draw ( )
{
VulkanExampleBase : : prepareFrame ( ) ;
submitInfo . commandBufferCount = 1 ;
submitInfo . pCommandBuffers = & drawCmdBuffers [ currentBuffer ] ;
VK_CHECK_RESULT ( vkQueueSubmit ( queue , 1 , & submitInfo , VK_NULL_HANDLE ) ) ;
VulkanExampleBase : : submitFrame ( ) ;
}
2016-02-16 15:07:25 +01:00
void prepare ( )
{
VulkanExampleBase : : prepare ( ) ;
2017-02-09 21:55:35 +01:00
loadAssets ( ) ;
2016-02-16 15:07:25 +01:00
prepareUniformBuffers ( ) ;
setupDescriptorSetLayout ( ) ;
preparePipelines ( ) ;
setupDescriptorPool ( ) ;
setupDescriptorSet ( ) ;
buildCommandBuffers ( ) ;
prepared = true ;
}
virtual void render ( )
{
if ( ! prepared )
return ;
draw ( ) ;
if ( ! paused )
{
updateUniformBuffers ( ) ;
}
}
virtual void viewChanged ( )
{
updateUniformBuffers ( ) ;
}
2017-03-24 17:58:25 +01:00
void toggleMappingMode ( )
{
ubos . fragmentShader . mappingMode + + ;
if ( ubos . fragmentShader . mappingMode > 4 ) {
ubos . fragmentShader . mappingMode = 0 ;
} ;
2016-02-16 15:07:25 +01:00
updateUniformBuffers ( ) ;
2017-03-24 17:58:25 +01:00
updateTextOverlay ( ) ;
2016-02-16 15:07:25 +01:00
}
2016-06-05 20:58:58 +02:00
virtual void keyPressed ( uint32_t keyCode )
{
switch ( keyCode )
{
2017-03-24 17:58:25 +01:00
case KEY_SPACE :
2016-06-05 20:58:58 +02:00
case GAMEPAD_BUTTON_A :
2017-03-24 17:58:25 +01:00
toggleMappingMode ( ) ;
2016-06-05 20:58:58 +02:00
break ;
}
}
virtual void getOverlayText ( VulkanTextOverlay * textOverlay )
{
2017-03-24 17:58:25 +01:00
const std : : vector < std : : string > mappingModes = {
" Color only " , " Normal mapping " , " Parallax mapping " , " Steep parallax mapping " , " Parallax occlusion mapping " ,
} ;
2016-06-05 20:58:58 +02:00
# if defined(__ANDROID__)
2017-03-24 17:58:25 +01:00
textOverlay - > addText ( " Mode: " + mappingModes [ ubos . fragmentShader . mappingMode ] + " ( \" Button A \" ) " , 5.0f , 85.0f , VulkanTextOverlay : : alignLeft ) ;
# else
textOverlay - > addText ( " Mode: " + mappingModes [ ubos . fragmentShader . mappingMode ] + " ( \" Space \" ) " , 5.0f , 85.0f , VulkanTextOverlay : : alignLeft ) ;
2016-06-05 20:58:58 +02:00
# endif
}
2016-02-16 15:07:25 +01:00
} ;
2016-12-13 19:25:56 +01:00
VULKAN_EXAMPLE_MAIN ( )