collada: animated eidelwind
This commit is contained in:
parent
440272ad7a
commit
dbd36f2d2c
3
Makefile
3
Makefile
@ -49,7 +49,8 @@ OBJS = \
|
|||||||
src/collada/animate.o
|
src/collada/animate.o
|
||||||
|
|
||||||
SCENES = \
|
SCENES = \
|
||||||
data/scenes/shadow_test/shadow_test.o
|
data/scenes/shadow_test/shadow_test.o \
|
||||||
|
data/scenes/eidelwind/eidelwind.o
|
||||||
|
|
||||||
ifeq ($(UNAME),Darwin)
|
ifeq ($(UNAME),Darwin)
|
||||||
LIBS = \
|
LIBS = \
|
||||||
|
|||||||
BIN
data/scenes/eidelwind/0_EidelWindTextureTest.dds
Normal file
BIN
data/scenes/eidelwind/0_EidelWindTextureTest.dds
Normal file
Binary file not shown.
5252
data/scenes/eidelwind/eidelwind.DAE
Normal file
5252
data/scenes/eidelwind/eidelwind.DAE
Normal file
File diff suppressed because one or more lines are too long
12602
data/scenes/eidelwind/eidelwind.cpp
Normal file
12602
data/scenes/eidelwind/eidelwind.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3
data/scenes/eidelwind/eidelwind.h
Normal file
3
data/scenes/eidelwind/eidelwind.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace eidelwind {
|
||||||
|
extern collada::types::descriptor const descriptor;
|
||||||
|
}
|
||||||
BIN
data/scenes/eidelwind/eidelwind.idx
Normal file
BIN
data/scenes/eidelwind/eidelwind.idx
Normal file
Binary file not shown.
BIN
data/scenes/eidelwind/eidelwind.vjw
Normal file
BIN
data/scenes/eidelwind/eidelwind.vjw
Normal file
Binary file not shown.
BIN
data/scenes/eidelwind/eidelwind.vtx
Normal file
BIN
data/scenes/eidelwind/eidelwind.vtx
Normal file
Binary file not shown.
BIN
data/scenes/eidelwind/images/0_EidelWindTextureTest.dds
Normal file
BIN
data/scenes/eidelwind/images/0_EidelWindTextureTest.dds
Normal file
Binary file not shown.
BIN
data/scenes/eidelwind/images/0_EidelWindTextureTest.png
Normal file
BIN
data/scenes/eidelwind/images/0_EidelWindTextureTest.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
@ -2,3 +2,8 @@ shader/collada.spv
|
|||||||
data/scenes/shadow_test/shadow_test.vtx
|
data/scenes/shadow_test/shadow_test.vtx
|
||||||
data/scenes/shadow_test/shadow_test.idx
|
data/scenes/shadow_test/shadow_test.idx
|
||||||
data/scenes/shadow_test/images/0_leaf_white.dds
|
data/scenes/shadow_test/images/0_leaf_white.dds
|
||||||
|
|
||||||
|
data/scenes/eidelwind/eidelwind.vtx
|
||||||
|
data/scenes/eidelwind/eidelwind.vjw
|
||||||
|
data/scenes/eidelwind/eidelwind.idx
|
||||||
|
data/scenes/eidelwind/images/0_EidelWindTextureTest.dds
|
||||||
|
|||||||
@ -18,6 +18,9 @@ namespace collada::scene {
|
|||||||
struct Node {
|
struct Node {
|
||||||
XMFLOAT4X4 world;
|
XMFLOAT4X4 world;
|
||||||
};
|
};
|
||||||
|
struct Joint {
|
||||||
|
XMFLOAT4X4 transform;
|
||||||
|
};
|
||||||
struct MaterialColor {
|
struct MaterialColor {
|
||||||
XMFLOAT4 emission;
|
XMFLOAT4 emission;
|
||||||
XMFLOAT4 ambient;
|
XMFLOAT4 ambient;
|
||||||
@ -41,12 +44,13 @@ namespace collada::scene {
|
|||||||
|
|
||||||
struct vulkan {
|
struct vulkan {
|
||||||
static constexpr uint32_t maxFrames = 2;
|
static constexpr uint32_t maxFrames = 2;
|
||||||
static constexpr uint32_t perFrameDescriptorCount = 2;
|
static constexpr uint32_t perFrameDescriptorCount = 3;
|
||||||
static constexpr uint32_t constantDescriptorCount = 1;
|
static constexpr uint32_t constantDescriptorCount = 1;
|
||||||
static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount + constantDescriptorCount;
|
static constexpr uint32_t uniformBufferDescriptorCount = maxFrames * perFrameDescriptorCount + constantDescriptorCount;
|
||||||
// +3: linear sampler, shadow sampled image, scene sampled image (array)
|
// +3: linear sampler, shadow sampled image, scene sampled image (array)
|
||||||
static constexpr uint32_t bindingCount = uniformBufferDescriptorCount + 3;
|
static constexpr uint32_t bindingCount = uniformBufferDescriptorCount + 3;
|
||||||
static constexpr int shaderVariantCount = 3;
|
static constexpr int shaderVariantCount = 3;
|
||||||
|
static constexpr uint32_t maxJointsCount = 128;
|
||||||
|
|
||||||
// externally initialized, opaque handle
|
// externally initialized, opaque handle
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
@ -70,6 +74,7 @@ namespace collada::scene {
|
|||||||
VkShaderModule shaderModule;
|
VkShaderModule shaderModule;
|
||||||
VkPipeline * pipelines; // per-scene, one per descriptor->inputs_list_count
|
VkPipeline * pipelines; // per-scene, one per descriptor->inputs_list_count
|
||||||
struct {
|
struct {
|
||||||
|
VkDeviceSize jointWeightOffset;
|
||||||
VkDeviceSize indexOffset;
|
VkDeviceSize indexOffset;
|
||||||
VkBuffer buffer;
|
VkBuffer buffer;
|
||||||
VkDeviceMemory memory;
|
VkDeviceMemory memory;
|
||||||
@ -107,6 +112,11 @@ namespace collada::scene {
|
|||||||
VkDeviceAddress nodesOffset;
|
VkDeviceAddress nodesOffset;
|
||||||
VkDeviceAddress nodesSize;
|
VkDeviceAddress nodesSize;
|
||||||
void * nodesMapped;
|
void * nodesMapped;
|
||||||
|
|
||||||
|
VkBuffer jointsBuffer;
|
||||||
|
VkDeviceAddress jointsOffset;
|
||||||
|
VkDeviceAddress jointsSize;
|
||||||
|
void * jointsMapped;
|
||||||
} frame[maxFrames];
|
} frame[maxFrames];
|
||||||
struct { // must match constantDescriptorCount
|
struct { // must match constantDescriptorCount
|
||||||
VkBuffer materialColorImagesBuffer;
|
VkBuffer materialColorImagesBuffer;
|
||||||
@ -151,6 +161,7 @@ namespace collada::scene {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void load_vertex_index_buffer(char const * vertex_filename,
|
void load_vertex_index_buffer(char const * vertex_filename,
|
||||||
|
char const * vertex_joint_weight_filename,
|
||||||
char const * index_filename);
|
char const * index_filename);
|
||||||
void create_pipelines(collada::types::descriptor const * const descriptor);
|
void create_pipelines(collada::types::descriptor const * const descriptor);
|
||||||
|
|
||||||
@ -171,9 +182,18 @@ namespace collada::scene {
|
|||||||
void draw_instance_geometries(types::instance_geometry const * const instance_geometries,
|
void draw_instance_geometries(types::instance_geometry const * const instance_geometries,
|
||||||
int const instance_geometries_count);
|
int const instance_geometries_count);
|
||||||
|
|
||||||
|
void draw_skin(types::skin const & skin,
|
||||||
|
types::instance_material const * const instance_materials,
|
||||||
|
int const instance_materials_count);
|
||||||
|
|
||||||
|
void draw_instance_controllers(types::instance_controller const * const instance_controllers,
|
||||||
|
int const instance_controllers_count,
|
||||||
|
instance_types::node const * const node_instances);
|
||||||
|
|
||||||
void draw_node(int32_t node_index,
|
void draw_node(int32_t node_index,
|
||||||
types::node const & node,
|
types::node const & node,
|
||||||
instance_types::node const & node_instance);
|
instance_types::node const & node_instance,
|
||||||
|
instance_types::node const * const node_instances);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// called by state::update
|
// called by state::update
|
||||||
|
|||||||
@ -5,6 +5,15 @@ struct VSInput
|
|||||||
float3 Texture : TEXCOORD0;
|
float3 Texture : TEXCOORD0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct VSSkinnedInput
|
||||||
|
{
|
||||||
|
float3 Position : POSITION0;
|
||||||
|
float3 Normal : NORMAL0;
|
||||||
|
float3 Texture : TEXCOORD0;
|
||||||
|
int4 BlendIndices : BLENDINDICES0;
|
||||||
|
float4 BlendWeight : BLENDWEIGHT0;
|
||||||
|
};
|
||||||
|
|
||||||
struct VSOutput
|
struct VSOutput
|
||||||
{
|
{
|
||||||
float4 Position : SV_POSITION;
|
float4 Position : SV_POSITION;
|
||||||
@ -26,6 +35,11 @@ struct Node
|
|||||||
column_major float4x4 World;
|
column_major float4x4 World;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Joint
|
||||||
|
{
|
||||||
|
column_major float4x4 Transform;
|
||||||
|
};
|
||||||
|
|
||||||
struct Scene
|
struct Scene
|
||||||
{
|
{
|
||||||
column_major float4x4 Projection;
|
column_major float4x4 Projection;
|
||||||
@ -58,6 +72,7 @@ struct MaterialColorImage
|
|||||||
// set 0: per-frame
|
// set 0: per-frame
|
||||||
[[vk::binding(0, 0)]] ConstantBuffer<Scene> Scene;
|
[[vk::binding(0, 0)]] ConstantBuffer<Scene> Scene;
|
||||||
[[vk::binding(1, 0)]] StructuredBuffer<Node> Nodes;
|
[[vk::binding(1, 0)]] StructuredBuffer<Node> Nodes;
|
||||||
|
[[vk::binding(2, 0)]] StructuredBuffer<Joint> Joints;
|
||||||
|
|
||||||
// set 1: constant
|
// set 1: constant
|
||||||
[[vk::binding(0, 1)]] StructuredBuffer<MaterialColorImage> MaterialColorImages;
|
[[vk::binding(0, 1)]] StructuredBuffer<MaterialColorImage> MaterialColorImages;
|
||||||
@ -72,10 +87,9 @@ struct PushConstant {
|
|||||||
|
|
||||||
[[vk::push_constant]] PushConstant constants;
|
[[vk::push_constant]] PushConstant constants;
|
||||||
|
|
||||||
float4 getView(float4x4 view, float3 position)
|
float4 getView(float4x4 view, float4 position)
|
||||||
{
|
{
|
||||||
float4x4 world = Nodes[constants.NodeIndex].World;
|
return mul(view, position);
|
||||||
return mul(view, mul(world, float4(position.xyz, 1.0)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 getProjection(float4x4 projection, float4 viewPosition)
|
float4 getProjection(float4x4 projection, float4 viewPosition)
|
||||||
@ -83,17 +97,40 @@ float4 getProjection(float4x4 projection, float4 viewPosition)
|
|||||||
return mul(projection, viewPosition) * float4(-1, -1, 1, 1);
|
return mul(projection, viewPosition) * float4(-1, -1, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[shader("vertex")]
|
float2 yf(float2 v)
|
||||||
VSOutput VSMain(VSInput input)
|
|
||||||
{
|
{
|
||||||
float4 viewPosition = getView(Scene.View, input.Position);
|
return float2(v.x, 1.0 - v.y);
|
||||||
float4 shadowPosition = getProjection(Scene.ShadowProjection, getView(Scene.ShadowView, input.Position));
|
}
|
||||||
|
|
||||||
|
float4x4 getWorld(VSSkinnedInput input)
|
||||||
|
{
|
||||||
|
float4x4 world
|
||||||
|
= input.BlendWeight.x * Joints[input.BlendIndices.x].Transform
|
||||||
|
+ input.BlendWeight.y * Joints[input.BlendIndices.y].Transform
|
||||||
|
+ input.BlendWeight.z * Joints[input.BlendIndices.z].Transform
|
||||||
|
+ input.BlendWeight.w * Joints[input.BlendIndices.w].Transform
|
||||||
|
;
|
||||||
|
//float4x4 world = Nodes[constants.NodeIndex].World;
|
||||||
|
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("vertex")]
|
||||||
|
VSOutput VSMain(VSSkinnedInput input)
|
||||||
|
{
|
||||||
|
float4x4 world = getWorld(input);
|
||||||
|
|
||||||
|
float4 worldPosition = mul(world, float4(input.Position, 1.0));
|
||||||
|
float4 viewPosition = getView(Scene.View, worldPosition);
|
||||||
|
float4 shadowPosition = getProjection(Scene.ShadowProjection, getView(Scene.ShadowView, worldPosition));
|
||||||
|
|
||||||
VSOutput output = (VSOutput)0;
|
VSOutput output = (VSOutput)0;
|
||||||
|
//output.Position = getProjection(Scene.ShadowProjection, viewPosition);
|
||||||
output.Position = getProjection(Scene.Projection, viewPosition);
|
output.Position = getProjection(Scene.Projection, viewPosition);
|
||||||
|
|
||||||
output.ShadowPosition = shadowPosition * float4(0.5, 0.5, 1.0, 1.0) + float4(0.5, 0.5, 0.0, 0.0);
|
output.ShadowPosition = shadowPosition * float4(0.5, 0.5, 1.0, 1.0) + float4(0.5, 0.5, 0.0, 0.0);
|
||||||
output.Normal = mul((float3x3)Scene.View, mul((float3x3)Nodes[constants.NodeIndex].World, input.Normal));
|
output.Normal = mul((float3x3)Scene.View, mul((float3x3)Nodes[constants.NodeIndex].World, input.Normal));
|
||||||
output.Texture = input.Texture.xy * 1.0;
|
output.Texture = yf(input.Texture.xy);
|
||||||
|
|
||||||
output.LightDirection = (Scene.LightPosition - viewPosition).xyz;
|
output.LightDirection = (Scene.LightPosition - viewPosition).xyz;
|
||||||
output.ViewDirection = -viewPosition.xyz;
|
output.ViewDirection = -viewPosition.xyz;
|
||||||
@ -135,17 +172,17 @@ float4 PSMain(VSOutput input) : SV_TARGET
|
|||||||
float4 specularColor;
|
float4 specularColor;
|
||||||
float4 emissionColor;
|
float4 emissionColor;
|
||||||
if (MCI.Image.Diffuse >= 0) {
|
if (MCI.Image.Diffuse >= 0) {
|
||||||
diffuseColor = SceneTexture[MCI.Image.Diffuse].Sample(LinearSampler, input.Texture).bgra;
|
diffuseColor = SceneTexture[MCI.Image.Diffuse].Sample(LinearSampler, input.Texture).rgba;
|
||||||
} else {
|
} else {
|
||||||
diffuseColor = MCI.Color.Diffuse;
|
diffuseColor = MCI.Color.Diffuse;
|
||||||
}
|
}
|
||||||
if (MCI.Image.Specular >= 0) {
|
if (MCI.Image.Specular >= 0) {
|
||||||
specularColor = SceneTexture[MCI.Image.Specular].Sample(LinearSampler, input.Texture).bgra;
|
specularColor = SceneTexture[MCI.Image.Specular].Sample(LinearSampler, input.Texture).rgba;
|
||||||
} else {
|
} else {
|
||||||
specularColor = MCI.Color.Specular;
|
specularColor = MCI.Color.Specular;
|
||||||
}
|
}
|
||||||
if (MCI.Image.Emission >= 0) {
|
if (MCI.Image.Emission >= 0) {
|
||||||
emissionColor = SceneTexture[MCI.Image.Emission].Sample(LinearSampler, input.Texture).bgra;
|
emissionColor = SceneTexture[MCI.Image.Emission].Sample(LinearSampler, input.Texture).rgba;
|
||||||
} else {
|
} else {
|
||||||
emissionColor = MCI.Color.Emission;
|
emissionColor = MCI.Color.Emission;
|
||||||
}
|
}
|
||||||
@ -195,7 +232,7 @@ struct GSGeometryOutput
|
|||||||
[maxvertexcount(6)]
|
[maxvertexcount(6)]
|
||||||
void GSGeometryMain(triangle VSGeometryOutput input[3], inout LineStream<GSGeometryOutput> outputStream)
|
void GSGeometryMain(triangle VSGeometryOutput input[3], inout LineStream<GSGeometryOutput> outputStream)
|
||||||
{
|
{
|
||||||
float normalLength = 2.0;
|
float normalLength = 0.1;
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
float3 position = input[i].Position.xyz;
|
float3 position = input[i].Position.xyz;
|
||||||
@ -203,11 +240,11 @@ void GSGeometryMain(triangle VSGeometryOutput input[3], inout LineStream<GSGeome
|
|||||||
float3 positionNormal = position + normal * normalLength;
|
float3 positionNormal = position + normal * normalLength;
|
||||||
|
|
||||||
GSGeometryOutput output = (GSGeometryOutput)0;
|
GSGeometryOutput output = (GSGeometryOutput)0;
|
||||||
output.Position = getProjection(Scene.Projection, getView(Scene.View, position));
|
output.Position = getProjection(Scene.Projection, getView(Scene.View, float4(position, 1.0)));
|
||||||
output.Color = float3(1, 0, 0);
|
output.Color = float3(1, 0, 0);
|
||||||
outputStream.Append(output);
|
outputStream.Append(output);
|
||||||
|
|
||||||
output.Position = getProjection(Scene.Projection, getView(Scene.View, positionNormal));
|
output.Position = getProjection(Scene.Projection, getView(Scene.View, float4(positionNormal, 1.0)));
|
||||||
output.Color = float3(0, 1, 0);
|
output.Color = float3(0, 1, 0);
|
||||||
outputStream.Append(output);
|
outputStream.Append(output);
|
||||||
|
|
||||||
@ -222,9 +259,12 @@ float4 PSGeometryMain(GSGeometryOutput input) : SV_TARGET
|
|||||||
}
|
}
|
||||||
|
|
||||||
[shader("vertex")]
|
[shader("vertex")]
|
||||||
VSShadowOutput VSShadowMain(VSInput input)
|
VSShadowOutput VSShadowMain(VSSkinnedInput input)
|
||||||
{
|
{
|
||||||
float4 viewPosition = getView(Scene.ShadowView, input.Position);
|
float4x4 world = getWorld(input);
|
||||||
|
|
||||||
|
float4 worldPosition = mul(world, float4(input.Position, 1.0));
|
||||||
|
float4 viewPosition = getView(Scene.ShadowView, worldPosition);
|
||||||
|
|
||||||
VSShadowOutput output = (VSShadowOutput)0;
|
VSShadowOutput output = (VSShadowOutput)0;
|
||||||
output.Position = getProjection(Scene.ShadowProjection, viewPosition);
|
output.Position = getProjection(Scene.ShadowProjection, viewPosition);
|
||||||
|
|||||||
@ -12,6 +12,7 @@ namespace collada::scene {
|
|||||||
this->descriptor = descriptor;
|
this->descriptor = descriptor;
|
||||||
|
|
||||||
vulkan.load_vertex_index_buffer(descriptor->position_normal_texture_buffer,
|
vulkan.load_vertex_index_buffer(descriptor->position_normal_texture_buffer,
|
||||||
|
descriptor->joint_weight_buffer,
|
||||||
descriptor->index_buffer);
|
descriptor->index_buffer);
|
||||||
vulkan.create_uniform_buffers(descriptor);
|
vulkan.create_uniform_buffers(descriptor);
|
||||||
vulkan.create_descriptor_sets(descriptor);
|
vulkan.create_descriptor_sets(descriptor);
|
||||||
@ -29,13 +30,13 @@ namespace collada::scene {
|
|||||||
types::node const & node = *descriptor->nodes[i];
|
types::node const & node = *descriptor->nodes[i];
|
||||||
instance_types::node const & node_instance = node_state.node_instances[i];
|
instance_types::node const & node_instance = node_state.node_instances[i];
|
||||||
|
|
||||||
if (node.instance_geometries_count <= 0)
|
if (node.type != types::node_type::NODE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
vulkan.draw_node(i,
|
vulkan.draw_node(i,
|
||||||
node,
|
node,
|
||||||
node_instance);
|
node_instance,
|
||||||
|
node_state.node_instances);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ namespace collada::scene {
|
|||||||
|
|
||||||
void state::update(float t)
|
void state::update(float t)
|
||||||
{
|
{
|
||||||
t = animate::loop(t, 3.3f);
|
t = animate::loop(t, 1.0f);
|
||||||
|
|
||||||
for (int i = 0; i < descriptor->nodes_count; i++) {
|
for (int i = 0; i < descriptor->nodes_count; i++) {
|
||||||
animate::animate_node(node_state.node_instances[i], t);
|
animate::animate_node(node_state.node_instances[i], t);
|
||||||
|
|||||||
@ -79,25 +79,46 @@ inline static void vulkan_vertex_input_states(collada::types::descriptor const *
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < descriptor->inputs_list_count; i++) {
|
for (int i = 0; i < descriptor->inputs_list_count; i++) {
|
||||||
collada::types::inputs const & inputs = descriptor->inputs_list[i];
|
collada::types::inputs const & inputs = descriptor->inputs_list[i];
|
||||||
VkVertexInputAttributeDescription * vertexAttributeDescriptions = NewM<VkVertexInputAttributeDescription>(inputs.elements_count);
|
VkVertexInputAttributeDescription * vertexAttributeDescriptions = NewM<VkVertexInputAttributeDescription>(inputs.elements_count + collada::inputs::skin_inputs.elements_count);
|
||||||
uint32_t stride = vulkan_load_layout(inputs,
|
uint32_t stride = vulkan_load_layout(inputs,
|
||||||
0, // binding
|
0, // binding
|
||||||
0, // start_offset
|
0, // start_offset
|
||||||
vertexAttributeDescriptions);
|
vertexAttributeDescriptions);
|
||||||
|
|
||||||
vertexBindingDescriptions[i] = {
|
uint32_t vertexJointWeightStride = vulkan_load_layout(collada::inputs::skin_inputs,
|
||||||
|
1, // binding
|
||||||
|
0, // start_offset
|
||||||
|
&vertexAttributeDescriptions[inputs.elements_count]);
|
||||||
|
|
||||||
|
vertexBindingDescriptions[i * 2 + 0] = {
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
.stride = stride,
|
.stride = stride,
|
||||||
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
||||||
};
|
};
|
||||||
|
|
||||||
vertexInputStates[i] = {
|
vertexBindingDescriptions[i * 2 + 1] = {
|
||||||
|
.binding = 1,
|
||||||
|
.stride = vertexJointWeightStride,
|
||||||
|
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
|
||||||
|
};
|
||||||
|
|
||||||
|
// non-skinned
|
||||||
|
vertexInputStates[i * 2 + 0] = {
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||||
.vertexBindingDescriptionCount = 1,
|
.vertexBindingDescriptionCount = 1,
|
||||||
.pVertexBindingDescriptions = &vertexBindingDescriptions[i],
|
.pVertexBindingDescriptions = &vertexBindingDescriptions[i * 2 + 0],
|
||||||
.vertexAttributeDescriptionCount = (uint32_t)inputs.elements_count,
|
.vertexAttributeDescriptionCount = (uint32_t)inputs.elements_count,
|
||||||
.pVertexAttributeDescriptions = vertexAttributeDescriptions,
|
.pVertexAttributeDescriptions = vertexAttributeDescriptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// skinned
|
||||||
|
vertexInputStates[i * 2 + 1] = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
|
||||||
|
.vertexBindingDescriptionCount = 2,
|
||||||
|
.pVertexBindingDescriptions = &vertexBindingDescriptions[i * 2 + 0],
|
||||||
|
.vertexAttributeDescriptionCount = (uint32_t)(inputs.elements_count + collada::inputs::skin_inputs.elements_count),
|
||||||
|
.pVertexAttributeDescriptions = vertexAttributeDescriptions,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,18 +157,22 @@ namespace collada::scene {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void vulkan::load_vertex_index_buffer(char const * vertex_filename,
|
void vulkan::load_vertex_index_buffer(char const * vertex_filename,
|
||||||
|
char const * vertex_joint_weight_filename,
|
||||||
char const * index_filename)
|
char const * index_filename)
|
||||||
{
|
{
|
||||||
uint32_t vertexSize;
|
uint32_t vertexSize;
|
||||||
void const * vertexStart = file::open(vertex_filename, &vertexSize);
|
void const * vertexStart = file::open(vertex_filename, &vertexSize);
|
||||||
|
uint32_t vertexJointWeightSize;
|
||||||
|
void const * vertexJointWeightStart = file::open(vertex_joint_weight_filename, &vertexJointWeightSize);
|
||||||
uint32_t indexSize;
|
uint32_t indexSize;
|
||||||
void const * indexStart = file::open(index_filename, &indexSize);
|
void const * indexStart = file::open(index_filename, &indexSize);
|
||||||
|
|
||||||
vertexIndex.indexOffset = vertexSize; // + vertexJWStart;
|
vertexIndex.jointWeightOffset = vertexSize;
|
||||||
|
vertexIndex.indexOffset = vertexSize + vertexJointWeightSize;
|
||||||
|
|
||||||
// create buffer
|
// create buffer
|
||||||
|
|
||||||
VkDeviceSize bufferSize{ vertexSize + indexSize };
|
VkDeviceSize bufferSize{ vertexSize + vertexJointWeightSize + indexSize };
|
||||||
VkBufferCreateInfo vertexIndexBufferCreateInfo{
|
VkBufferCreateInfo vertexIndexBufferCreateInfo{
|
||||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
.size = bufferSize,
|
.size = bufferSize,
|
||||||
@ -180,7 +205,8 @@ namespace collada::scene {
|
|||||||
void * vertexIndexMappedData;
|
void * vertexIndexMappedData;
|
||||||
VK_CHECK(vkMapMemory(device, vertexIndex.memory, 0, VK_WHOLE_SIZE, 0, &vertexIndexMappedData));
|
VK_CHECK(vkMapMemory(device, vertexIndex.memory, 0, VK_WHOLE_SIZE, 0, &vertexIndexMappedData));
|
||||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vertexStart, vertexSize);
|
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + 0), vertexStart, vertexSize);
|
||||||
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize), indexStart, indexSize);
|
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize), vertexJointWeightStart, vertexJointWeightSize);
|
||||||
|
memcpy((void *)(((ptrdiff_t)vertexIndexMappedData) + vertexSize + vertexJointWeightSize), indexStart, indexSize);
|
||||||
|
|
||||||
VkMappedMemoryRange mappedMemoryRange{
|
VkMappedMemoryRange mappedMemoryRange{
|
||||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||||
@ -229,6 +255,16 @@ namespace collada::scene {
|
|||||||
};
|
};
|
||||||
VK_CHECK(vkCreateBuffer(device, &nodesBufferCreateInfo, nullptr, &shaderDataDevice.frame[i].nodesBuffer));
|
VK_CHECK(vkCreateBuffer(device, &nodesBufferCreateInfo, nullptr, &shaderDataDevice.frame[i].nodesBuffer));
|
||||||
vkGetBufferMemoryRequirements(device, shaderDataDevice.frame[i].nodesBuffer, &memoryRequirements[memoryRequirementsIndex++]);
|
vkGetBufferMemoryRequirements(device, shaderDataDevice.frame[i].nodesBuffer, &memoryRequirements[memoryRequirementsIndex++]);
|
||||||
|
|
||||||
|
// joints buffer
|
||||||
|
VkBufferCreateInfo jointsBufferCreateInfo{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.size = (sizeof (Joint)) * maxJointsCount,
|
||||||
|
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
|
||||||
|
.sharingMode = VK_SHARING_MODE_EXCLUSIVE
|
||||||
|
};
|
||||||
|
VK_CHECK(vkCreateBuffer(device, &jointsBufferCreateInfo, nullptr, &shaderDataDevice.frame[i].jointsBuffer));
|
||||||
|
vkGetBufferMemoryRequirements(device, shaderDataDevice.frame[i].jointsBuffer, &memoryRequirements[memoryRequirementsIndex++]);
|
||||||
};
|
};
|
||||||
|
|
||||||
// material color buffer
|
// material color buffer
|
||||||
@ -272,6 +308,11 @@ namespace collada::scene {
|
|||||||
shaderDataDevice.frame[i].nodesSize = memoryRequirements[offsetsIndex++].size;
|
shaderDataDevice.frame[i].nodesSize = memoryRequirements[offsetsIndex++].size;
|
||||||
shaderDataDevice.frame[i].nodesMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.frame[i].nodesOffset);
|
shaderDataDevice.frame[i].nodesMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.frame[i].nodesOffset);
|
||||||
VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.frame[i].nodesBuffer, shaderDataDevice.memory, shaderDataDevice.frame[i].nodesOffset));
|
VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.frame[i].nodesBuffer, shaderDataDevice.memory, shaderDataDevice.frame[i].nodesOffset));
|
||||||
|
|
||||||
|
shaderDataDevice.frame[i].jointsOffset = offsets[offsetsIndex];
|
||||||
|
shaderDataDevice.frame[i].jointsSize = memoryRequirements[offsetsIndex++].size;
|
||||||
|
shaderDataDevice.frame[i].jointsMapped = (void *)(((size_t)shaderDataDevice.mappedData) + shaderDataDevice.frame[i].jointsOffset);
|
||||||
|
VK_CHECK(vkBindBufferMemory(device, shaderDataDevice.frame[i].jointsBuffer, shaderDataDevice.memory, shaderDataDevice.frame[i].jointsOffset));
|
||||||
}
|
}
|
||||||
shaderDataDevice.constant.materialColorImagesOffset = offsets[offsetsIndex];
|
shaderDataDevice.constant.materialColorImagesOffset = offsets[offsetsIndex];
|
||||||
shaderDataDevice.constant.materialColorImagesSize = memoryRequirements[offsetsIndex++].size;
|
shaderDataDevice.constant.materialColorImagesSize = memoryRequirements[offsetsIndex++].size;
|
||||||
@ -294,11 +335,11 @@ namespace collada::scene {
|
|||||||
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
VkDescriptorPoolSize descriptorPoolSizes[descriptorPoolSizesCount]{
|
||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
.descriptorCount = maxFrames,
|
.descriptorCount = (maxFrames * 1),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
.type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
.descriptorCount = maxFrames + 1, // +1 for materialColorImages
|
.descriptorCount = (maxFrames * 2) + 1, // +1 for materialColorImages
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
.type = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||||
@ -321,7 +362,7 @@ namespace collada::scene {
|
|||||||
// uniform buffer descriptor set layout/allocation (set 0, per-frame)
|
// uniform buffer descriptor set layout/allocation (set 0, per-frame)
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
constexpr int bindingCount = 2;
|
constexpr int bindingCount = 3;
|
||||||
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
VkDescriptorSetLayoutBinding descriptorSetLayoutBindings[bindingCount]{
|
||||||
{
|
{
|
||||||
.binding = 0,
|
.binding = 0,
|
||||||
@ -334,6 +375,12 @@ namespace collada::scene {
|
|||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_GEOMETRY_BIT
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.binding = 2,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -418,6 +465,7 @@ namespace collada::scene {
|
|||||||
|
|
||||||
VkDescriptorBufferInfo sceneDescriptorBufferInfos[maxFrames];
|
VkDescriptorBufferInfo sceneDescriptorBufferInfos[maxFrames];
|
||||||
VkDescriptorBufferInfo nodesDescriptorBufferInfos[maxFrames];
|
VkDescriptorBufferInfo nodesDescriptorBufferInfos[maxFrames];
|
||||||
|
VkDescriptorBufferInfo jointsDescriptorBufferInfos[maxFrames];
|
||||||
|
|
||||||
for (uint32_t i = 0; i < maxFrames; i++) {
|
for (uint32_t i = 0; i < maxFrames; i++) {
|
||||||
sceneDescriptorBufferInfos[i] = {
|
sceneDescriptorBufferInfos[i] = {
|
||||||
@ -446,6 +494,19 @@ namespace collada::scene {
|
|||||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
.pBufferInfo = &nodesDescriptorBufferInfos[i]
|
.pBufferInfo = &nodesDescriptorBufferInfos[i]
|
||||||
};
|
};
|
||||||
|
jointsDescriptorBufferInfos[i] = {
|
||||||
|
.buffer = shaderDataDevice.frame[i].jointsBuffer,
|
||||||
|
.offset = 0,
|
||||||
|
.range = shaderDataDevice.frame[i].jointsSize,
|
||||||
|
};
|
||||||
|
writeDescriptorSets[writeIndex++] = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||||
|
.dstSet = descriptorSets0[i],
|
||||||
|
.dstBinding = 2,
|
||||||
|
.descriptorCount = 1,
|
||||||
|
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
.pBufferInfo = &jointsDescriptorBufferInfos[i]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorBufferInfo materialColorImagesDescriptorBufferInfo{
|
VkDescriptorBufferInfo materialColorImagesDescriptorBufferInfo{
|
||||||
@ -758,6 +819,15 @@ namespace collada::scene {
|
|||||||
.writeMask = 0x01,
|
.writeMask = 0x01,
|
||||||
.reference = 1,
|
.reference = 1,
|
||||||
},
|
},
|
||||||
|
.back = {
|
||||||
|
.failOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.passOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.depthFailOp = VK_STENCIL_OP_REPLACE,
|
||||||
|
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||||
|
.compareMask = 0x01,
|
||||||
|
.writeMask = 0x01,
|
||||||
|
.reference = 1,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineRenderingCreateInfo renderingCreateInfo{
|
VkPipelineRenderingCreateInfo renderingCreateInfo{
|
||||||
@ -786,8 +856,8 @@ namespace collada::scene {
|
|||||||
};
|
};
|
||||||
VkPipelineRasterizationStateCreateInfo rasterizationState{
|
VkPipelineRasterizationStateCreateInfo rasterizationState{
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
|
||||||
.cullMode = VK_CULL_MODE_BACK_BIT,
|
//.cullMode = VK_CULL_MODE_BACK_BIT,
|
||||||
//.cullMode = VK_CULL_MODE_NONE,
|
.cullMode = VK_CULL_MODE_NONE,
|
||||||
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE,
|
||||||
.lineWidth = 1.0f
|
.lineWidth = 1.0f
|
||||||
};
|
};
|
||||||
@ -803,8 +873,8 @@ namespace collada::scene {
|
|||||||
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
|
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT
|
||||||
};
|
};
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo * vertexInputStates = NewM<VkPipelineVertexInputStateCreateInfo>(descriptor->inputs_list_count);
|
VkPipelineVertexInputStateCreateInfo * vertexInputStates = NewM<VkPipelineVertexInputStateCreateInfo>(descriptor->inputs_list_count * 2);
|
||||||
VkVertexInputBindingDescription * vertexBindingDescriptions = NewM<VkVertexInputBindingDescription>(descriptor->inputs_list_count);
|
VkVertexInputBindingDescription * vertexBindingDescriptions = NewM<VkVertexInputBindingDescription>(descriptor->inputs_list_count * 2);
|
||||||
vulkan_vertex_input_states(descriptor,
|
vulkan_vertex_input_states(descriptor,
|
||||||
vertexInputStates,
|
vertexInputStates,
|
||||||
vertexBindingDescriptions);
|
vertexBindingDescriptions);
|
||||||
@ -819,7 +889,7 @@ namespace collada::scene {
|
|||||||
.pNext = &shadowRenderingCreateInfo,
|
.pNext = &shadowRenderingCreateInfo,
|
||||||
.stageCount = 2,
|
.stageCount = 2,
|
||||||
.pStages = shadowShaderStages,
|
.pStages = shadowShaderStages,
|
||||||
.pVertexInputState = &vertexInputStates[i],
|
.pVertexInputState = &vertexInputStates[i * 2 + 1],
|
||||||
.pInputAssemblyState = &inputAssemblyState,
|
.pInputAssemblyState = &inputAssemblyState,
|
||||||
.pViewportState = &viewportState,
|
.pViewportState = &viewportState,
|
||||||
.pRasterizationState = &shadowRasterizationState,
|
.pRasterizationState = &shadowRasterizationState,
|
||||||
@ -836,7 +906,7 @@ namespace collada::scene {
|
|||||||
.pNext = &renderingCreateInfo,
|
.pNext = &renderingCreateInfo,
|
||||||
.stageCount = 2,
|
.stageCount = 2,
|
||||||
.pStages = shaderStages,
|
.pStages = shaderStages,
|
||||||
.pVertexInputState = &vertexInputStates[i],
|
.pVertexInputState = &vertexInputStates[i * 2 + 1],
|
||||||
.pInputAssemblyState = &inputAssemblyState,
|
.pInputAssemblyState = &inputAssemblyState,
|
||||||
.pViewportState = &viewportState,
|
.pViewportState = &viewportState,
|
||||||
.pRasterizationState = &rasterizationState,
|
.pRasterizationState = &rasterizationState,
|
||||||
@ -853,7 +923,7 @@ namespace collada::scene {
|
|||||||
.pNext = &renderingCreateInfo,
|
.pNext = &renderingCreateInfo,
|
||||||
.stageCount = 3,
|
.stageCount = 3,
|
||||||
.pStages = geometryShaderStages,
|
.pStages = geometryShaderStages,
|
||||||
.pVertexInputState = &vertexInputStates[i],
|
.pVertexInputState = &vertexInputStates[i * 2 + 1],
|
||||||
.pInputAssemblyState = &inputAssemblyState,
|
.pInputAssemblyState = &inputAssemblyState,
|
||||||
.pViewportState = &viewportState,
|
.pViewportState = &viewportState,
|
||||||
.pRasterizationState = &rasterizationState,
|
.pRasterizationState = &rasterizationState,
|
||||||
@ -872,7 +942,7 @@ namespace collada::scene {
|
|||||||
|
|
||||||
free(vertexBindingDescriptions);
|
free(vertexBindingDescriptions);
|
||||||
for (int i = 0; i < descriptor->inputs_list_count; i++) {
|
for (int i = 0; i < descriptor->inputs_list_count; i++) {
|
||||||
free((void *)vertexInputStates[i].pVertexAttributeDescriptions);
|
free((void *)vertexInputStates[i * 2 + 0].pVertexAttributeDescriptions); // [i * 2 + 1] uses same pointer
|
||||||
}
|
}
|
||||||
free(vertexInputStates);
|
free(vertexInputStates);
|
||||||
}
|
}
|
||||||
@ -885,6 +955,7 @@ namespace collada::scene {
|
|||||||
types::instance_material const * const instance_materials,
|
types::instance_material const * const instance_materials,
|
||||||
int const instance_materials_count)
|
int const instance_materials_count)
|
||||||
{
|
{
|
||||||
|
assert(false);
|
||||||
types::mesh const& mesh = geometry.mesh;
|
types::mesh const& mesh = geometry.mesh;
|
||||||
|
|
||||||
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset + mesh.index_buffer_offset, VK_INDEX_TYPE_UINT32);
|
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset + mesh.index_buffer_offset, VK_INDEX_TYPE_UINT32);
|
||||||
@ -921,6 +992,99 @@ namespace collada::scene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vulkan::draw_skin(types::skin const & skin,
|
||||||
|
types::instance_material const * const instance_materials,
|
||||||
|
int const instance_materials_count)
|
||||||
|
{
|
||||||
|
types::mesh const& mesh = skin.geometry->mesh;
|
||||||
|
|
||||||
|
vkCmdBindIndexBuffer(commandBuffer, vertexIndex.buffer, vertexIndex.indexOffset + mesh.index_buffer_offset, VK_INDEX_TYPE_UINT32);
|
||||||
|
|
||||||
|
for (int j = 0; j < instance_materials_count; j++) {
|
||||||
|
types::instance_material const& instance_material = instance_materials[j];
|
||||||
|
int materialIndex = instance_material.material_index;
|
||||||
|
if (materialIndex == excludeMaterialIndex) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
types::triangles const& triangles = mesh.triangles[instance_material.element_index];
|
||||||
|
|
||||||
|
VkShaderStageFlags stageFlags{ VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT };
|
||||||
|
constexpr uint32_t offset{ (offsetof (PushConstant, materialIndex)) };
|
||||||
|
vkCmdPushConstants(commandBuffer, pipelineLayout, stageFlags, offset, (sizeof (uint32_t)), &materialIndex);
|
||||||
|
|
||||||
|
VkBuffer buffers[2] = {
|
||||||
|
vertexIndex.buffer,
|
||||||
|
vertexIndex.buffer,
|
||||||
|
};
|
||||||
|
VkDeviceSize offsets[2] = {
|
||||||
|
(VkDeviceSize)mesh.vertex_buffer_offset,
|
||||||
|
vertexIndex.jointWeightOffset + (VkDeviceSize)skin.vertex_buffer_offset,
|
||||||
|
};
|
||||||
|
vkCmdBindVertexBuffers(commandBuffer, 0, 2, buffers, offsets);
|
||||||
|
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[triangles.inputs_index * shaderVariantCount + pipelineIndex]);
|
||||||
|
|
||||||
|
uint32_t indexCount = triangles.count * 3;
|
||||||
|
vkCmdDrawIndexed(commandBuffer, indexCount, 1, triangles.index_offset, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vulkan::draw_instance_controllers(types::instance_controller const * const instance_controllers,
|
||||||
|
int const instance_controllers_count,
|
||||||
|
instance_types::node const * const node_instances)
|
||||||
|
{
|
||||||
|
static Joint joints[maxJointsCount];
|
||||||
|
|
||||||
|
for (int i = 0; i < instance_controllers_count; i++) {
|
||||||
|
types::instance_controller const &instance_controller = instance_controllers[i];
|
||||||
|
types::skin const &skin = instance_controller.controller->skin;
|
||||||
|
|
||||||
|
XMMATRIX bsm = XMLoadFloat4x4((XMFLOAT4X4*)&skin.bind_shape_matrix);
|
||||||
|
|
||||||
|
assert((uint32_t)instance_controller.joint_count <= maxJointsCount);
|
||||||
|
for (int joint_index = 0; joint_index < instance_controller.joint_count; joint_index++) {
|
||||||
|
XMMATRIX ibm = XMLoadFloat4x4((XMFLOAT4X4*)&skin.inverse_bind_matrices[joint_index]);
|
||||||
|
int node_index = instance_controller.joint_node_indices[joint_index];
|
||||||
|
instance_types::node const & node_instance = node_instances[node_index];
|
||||||
|
|
||||||
|
XMStoreFloat4x4(&joints[joint_index].transform,
|
||||||
|
XMMatrixTranspose(bsm) * XMMatrixTranspose(ibm) * node_instance.world);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy
|
||||||
|
memcpy(shaderDataDevice.frame[frameIndex].jointsMapped, &joints[0], (sizeof (Joint)) * instance_controller.joint_count);
|
||||||
|
|
||||||
|
// flush
|
||||||
|
|
||||||
|
VkMappedMemoryRange mappedMemoryRanges[1]{
|
||||||
|
{
|
||||||
|
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||||
|
.memory = shaderDataDevice.memory,
|
||||||
|
.offset = shaderDataDevice.frame[frameIndex].jointsOffset,
|
||||||
|
.size = shaderDataDevice.frame[frameIndex].jointsSize,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
alignMappedMemoryRanges(physicalDeviceProperties.limits.nonCoherentAtomSize,
|
||||||
|
shaderDataDevice.memorySize,
|
||||||
|
1,
|
||||||
|
mappedMemoryRanges);
|
||||||
|
vkFlushMappedMemoryRanges(device, 1, mappedMemoryRanges);
|
||||||
|
|
||||||
|
/*
|
||||||
|
int joints_size = (sizeof (XMFLOAT4X4)) * instance_controller.joint_count;
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, joint_uniform_buffer);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, joints_size, (void *)&joints[0], GL_DYNAMIC_DRAW);
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||||
|
glBindBufferRange(GL_UNIFORM_BUFFER, layout.binding.joint, joint_uniform_buffer, 0, joints_size);
|
||||||
|
*/
|
||||||
|
|
||||||
|
draw_skin(skin,
|
||||||
|
instance_controller.instance_materials,
|
||||||
|
instance_controller.instance_materials_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void vulkan::transfer_transforms(XMMATRIX const & projection,
|
void vulkan::transfer_transforms(XMMATRIX const & projection,
|
||||||
XMMATRIX const & view,
|
XMMATRIX const & view,
|
||||||
XMMATRIX const & shadowProjection,
|
XMMATRIX const & shadowProjection,
|
||||||
@ -970,13 +1134,15 @@ namespace collada::scene {
|
|||||||
|
|
||||||
void vulkan::draw_node(int32_t node_index,
|
void vulkan::draw_node(int32_t node_index,
|
||||||
types::node const & node,
|
types::node const & node,
|
||||||
instance_types::node const & node_instance)
|
instance_types::node const & node_instance,
|
||||||
|
instance_types::node const * const node_instances)
|
||||||
{
|
{
|
||||||
VkShaderStageFlags stageFlags{ VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT };
|
VkShaderStageFlags stageFlags{ VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_GEOMETRY_BIT };
|
||||||
constexpr uint32_t offset{ (offsetof (PushConstant, nodeIndex)) };
|
constexpr uint32_t offset{ (offsetof (PushConstant, nodeIndex)) };
|
||||||
vkCmdPushConstants(commandBuffer, pipelineLayout, stageFlags, offset, (sizeof (uint32_t)), &node_index);
|
vkCmdPushConstants(commandBuffer, pipelineLayout, stageFlags, offset, (sizeof (uint32_t)), &node_index);
|
||||||
|
|
||||||
draw_instance_geometries(node.instance_geometries, node.instance_geometries_count);
|
draw_instance_geometries(node.instance_geometries, node.instance_geometries_count);
|
||||||
|
draw_instance_controllers(node.instance_controllers, node.instance_controllers_count, node_instances);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vulkan::change_frame(VkCommandBuffer commandBuffer, uint32_t frameIndex)
|
void vulkan::change_frame(VkCommandBuffer commandBuffer, uint32_t frameIndex)
|
||||||
@ -1012,6 +1178,7 @@ namespace collada::scene {
|
|||||||
for (uint32_t i = 0; i < maxFrames; i++) {
|
for (uint32_t i = 0; i < maxFrames; i++) {
|
||||||
vkDestroyBuffer(device, shaderDataDevice.frame[i].sceneBuffer, nullptr);
|
vkDestroyBuffer(device, shaderDataDevice.frame[i].sceneBuffer, nullptr);
|
||||||
vkDestroyBuffer(device, shaderDataDevice.frame[i].nodesBuffer, nullptr);
|
vkDestroyBuffer(device, shaderDataDevice.frame[i].nodesBuffer, nullptr);
|
||||||
|
vkDestroyBuffer(device, shaderDataDevice.frame[i].jointsBuffer, nullptr);
|
||||||
}
|
}
|
||||||
vkDestroyBuffer(device, shaderDataDevice.constant.materialColorImagesBuffer, nullptr);
|
vkDestroyBuffer(device, shaderDataDevice.constant.materialColorImagesBuffer, nullptr);
|
||||||
vkFreeMemory(device, shaderDataDevice.memory, nullptr);
|
vkFreeMemory(device, shaderDataDevice.memory, nullptr);
|
||||||
|
|||||||
67
src/main.cpp
67
src/main.cpp
@ -19,6 +19,7 @@
|
|||||||
#include "collada/scene/vulkan.h"
|
#include "collada/scene/vulkan.h"
|
||||||
|
|
||||||
#include "scenes/shadow_test/shadow_test.h"
|
#include "scenes/shadow_test/shadow_test.h"
|
||||||
|
#include "scenes/eidelwind/eidelwind.h"
|
||||||
|
|
||||||
VkInstance instance{ VK_NULL_HANDLE };
|
VkInstance instance{ VK_NULL_HANDLE };
|
||||||
VkDevice device{ VK_NULL_HANDLE };
|
VkDevice device{ VK_NULL_HANDLE };
|
||||||
@ -591,7 +592,7 @@ int main()
|
|||||||
textureSamplers[0],
|
textureSamplers[0],
|
||||||
shadowDepthImageViewDepth);
|
shadowDepthImageViewDepth);
|
||||||
|
|
||||||
collada::types::descriptor const * collada_scene_descriptor = &shadow_test::descriptor;
|
collada::types::descriptor const * collada_scene_descriptor = &eidelwind::descriptor;
|
||||||
collada_state.load_scene(collada_scene_descriptor);
|
collada_state.load_scene(collada_scene_descriptor);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
@ -608,9 +609,10 @@ int main()
|
|||||||
|
|
||||||
int cameraIndex = collada_state.find_node_index_by_name("Camera001");
|
int cameraIndex = collada_state.find_node_index_by_name("Camera001");
|
||||||
int cameraTargetIndex = collada_state.find_node_index_by_name("Camera001.Target");
|
int cameraTargetIndex = collada_state.find_node_index_by_name("Camera001.Target");
|
||||||
int lightIndex = collada_state.find_node_index_by_name("DirectLight");
|
int lightIndex = collada_state.find_node_index_by_name("Camera001");
|
||||||
int lightTargetIndex = collada_state.find_node_index_by_name("DirectLight.Target");
|
int lightTargetIndex = collada_state.find_node_index_by_name("Torso");
|
||||||
int lightMaterialIndex = collada_state.find_material_index_by_name("LightMaterial");
|
//int lightMaterialIndex = collada_state.find_material_index_by_name("LightMaterial");
|
||||||
|
int lightMaterialIndex = -1;
|
||||||
|
|
||||||
while (quit == false) {
|
while (quit == false) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
@ -647,7 +649,7 @@ int main()
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
double time = getTime(start_time);
|
double time = getTime(start_time);
|
||||||
collada_state.update(time / 8.0f);
|
collada_state.update(time / 1.5f);
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// fence
|
// fence
|
||||||
@ -669,12 +671,37 @@ int main()
|
|||||||
};
|
};
|
||||||
VK_CHECK(vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo));
|
VK_CHECK(vkBeginCommandBuffer(commandBuffer, &commandBufferBeginInfo));
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
// transfer
|
||||||
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
{
|
||||||
|
collada_state.vulkan.change_frame(commandBuffer, frameIndex);
|
||||||
|
|
||||||
|
XMMATRIX projection = currentProjection();
|
||||||
|
XMMATRIX view = currentView(collada_state.node_state.node_instances[cameraIndex],
|
||||||
|
collada_state.node_state.node_instances[cameraTargetIndex]);
|
||||||
|
XMMATRIX shadowProjection = XMMatrixOrthographicLH(300, 300, 0.1, 500);
|
||||||
|
XMMATRIX shadowView = currentView(collada_state.node_state.node_instances[lightIndex],
|
||||||
|
collada_state.node_state.node_instances[lightTargetIndex]);
|
||||||
|
|
||||||
|
collada::instance_types::node const & lightNode = collada_state.node_state.node_instances[lightIndex];
|
||||||
|
XMVECTOR lightPositionWorld = XMVector3Transform(XMVectorZero(), lightNode.world);
|
||||||
|
|
||||||
|
collada_state.vulkan.transfer_transforms(projection,
|
||||||
|
view,
|
||||||
|
shadowProjection,
|
||||||
|
shadowView,
|
||||||
|
lightPositionWorld,
|
||||||
|
collada_state.descriptor->nodes_count,
|
||||||
|
collada_state.node_state.node_instances);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// shadow render
|
// shadow render
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// barrier
|
// barrier
|
||||||
|
|
||||||
VkImageMemoryBarrier2 shadowBarriers[1]{
|
VkImageMemoryBarrier2 shadowBarriers[1]{
|
||||||
VkImageMemoryBarrier2{
|
VkImageMemoryBarrier2{
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||||
@ -739,30 +766,6 @@ int main()
|
|||||||
};
|
};
|
||||||
vkCmdSetScissor(commandBuffer, 0, 1, &shadowScissor);
|
vkCmdSetScissor(commandBuffer, 0, 1, &shadowScissor);
|
||||||
|
|
||||||
// transfer
|
|
||||||
|
|
||||||
{
|
|
||||||
collada_state.vulkan.change_frame(commandBuffer, frameIndex);
|
|
||||||
|
|
||||||
XMMATRIX projection = currentProjection();
|
|
||||||
XMMATRIX view = currentView(collada_state.node_state.node_instances[cameraIndex],
|
|
||||||
collada_state.node_state.node_instances[cameraTargetIndex]);
|
|
||||||
XMMATRIX shadowProjection = XMMatrixOrthographicLH(300, 300, 0.1, 500);
|
|
||||||
XMMATRIX shadowView = currentView(collada_state.node_state.node_instances[lightIndex],
|
|
||||||
collada_state.node_state.node_instances[lightTargetIndex]);
|
|
||||||
|
|
||||||
collada::instance_types::node const & lightNode = collada_state.node_state.node_instances[lightIndex];
|
|
||||||
XMVECTOR lightPositionWorld = XMVector3Transform(XMVectorZero(), lightNode.world);
|
|
||||||
|
|
||||||
collada_state.vulkan.transfer_transforms(projection,
|
|
||||||
view,
|
|
||||||
shadowProjection,
|
|
||||||
shadowView,
|
|
||||||
lightPositionWorld,
|
|
||||||
collada_state.descriptor->nodes_count,
|
|
||||||
collada_state.node_state.node_instances);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
|
|
||||||
collada_state.vulkan.excludeMaterialIndex = lightMaterialIndex;
|
collada_state.vulkan.excludeMaterialIndex = lightMaterialIndex;
|
||||||
@ -889,8 +892,8 @@ int main()
|
|||||||
collada_state.vulkan.excludeMaterialIndex = -1;
|
collada_state.vulkan.excludeMaterialIndex = -1;
|
||||||
collada_state.vulkan.pipelineIndex = 1; // non-shadow pipeline
|
collada_state.vulkan.pipelineIndex = 1; // non-shadow pipeline
|
||||||
collada_state.draw();
|
collada_state.draw();
|
||||||
collada_state.vulkan.pipelineIndex = 2; // geometry shader pipeline
|
//collada_state.vulkan.pipelineIndex = 2; // geometry shader pipeline
|
||||||
collada_state.draw();
|
//collada_state.draw();
|
||||||
|
|
||||||
vkCmdEndRendering(commandBuffer);
|
vkCmdEndRendering(commandBuffer);
|
||||||
|
|
||||||
|
|||||||
1
texconv.sh
Normal file
1
texconv.sh
Normal file
@ -0,0 +1 @@
|
|||||||
|
WINEDEBUG=-all wine $HOME/Texconv.exe -nogpu -nowic -dx10 --format BC7_UNORM_SRGB $1
|
||||||
Loading…
x
Reference in New Issue
Block a user