Updated displacement example

This commit is contained in:
saschawillems 2016-06-06 14:28:13 +02:00
parent 0ecff76c40
commit 2ec1a60535
16 changed files with 77 additions and 177 deletions

View file

@ -12,12 +12,10 @@ if %ERRORLEVEL% EQU 0 (
xcopy "..\..\data\shaders\displacement\*.spv" "assets\shaders\displacement" /Y xcopy "..\..\data\shaders\displacement\*.spv" "assets\shaders\displacement" /Y
mkdir "assets\textures" mkdir "assets\textures"
xcopy "..\..\data\textures\stonewall_colormap_bc3.dds" "assets\textures" /Y xcopy "..\..\data\textures\pattern_36_bc3.ktx" "assets\textures" /Y
xcopy "..\..\data\textures\stonewall_heightmap_rgba.dds" "assets\textures" /Y
mkdir "assets\models" mkdir "assets\models"
xcopy "..\..\data\models\torus.obj" "assets\models" /Y xcopy "..\..\data\models\plane.obj" "assets\models" /Y
mkdir "res\drawable" mkdir "res\drawable"
xcopy "..\..\android\images\icon.png" "res\drawable" /Y xcopy "..\..\android\images\icon.png" "res\drawable" /Y

View file

@ -3,7 +3,7 @@
#extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable #extension GL_ARB_shading_language_420pack : enable
layout (binding = 3) uniform sampler2D colorMap; layout (binding = 2) uniform sampler2D colorMap;
layout (location = 0) in vec3 inNormal; layout (location = 0) in vec3 inNormal;
layout (location = 1) in vec2 inUV; layout (location = 1) in vec2 inUV;
@ -25,5 +25,5 @@ void main()
vec4 IAmbient = vec4(0.0, 0.0, 0.0, 1.0); vec4 IAmbient = vec4(0.0, 0.0, 0.0, 1.0);
vec4 IDiffuse = vec4(1.0) * max(dot(inNormal, inLightVec), 0.0); vec4 IDiffuse = vec4(1.0) * max(dot(inNormal, inLightVec), 0.0);
outFragColor = vec4((IAmbient + IDiffuse) * texture(colorMap, inUV)); outFragColor = vec4((IAmbient + IDiffuse) * vec4(texture(colorMap, inUV).rgb, 1.0));
} }

View file

@ -26,12 +26,11 @@ layout (location = 3) out vec3 outLightVec;
void main() void main()
{ {
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) + (gl_TessCoord.y * gl_in[1].gl_Position) + (gl_TessCoord.z * gl_in[2].gl_Position); gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) + (gl_TessCoord.y * gl_in[1].gl_Position) + (gl_TessCoord.z * gl_in[2].gl_Position);
outUV = gl_TessCoord.x * inUV[0] + gl_TessCoord.y * inUV[1] + gl_TessCoord.z * inUV[2]; outUV = gl_TessCoord.x * inUV[0] + gl_TessCoord.y * inUV[1] + gl_TessCoord.z * inUV[2];
outNormal = gl_TessCoord.x * inNormal[0] + gl_TessCoord.y * inNormal[1] + gl_TessCoord.z * inNormal[2]; outNormal = gl_TessCoord.x * inNormal[0] + gl_TessCoord.y * inNormal[1] + gl_TessCoord.z * inNormal[2];
gl_Position.xyz += normalize(outNormal) * (max(textureLod(displacementMap, outUV.st, 0.0).r, 0.45) * ubo.tessStrength); gl_Position.xyz += normalize(outNormal) * (max(textureLod(displacementMap, outUV.st, 0.0).a, 0.0) * ubo.tessStrength);
outEyesPos = (gl_Position).xyz; outEyesPos = (gl_Position).xyz;
outLightVec = normalize(ubo.lightPos.xyz - outEyesPos); outLightVec = normalize(ubo.lightPos.xyz - outEyesPos);

View file

@ -1,7 +1,5 @@
glslangvalidator -V base.vert -o base.vert.spv glslangvalidator -V base.vert -o base.vert.spv
glslangvalidator -V base.frag -o base.frag.spv glslangvalidator -V base.frag -o base.frag.spv
glslangvalidator -V passthrough.tesc -o passthrough.tesc.spv
glslangvalidator -V passthrough.tese -o passthrough.tese.spv
glslangvalidator -V displacement.tesc -o displacement.tesc.spv glslangvalidator -V displacement.tesc -o displacement.tesc.spv
glslangvalidator -V displacement.tese -o displacement.tese.spv glslangvalidator -V displacement.tese -o displacement.tese.spv

