minecraft: texture sampling
This commit is contained in:
parent
46924c8451
commit
b79473a881
2
Makefile
2
Makefile
@ -25,7 +25,7 @@ CFLAGS += -I./data
|
||||
CFLAGS += -I../SDL3-dist/include
|
||||
CFLAGS += -fpic
|
||||
|
||||
FLAGS += -fstack-protector -fstack-protector-all -fno-omit-frame-pointer -fsanitize=address
|
||||
#FLAGS += -fstack-protector -fstack-protector-all -fno-omit-frame-pointer -fsanitize=address
|
||||
|
||||
LDFLAGS += -lm
|
||||
ifeq ($(UNAME),Linux)
|
||||
|
||||
BIN
data/minecraft/terrain2.dds
Normal file
BIN
data/minecraft/terrain2.dds
Normal file
Binary file not shown.
BIN
data/minecraft/terrain2.png
Normal file
BIN
data/minecraft/terrain2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -33,3 +33,5 @@ data/minecraft/midnightmeadow/region.0.-1.instance.cfg
|
||||
data/minecraft/midnightmeadow/region.-1.-1.instance.cfg
|
||||
data/minecraft/midnightmeadow/global.dump
|
||||
data/minecraft/midnightmeadow/global.lights.vtx
|
||||
|
||||
data/minecraft/terrain2.dds
|
||||
|
||||
@ -19,7 +19,7 @@ namespace minecraft::vulkan {
|
||||
static constexpr uint32_t maxFrames = 2;
|
||||
static constexpr uint32_t perFrameDescriptorCount = 1;
|
||||
static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount;
|
||||
static constexpr uint32_t bindingCount = uniformBufferDescriptorCount + 0;
|
||||
static constexpr uint32_t bindingCount = uniformBufferDescriptorCount + 3;
|
||||
|
||||
static constexpr int perVertexSize = (3 + 3 + 2) * 2;
|
||||
static constexpr int perInstanceSize = (3 + 1 + 3 + 1) * 2;
|
||||
@ -43,6 +43,9 @@ namespace minecraft::vulkan {
|
||||
VkFormat colorFormat;
|
||||
VkFormat depthFormat;
|
||||
|
||||
VkSampler linearSampler;
|
||||
VkImageView shadowDepthImageView;
|
||||
|
||||
//
|
||||
// method initialized
|
||||
//
|
||||
@ -54,8 +57,16 @@ namespace minecraft::vulkan {
|
||||
|
||||
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
|
||||
|
||||
VkDescriptorSetLayout descriptorSetLayouts[1]; // unrelated to maxFrames, unrelated to descriptorCount
|
||||
VkDescriptorSetLayout descriptorSetLayouts[2]; // unrelated to maxFrames, unrelated to descriptorCount
|
||||
VkDescriptorSet descriptorSets0[maxFrames];
|
||||
VkDescriptorSet descriptorSet1;
|
||||
|
||||
struct Image {
|
||||
VkImage image;
|
||||
VkDeviceMemory memory;
|
||||
VkImageView imageView;
|
||||
};
|
||||
Image terrainImage;
|
||||
|
||||
struct {
|
||||
VkDeviceMemory memory;
|
||||
@ -76,7 +87,9 @@ namespace minecraft::vulkan {
|
||||
VkPhysicalDeviceProperties physicalDeviceProperties,
|
||||
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties,
|
||||
VkFormat colorFormat,
|
||||
VkFormat depthFormat);
|
||||
VkFormat depthFormat,
|
||||
VkSampler linearSampler,
|
||||
VkImageView shadowDepthImageView);
|
||||
void init();
|
||||
void load_vertex_index_buffer(char const * vertex_filename,
|
||||
char const * index_filename);
|
||||
@ -89,6 +102,8 @@ namespace minecraft::vulkan {
|
||||
void transfer_transforms(XMMATRIX const & projection,
|
||||
XMMATRIX const & view,
|
||||
uint32_t frameIndex);
|
||||
void load_image(char const * filename,
|
||||
Image & image);
|
||||
|
||||
void draw(VkCommandBuffer commandBuffer,
|
||||
uint32_t frameIndex);
|
||||
|
||||
@ -14,6 +14,7 @@ struct VSInput
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float4 Texture : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct Scene
|
||||
@ -28,17 +29,33 @@ struct Scene
|
||||
// set 0: per-frame
|
||||
[[vk::binding(0, 0)]] ConstantBuffer<Scene> Scene;
|
||||
|
||||
// set 1: constant
|
||||
[[vk::binding(0, 1)]] SamplerState LinearSampler;
|
||||
[[vk::binding(1, 1)]] Texture2DArray ShadowTexture;
|
||||
[[vk::binding(2, 1)]] Texture2D TerrainTexture;
|
||||
|
||||
float2 yf(float2 v, float scale)
|
||||
{
|
||||
return float2(v.x, 1.0 - v.y) * scale;
|
||||
}
|
||||
|
||||
[shader("vertex")]
|
||||
VSOutput VSMain(VSInput input)
|
||||
{
|
||||
VSOutput output = (VSOutput)0;
|
||||
float4 Position = float4(input.Position.xyz + input.BlockPosition, 1.0);
|
||||
output.Position = mul(Scene.Projection, mul(Scene.View, Position));
|
||||
|
||||
float2 textureOffset = float2(input.TextureID % 8, input.TextureID / 8) * 16;
|
||||
output.Texture = float4(yf(input.Texture.xy, 16), textureOffset);
|
||||
return output;
|
||||
}
|
||||
|
||||
[shader("pixel")]
|
||||
float4 PSMain(VSOutput input) : SV_TARGET
|
||||
{
|
||||
return float4(1, 0, 0, 1);
|
||||
float2 texture = input.Texture.xy + input.Texture.zw;
|
||||
float4 color = TerrainTexture.Load(int3(texture, 0)).xyzw;
|
||||
|
||||
return float4(color.xyz, 1);
|
||||
}
|
||||
|
||||
@ -609,7 +609,9 @@ int main()
|
||||
physicalDeviceProperties,
|
||||
physicalDeviceMemoryProperties,
|
||||
surfaceFormat.format,
|
||||
depthFormat);
|
||||
depthFormat,
|
||||
textureSamplers[0],
|
||||
shadowDepthImageViewDepth);
|
||||
minecraft_state.init();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -29,7 +29,9 @@ namespace minecraft::vulkan {
|
||||
VkPhysicalDeviceProperties physicalDeviceProperties,
|
||||
VkPhysicalDeviceMemoryProperties physicalDeviceMemoryProperties,
|
||||
VkFormat colorFormat,
|
||||
VkFormat depthFormat)
|
||||
VkFormat depthFormat,
|
||||
VkSampler linearSampler,
|
||||
VkImageView shadowDepthImageView)
|
||||
{
|
||||
this->instance = instance;
|
||||
this->device = device;
|
||||
@ -41,12 +43,16 @@ namespace minecraft::vulkan {
|
||||
|
||||
this->colorFormat = colorFormat;
|
||||
this->depthFormat = depthFormat;
|
||||
|
||||
this->linearSampler = linearSampler;
|
||||
this->shadowDepthImageView = shadowDepthImageView;
|
||||
}
|
||||
|
||||
void vulkan::init()
|
||||
{
|
||||
load_vertex_index_buffer("data/minecraft/per_vertex.vtx", "data/minecraft/configuration.idx");
|
||||
load_shader();
|
||||
load_image("data/minecraft/terrain2.dds", terrainImage);
|
||||
create_uniform_buffers();
|
||||
create_descriptor_sets();
|
||||
write_descriptor_sets();
|
||||
@ -142,7 +148,7 @@ namespace minecraft::vulkan {
|
||||
{
|
||||
VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = 1,
|
||||
.setLayoutCount = 2,
|
||||
.pSetLayouts = descriptorSetLayouts,
|
||||
//.pushConstantRangeCount = 0,
|
||||
//.pPushConstantRanges = nullptr
|
||||
@ -388,6 +394,49 @@ namespace minecraft::vulkan {
|
||||
assert(offsetsIndex == uniformBufferDescriptorCount);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// images
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
void vulkan::load_image(char const * filename,
|
||||
Image & image)
|
||||
{
|
||||
VkCommandBuffer commandBuffer{};
|
||||
VkCommandBufferAllocateInfo commandBufferAllocateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.commandPool = commandPool,
|
||||
.commandBufferCount = 1
|
||||
};
|
||||
VK_CHECK(vkAllocateCommandBuffers(device, &commandBufferAllocateInfo, &commandBuffer));
|
||||
|
||||
VkFenceCreateInfo fenceCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
|
||||
};
|
||||
VkFence fence{};
|
||||
VK_CHECK(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
|
||||
|
||||
// load
|
||||
|
||||
createImageFromFilenameDDS(device,
|
||||
queue,
|
||||
commandBuffer,
|
||||
fence,
|
||||
physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||
physicalDeviceMemoryProperties,
|
||||
filename,
|
||||
&image.image,
|
||||
&image.memory,
|
||||
&image.imageView);
|
||||
|
||||
// cleanup
|
||||
|
||||
vkDestroyFence(device, fence, nullptr);
|
||||
vkFreeCommandBuffers(device,
|
||||
commandPool,
|
||||
1,
|
||||
&commandBuffer);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// descriptor sets
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -397,16 +446,24 @@ namespace minecraft::vulkan {
|
||||
//
|
||||
// pool
|
||||
//
|
||||
constexpr int descriptorPoolSizesCount = 1;
|
||||
constexpr int descriptorPoolSizesCount = 3;
|
||||
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = (maxFrames * 1),
|
||||
},
|
||||
{ // linear sampler
|
||||
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
},
|
||||
{
|
||||
.type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.descriptorCount = 1 + 1, // +1 for shadow sampler
|
||||
}
|
||||
};
|
||||
VkDescriptorPoolCreateInfo descriptorPoolCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.maxSets = maxFrames,
|
||||
.maxSets = maxFrames + 1,
|
||||
.poolSizeCount = descriptorPoolSizesCount,
|
||||
.pPoolSizes = descriptorPoolSizes
|
||||
};
|
||||
@ -446,6 +503,48 @@ namespace minecraft::vulkan {
|
||||
};
|
||||
VK_CHECK(vkAllocateDescriptorSets(device, &descriptorSetAllocateInfo, descriptorSets0));
|
||||
}
|
||||
|
||||
//
|
||||
// uniform buffer descriptor set layout/allocation (set 1, constant)
|
||||
//
|
||||
{
|
||||
constexpr int bindingCount = 3;
|
||||
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
||||
{
|
||||
.binding = 0,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||
},
|
||||
{ // shadow sampled image
|
||||
.binding = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||
},
|
||||
{ // terrain sampled image
|
||||
.binding = 2,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
|
||||
}
|
||||
};
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
.bindingCount = bindingCount,
|
||||
.pBindings = descriptorSetLayoutBindings
|
||||
};
|
||||
VK_CHECK(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCreateInfo, nullptr, &descriptorSetLayouts[1]));
|
||||
|
||||
VkDescriptorSetAllocateInfo descriptorSetAllocateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.descriptorPool = descriptorPool,
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = &descriptorSetLayouts[1]
|
||||
};
|
||||
VK_CHECK(vkAllocateDescriptorSets(device, &descriptorSetAllocateInfo, &descriptorSet1));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@ -459,6 +558,7 @@ namespace minecraft::vulkan {
|
||||
|
||||
VkDescriptorBufferInfo sceneDescriptorBufferInfos[maxFrames];
|
||||
|
||||
// set0 bindings
|
||||
for (uint32_t i = 0; i < maxFrames; i++) {
|
||||
sceneDescriptorBufferInfos[i] = {
|
||||
.buffer = shaderDataDevice.frame[i].sceneBuffer,
|
||||
@ -475,6 +575,43 @@ namespace minecraft::vulkan {
|
||||
};
|
||||
}
|
||||
|
||||
// set1 bindings
|
||||
VkDescriptorImageInfo samplerDescriptorImageInfo = {
|
||||
.sampler = linearSampler,
|
||||
};
|
||||
writeDescriptorSets[writeIndex++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSet1,
|
||||
.dstBinding = 0,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.pImageInfo = &samplerDescriptorImageInfo
|
||||
};
|
||||
VkDescriptorImageInfo shadowDepthDescriptorImageInfo = {
|
||||
.imageView = shadowDepthImageView,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL
|
||||
};
|
||||
writeDescriptorSets[writeIndex++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSet1,
|
||||
.dstBinding = 1,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.pImageInfo = &shadowDepthDescriptorImageInfo
|
||||
};
|
||||
VkDescriptorImageInfo terrainDescriptorImageInfo = {
|
||||
.imageView = terrainImage.imageView,
|
||||
.imageLayout = VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL
|
||||
};
|
||||
writeDescriptorSets[writeIndex++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSet1,
|
||||
.dstBinding = 2,
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.pImageInfo = &terrainDescriptorImageInfo
|
||||
};
|
||||
|
||||
assert(writeIndex == bindingCount);
|
||||
vkUpdateDescriptorSets(device, writeIndex, writeDescriptorSets, 0, nullptr);
|
||||
}
|
||||
@ -529,11 +666,12 @@ namespace minecraft::vulkan {
|
||||
{
|
||||
VkDescriptorSet descriptorSets[2] = {
|
||||
descriptorSets0[frameIndex],
|
||||
descriptorSet1,
|
||||
};
|
||||
vkCmdBindDescriptorSets(commandBuffer,
|
||||
VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
pipelineLayout,
|
||||
0, 1, descriptorSets,
|
||||
0, 2, descriptorSets,
|
||||
0, nullptr);
|
||||
|
||||
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset, VK_INDEX_TYPE_UINT16);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user