View file

@ -1,26 +0,0 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (vertices = 3) out;
layout (location = 0) in vec3 inNormal[];
layout (location = 1) in vec2 inTexCoord[];
layout (location = 0) out vec3 outNormal[3];
layout (location = 3) out vec2 oTexCoord[3];
void main(void)
{
if (gl_InvocationID == 0)
{
gl_TessLevelInner[0] = 1.0;
gl_TessLevelOuter[0] = 1.0;
gl_TessLevelOuter[1] = 1.0;
gl_TessLevelOuter[2] = 1.0;
}
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
outNormal[gl_InvocationID] = inNormal[gl_InvocationID];
oTexCoord[gl_InvocationID] = inTexCoord[gl_InvocationID];
}

View file

@ -1,34 +0,0 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (triangles) in;
layout (binding = 1) uniform UBO
{
mat4 projection;
mat4 model;
vec3 lightPos;
float tessAlpha;
float tessStrength;
} ubo;
layout (location = 0) in vec3 inNormal[];
layout (location = 3) in vec2 inTexCoord[];
layout (location = 0) out vec3 outNormal;
layout (location = 1) out vec2 outTexCoord;
layout (location = 2) out vec3 outEyesPos;
layout (location = 3) out vec3 outLightVec;
void main(void)
{
gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) + (gl_TessCoord.y * gl_in[1].gl_Position) + (gl_TessCoord.z * gl_in[2].gl_Position);
outNormal = gl_TessCoord.x * inNormal[0] + gl_TessCoord.y * inNormal[1] + gl_TessCoord.z * inNormal[2];
outTexCoord = gl_TessCoord.x * inTexCoord[0] + gl_TessCoord.y * inTexCoord[1] + gl_TessCoord.z * inTexCoord[2];
gl_Position.xyz += normalize(outNormal);
outEyesPos = (gl_Position).xyz;
outLightVec = normalize(ubo.lightPos - outEyesPos);
gl_Position = ubo.projection * ubo.model * gl_Position;
}

Binary file not shown.

View file

@ -36,11 +36,11 @@ class VulkanExample : public VulkanExampleBase
{ {
private: private:
struct { struct {
vkTools::VulkanTexture colorMap; vkTools::VulkanTexture colorHeightMap;
vkTools::VulkanTexture heightMap;
} textures; } textures;
public: public:
bool splitScreen = true; bool splitScreen = true;
bool displacement = true;
struct { struct {
VkPipelineVertexInputStateCreateInfo inputState; VkPipelineVertexInputStateCreateInfo inputState;
@ -55,25 +55,21 @@ public:
vkTools::UniformData uniformDataTC, uniformDataTE; vkTools::UniformData uniformDataTC, uniformDataTE;
struct { struct {
float tessLevel = 8.0; float tessLevel = 64.0f;
} uboTC; } uboTC;
struct { struct {
glm::mat4 projection; glm::mat4 projection;
glm::mat4 model; glm::mat4 model;
glm::vec4 lightPos = glm::vec4(0.0, -25.0, 0.0, 0.0); glm::vec4 lightPos = glm::vec4(0.0f, -1.0f, 0.0f, 0.0f);
float tessAlpha = 1.0; float tessAlpha = 1.0f;
float tessStrength = 1.0; float tessStrength = 0.1f;
} uboTE; } uboTE;
struct { struct {
VkPipeline solid; VkPipeline solid;
VkPipeline wire; VkPipeline wireframe;
VkPipeline solidPassThrough;
VkPipeline wirePassThrough;
} pipelines; } pipelines;
VkPipeline *pipelineLeft = &pipelines.solidPassThrough;
VkPipeline *pipelineRight = &pipelines.solid;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
VkDescriptorSet descriptorSet; VkDescriptorSet descriptorSet;
@ -81,8 +77,8 @@ public:
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION) VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
{ {
zoom = -35; zoom = -1.25f;
rotation = glm::vec3(-35.0, 0.0, 0); rotation = glm::vec3(-20.0f, 45.0f, 0.0f);
enableTextOverlay = true; enableTextOverlay = true;
title = "Vulkan Example - Tessellation shader displacement mapping"; title = "Vulkan Example - Tessellation shader displacement mapping";
// Support for tessellation shaders is optional, so check first // Support for tessellation shaders is optional, so check first
@ -97,9 +93,7 @@ public:
// Clean up used Vulkan resources // Clean up used Vulkan resources
// Note : Inherited destructor cleans up resources stored in base class // Note : Inherited destructor cleans up resources stored in base class
vkDestroyPipeline(device, pipelines.solid, nullptr); vkDestroyPipeline(device, pipelines.solid, nullptr);
vkDestroyPipeline(device, pipelines.wire, nullptr); vkDestroyPipeline(device, pipelines.wireframe, nullptr);
vkDestroyPipeline(device, pipelines.solidPassThrough, nullptr);
vkDestroyPipeline(device, pipelines.wirePassThrough, nullptr);
vkDestroyPipelineLayout(device, pipelineLayout, nullptr); vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr); vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
@ -112,20 +106,15 @@ public:
vkDestroyBuffer(device, uniformDataTE.buffer, nullptr); vkDestroyBuffer(device, uniformDataTE.buffer, nullptr);
vkFreeMemory(device, uniformDataTE.memory, nullptr); vkFreeMemory(device, uniformDataTE.memory, nullptr);
textureLoader->destroyTexture(textures.colorMap); textureLoader->destroyTexture(textures.colorHeightMap);
textureLoader->destroyTexture(textures.heightMap);
} }
void loadTextures() void loadTextures()
{ {
textureLoader->loadTexture( textureLoader->loadTexture(
getAssetPath() + "textures/stonewall_colormap_bc3.dds", getAssetPath() + "textures/pattern_36_bc3.ktx",
VK_FORMAT_BC3_UNORM_BLOCK, VK_FORMAT_BC3_UNORM_BLOCK,
&textures.colorMap); &textures.colorHeightMap);
textureLoader->loadTexture(
getAssetPath() + "textures/stonewall_heightmap_rgba.dds",
VK_FORMAT_R8G8B8A8_UNORM,
&textures.heightMap);
} }
void reBuildCommandBuffers() void reBuildCommandBuffers()
@ -164,10 +153,10 @@ public:
vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
VkViewport viewport = vkTools::initializers::viewport(splitScreen ? (float)width / 2.0f : (float)width, (float)height, 0.0f, 1.0f); VkViewport viewport = vkTools::initializers::viewport((float)width, (float)height, 0.0f, 1.0f);
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport);
VkRect2D scissor = vkTools::initializers::rect2D(width, height, 0, 0); VkRect2D scissor = vkTools::initializers::rect2D(splitScreen ? width / 2 : width, height, 0, 0);
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
vkCmdSetLineWidth(drawCmdBuffers[i], 1.0f); vkCmdSetLineWidth(drawCmdBuffers[i], 1.0f);
@ -180,14 +169,13 @@ public:
if (splitScreen) if (splitScreen)
{ {
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.wireframe);
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLeft);
vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0); vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0);
viewport.x = float(width) / 2; scissor.offset.x = width / 2;
vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor);
} }
vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.solid);
vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineRight);
vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0); vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0);
vkCmdEndRenderPass(drawCmdBuffers[i]); vkCmdEndRenderPass(drawCmdBuffers[i]);
@ -198,7 +186,7 @@ public:
void loadMeshes() void loadMeshes()
{ {
loadMesh(getAssetPath() + "models/torus.obj", &meshes.object, vertexLayout, 0.25f); loadMesh(getAssetPath() + "models/plane.obj", &meshes.object, vertexLayout, 0.25f);
} }
void setupVertexDescriptions() void setupVertexDescriptions()
@ -252,7 +240,7 @@ public:
std::vector<VkDescriptorPoolSize> poolSizes = std::vector<VkDescriptorPoolSize> poolSizes =
{ {
vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2), vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2),
vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2) vkTools::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1)
}; };
VkDescriptorPoolCreateInfo descriptorPoolInfo = VkDescriptorPoolCreateInfo descriptorPoolInfo =
@ -278,16 +266,11 @@ public:
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
1), 1),
// Binding 2 : Tessellation evaluation shader displacement map image sampler // Binding 2 : Combined color (rgb) and height (alpha) map
vkTools::initializers::descriptorSetLayoutBinding( vkTools::initializers::descriptorSetLayoutBinding(
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
2), 2),
// Binding 3 : Fragment shader color map image sampler
vkTools::initializers::descriptorSetLayoutBinding(
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
VK_SHADER_STAGE_FRAGMENT_BIT,
3),
}; };
VkDescriptorSetLayoutCreateInfo descriptorLayout = VkDescriptorSetLayoutCreateInfo descriptorLayout =
@ -315,18 +298,11 @@ public:
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
// Displacement map image descriptor // Color and height map image descriptor
VkDescriptorImageInfo texDescriptorDisplacementMap = VkDescriptorImageInfo texDescriptor =
vkTools::initializers::descriptorImageInfo( vkTools::initializers::descriptorImageInfo(
textures.heightMap.sampler, textures.colorHeightMap.sampler,
textures.heightMap.view, textures.colorHeightMap.view,
VK_IMAGE_LAYOUT_GENERAL);
// Color map image descriptor
VkDescriptorImageInfo texDescriptorColorMap =
vkTools::initializers::descriptorImageInfo(
textures.colorMap.sampler,
textures.colorMap.view,
VK_IMAGE_LAYOUT_GENERAL); VK_IMAGE_LAYOUT_GENERAL);
std::vector<VkWriteDescriptorSet> writeDescriptorSets = std::vector<VkWriteDescriptorSet> writeDescriptorSets =
@ -343,18 +319,12 @@ public:
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1, 1,
&uniformDataTE.descriptor), &uniformDataTE.descriptor),
// Binding 2 : Displacement map // Binding 2 : Color and displacement map (alpha channel)
vkTools::initializers::writeDescriptorSet( vkTools::initializers::writeDescriptorSet(
descriptorSet, descriptorSet,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
2, 2,
&texDescriptorDisplacementMap), &texDescriptor),
// Binding 3 : Color map
vkTools::initializers::writeDescriptorSet(
descriptorSet,
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
3,
&texDescriptorColorMap),
}; };
vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL); vkUpdateDescriptorSets(device, writeDescriptorSets.size(), writeDescriptorSets.data(), 0, NULL);
@ -446,20 +416,7 @@ public:
// Wireframe pipeline // Wireframe pipeline
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
rasterizationState.cullMode = VK_CULL_MODE_NONE; rasterizationState.cullMode = VK_CULL_MODE_NONE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wire)); VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wireframe));
// Pass through pipelines
// Load pass through tessellation shaders (Vert and frag are reused)
shaderStages[2] = loadShader(getAssetPath() + "shaders/displacement/passthrough.tesc.spv", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
shaderStages[3] = loadShader(getAssetPath() + "shaders/displacement/passthrough.tese.spv", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
// Solid
rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
rasterizationState.cullMode = VK_CULL_MODE_BACK_BIT;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solidPassThrough));
// Wireframe
rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
rasterizationState.cullMode = VK_CULL_MODE_NONE;
VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.wirePassThrough));
} }
// Prepare and initialize uniform buffer containing shader uniforms // Prepare and initialize uniform buffer containing shader uniforms
@ -492,7 +449,7 @@ public:
{ {
// Tessellation eval // Tessellation eval
glm::mat4 viewMatrix = glm::mat4(); glm::mat4 viewMatrix = glm::mat4();
uboTE.projection = glm::perspective(glm::radians(45.0f), (float)(width* ((splitScreen) ? 0.5f : 1.0f)) / (float)height, 0.1f, 256.0f); uboTE.projection = glm::perspective(glm::radians(45.0f), (float)(width) / (float)height, 0.1f, 256.0f);
viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, zoom)); viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, zoom));
float offset = 0.5f; float offset = 0.5f;
@ -503,15 +460,27 @@ public:
uboTE.model = glm::rotate(uboTE.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); uboTE.model = glm::rotate(uboTE.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
uboTE.model = glm::rotate(uboTE.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); uboTE.model = glm::rotate(uboTE.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
uboTE.lightPos.y = -0.5f - uboTE.tessStrength;
uint8_t *pData; uint8_t *pData;
VK_CHECK_RESULT(vkMapMemory(device, uniformDataTE.memory, 0, sizeof(uboTE), 0, (void **)&pData)); VK_CHECK_RESULT(vkMapMemory(device, uniformDataTE.memory, 0, sizeof(uboTE), 0, (void **)&pData));
memcpy(pData, &uboTE, sizeof(uboTE)); memcpy(pData, &uboTE, sizeof(uboTE));
vkUnmapMemory(device, uniformDataTE.memory); vkUnmapMemory(device, uniformDataTE.memory);
// Tessellation control // Tessellation control
float savedLevel = uboTC.tessLevel;
if (!displacement)
{
uboTC.tessLevel = 1.0f;
}
VK_CHECK_RESULT(vkMapMemory(device, uniformDataTC.memory, 0, sizeof(uboTC), 0, (void **)&pData)); VK_CHECK_RESULT(vkMapMemory(device, uniformDataTC.memory, 0, sizeof(uboTC), 0, (void **)&pData));
memcpy(pData, &uboTC, sizeof(uboTC)); memcpy(pData, &uboTC, sizeof(uboTC));
vkUnmapMemory(device, uniformDataTC.memory); vkUnmapMemory(device, uniformDataTC.memory);
if (!displacement)
{
uboTC.tessLevel = savedLevel;
}
} }
void draw() void draw()
@ -547,9 +516,7 @@ public:
{ {
if (!prepared) if (!prepared)
return; return;
vkDeviceWaitIdle(device);
draw(); draw();
vkDeviceWaitIdle(device);
} }
virtual void viewChanged() virtual void viewChanged()
@ -560,25 +527,17 @@ public:
void changeTessellationLevel(float delta) void changeTessellationLevel(float delta)
{ {
uboTC.tessLevel += delta; uboTC.tessLevel += delta;
// Clamp
uboTC.tessLevel = fmax(1.0, fmin(uboTC.tessLevel, 32.0)); uboTC.tessLevel = fmax(1.0, fmin(uboTC.tessLevel, 32.0));
updateUniformBuffers(); updateUniformBuffers();
updateTextOverlay(); updateTextOverlay();
} }
void togglePipelines() void changeTessellationStrength(float delta)
{ {
if (pipelineRight == &pipelines.solid) uboTE.tessStrength += delta;
{ uboTE.tessStrength = fmax(0.0f, fmin(uboTE.tessStrength, 1.0f));
pipelineRight = &pipelines.wire; updateUniformBuffers();
pipelineLeft = &pipelines.wirePassThrough; updateTextOverlay();
}
else
{
pipelineRight = &pipelines.solid;
pipelineLeft = &pipelines.solidPassThrough;
}
reBuildCommandBuffers();
} }
void toggleSplitScreen() void toggleSplitScreen()
@ -588,21 +547,27 @@ public:
updateUniformBuffers(); updateUniformBuffers();
} }
void toggleDisplacement()
{
displacement = !displacement;
updateUniformBuffers();
}
virtual void keyPressed(uint32_t keyCode) virtual void keyPressed(uint32_t keyCode)
{ {
switch (keyCode) switch (keyCode)
{ {
case 0x6B: case 0x6B:
case GAMEPAD_BUTTON_R1: case GAMEPAD_BUTTON_R1:
changeTessellationLevel(0.25); changeTessellationStrength(0.025);
break; break;
case 0x6D: case 0x6D:
case GAMEPAD_BUTTON_L1: case GAMEPAD_BUTTON_L1:
changeTessellationLevel(-0.25); changeTessellationStrength(-0.025);
break; break;
case 0x57: case 0x44:
case GAMEPAD_BUTTON_A: case GAMEPAD_BUTTON_A:
togglePipelines(); toggleDisplacement();
break; break;
case 0x53: case 0x53:
case GAMEPAD_BUTTON_X: case GAMEPAD_BUTTON_X:
@ -614,14 +579,14 @@ public:
virtual void getOverlayText(VulkanTextOverlay *textOverlay) virtual void getOverlayText(VulkanTextOverlay *textOverlay)
{ {
std::stringstream ss; std::stringstream ss;
ss << std::setprecision(2) << std::fixed << uboTC.tessLevel; ss << std::setprecision(2) << std::fixed << uboTE.tessStrength;
#if defined(__ANDROID__) #if defined(__ANDROID__)
textOverlay->addText("Tessellation level: " + ss.str() + " (Buttons L1/R1 to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Tessellation height: " + ss.str() + " (Buttons L1/R1)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
textOverlay->addText("Press \"Button A\" to toggle wireframe", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Press \"Button A\" to toggle displacement", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
textOverlay->addText("Press \"Button X\" to toggle splitscreen", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Press \"Button X\" to toggle splitscreen", 5.0f, 115.0f, VulkanTextOverlay::alignLeft);
#else #else
textOverlay->addText("Tessellation level: " + ss.str() + " (NUMPAD +/- to change)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Tessellation height: " + ss.str() + " (numpad +/-)", 5.0f, 85.0f, VulkanTextOverlay::alignLeft);
textOverlay->addText("Press \"w\" to toggle wireframe", 5.0f, 100.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Press \"d\" to toggle displacement", 5.0f, 100.0f, VulkanTextOverlay::alignLeft);
textOverlay->addText("Press \"s\" to toggle splitscreen", 5.0f, 115.0f, VulkanTextOverlay::alignLeft); textOverlay->addText("Press \"s\" to toggle splitscreen", 5.0f, 115.0f, VulkanTextOverlay::alignLeft);
#endif #endif
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 KiB

After

Width:  |  Height:  |  Size: 283 KiB

Before After
Before After