Send view and project matrices in push constant
This commit is contained in:
1 parent
f3aa7435ec
commit
ea82627695
4 files changed
+67
-59
No files matched your search
@@ -540,10 +540,17 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create pipeline layout
|
// Create pipeline layout
|
||||||
|
const VkPushConstantRange push_constant_range = {
|
||||||
|
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
|
||||||
|
.offset = 0,
|
||||||
|
.size = sizeof(vp_t),
|
||||||
|
};
|
||||||
const VkPipelineLayoutCreateInfo pipeline_layout_config = {
|
const VkPipelineLayoutCreateInfo pipeline_layout_config = {
|
||||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||||
.setLayoutCount = 1,
|
.setLayoutCount = 1,
|
||||||
.pSetLayouts = &ctx->desc_set_layout,
|
.pSetLayouts = &ctx->desc_set_layout,
|
||||||
|
.pushConstantRangeCount = 1,
|
||||||
|
.pPushConstantRanges = &push_constant_range,
|
||||||
};
|
};
|
||||||
result = vkCreatePipelineLayout(
|
result = vkCreatePipelineLayout(
|
||||||
ctx->dev, &pipeline_layout_config, nullptr, &ctx->pipeline_layout);
|
ctx->dev, &pipeline_layout_config, nullptr, &ctx->pipeline_layout);
|
||||||
@@ -807,15 +814,16 @@ void gpu_model_load(
|
|||||||
ctx->dev, &desc_sets_alloc_config, out->desc_sets);
|
ctx->dev, &desc_sets_alloc_config, out->desc_sets);
|
||||||
assert(result == VK_SUCCESS);
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
// Create and map MVP buffer
|
// Create and map transform buffer
|
||||||
const size_t mvp_size = ctx->swapchain_img_count * sizeof(mvp_t);
|
const size_t transform_size = ctx->swapchain_img_count * sizeof(mat4_t);
|
||||||
create_buffer(
|
create_buffer(
|
||||||
ctx, mvp_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
ctx, transform_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
||||||
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
||||||
&out->mvp_buf, &out->mvp_mem);
|
&out->transform_buf, &out->transform_mem);
|
||||||
vkMapMemory(
|
vkMapMemory(
|
||||||
ctx->dev, out->mvp_mem, 0, mvp_size, 0, (void **)&out->mvp_ptr);
|
ctx->dev, out->transform_mem, 0, transform_size, 0,
|
||||||
|
(void **)&out->transform_ptr);
|
||||||
|
|
||||||
// Create and map bone matrix buffer
|
// Create and map bone matrix buffer
|
||||||
const size_t bone_size
|
const size_t bone_size
|
||||||
@@ -828,7 +836,7 @@ void gpu_model_load(
|
|||||||
vkMapMemory(
|
vkMapMemory(
|
||||||
ctx->dev, out->bone_mem, 0, bone_size, 0, (void **)&out->bone_ptr);
|
ctx->dev, out->bone_mem, 0, bone_size, 0, (void **)&out->bone_ptr);
|
||||||
|
|
||||||
// Configure descriptor sets to use MVP and bone matrix buffers
|
// Configure descriptor sets to use transform and bone matrix buffers
|
||||||
for (unsigned i = 0; i < ctx->swapchain_img_count; ++i) {
|
for (unsigned i = 0; i < ctx->swapchain_img_count; ++i) {
|
||||||
const VkWriteDescriptorSet desc_writes[] = {
|
const VkWriteDescriptorSet desc_writes[] = {
|
||||||
{
|
{
|
||||||
@@ -839,9 +847,9 @@ void gpu_model_load(
|
|||||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||||
.descriptorCount = 1,
|
.descriptorCount = 1,
|
||||||
.pBufferInfo = &(VkDescriptorBufferInfo) {
|
.pBufferInfo = &(VkDescriptorBufferInfo) {
|
||||||
.buffer = out->mvp_buf,
|
.buffer = out->transform_buf,
|
||||||
.offset = i * sizeof(mvp_t),
|
.offset = i * sizeof(mat4_t),
|
||||||
.range = sizeof(mvp_t),
|
.range = sizeof(mat4_t),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -870,8 +878,8 @@ void gpu_model_cleanup(const gpu_ctx_t *ctx, const gpu_model_t *model)
|
|||||||
vkDestroyBuffer(ctx->dev, model->bone_buf, nullptr);
|
vkDestroyBuffer(ctx->dev, model->bone_buf, nullptr);
|
||||||
vkFreeMemory(ctx->dev, model->bone_mem, nullptr);
|
vkFreeMemory(ctx->dev, model->bone_mem, nullptr);
|
||||||
|
|
||||||
vkDestroyBuffer(ctx->dev, model->mvp_buf, nullptr);
|
vkDestroyBuffer(ctx->dev, model->transform_buf, nullptr);
|
||||||
vkFreeMemory(ctx->dev, model->mvp_mem, nullptr);
|
vkFreeMemory(ctx->dev, model->transform_mem, nullptr);
|
||||||
|
|
||||||
vkDestroyBuffer(ctx->dev, model->index_buf, nullptr);
|
vkDestroyBuffer(ctx->dev, model->index_buf, nullptr);
|
||||||
vkFreeMemory(ctx->dev, model->index_mem, nullptr);
|
vkFreeMemory(ctx->dev, model->index_mem, nullptr);
|
||||||
@@ -879,7 +887,7 @@ void gpu_model_cleanup(const gpu_ctx_t *ctx, const gpu_model_t *model)
|
|||||||
vkFreeMemory(ctx->dev, model->vertex_mem, nullptr);
|
vkFreeMemory(ctx->dev, model->vertex_mem, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpu_render_begin(gpu_ctx_t *ctx)
|
void gpu_render_begin(gpu_ctx_t *ctx, vp_t vp)
|
||||||
{
|
{
|
||||||
VkResult result;
|
VkResult result;
|
||||||
|
|
||||||
@@ -901,7 +909,6 @@ void gpu_render_begin(gpu_ctx_t *ctx)
|
|||||||
result = vkBeginCommandBuffer(ctx->cmd_buf, &cmd_begin);
|
result = vkBeginCommandBuffer(ctx->cmd_buf, &cmd_begin);
|
||||||
assert(result == VK_SUCCESS);
|
assert(result == VK_SUCCESS);
|
||||||
|
|
||||||
// Start render pass
|
|
||||||
VkClearValue clear_values[] = {
|
VkClearValue clear_values[] = {
|
||||||
[0] = { .color = { { 0.0, 0.0, 0.0, 1.0 } } },
|
[0] = { .color = { { 0.0, 0.0, 0.0, 1.0 } } },
|
||||||
[1] = { .depthStencil = { 1.0, 0.0 } },
|
[1] = { .depthStencil = { 1.0, 0.0 } },
|
||||||
@@ -918,15 +925,19 @@ void gpu_render_begin(gpu_ctx_t *ctx)
|
|||||||
ctx->cmd_buf, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
|
ctx->cmd_buf, &render_pass_begin, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
vkCmdBindPipeline(
|
vkCmdBindPipeline(
|
||||||
ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pipeline);
|
ctx->cmd_buf, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pipeline);
|
||||||
|
|
||||||
|
vkCmdPushConstants(
|
||||||
|
ctx->cmd_buf, ctx->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT, 0,
|
||||||
|
sizeof(vp_t), &vp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gpu_render_model(
|
void gpu_render_model(
|
||||||
const gpu_ctx_t *ctx, const gpu_model_t *model, const mvp_t *mvp,
|
const gpu_ctx_t *ctx, const gpu_model_t *model,
|
||||||
const mat4_t *bone_matrices)
|
const mat4_t *bone_matrices, mat4_t transform)
|
||||||
{
|
{
|
||||||
assert(ctx->active_img_index < ctx->swapchain_img_count);
|
assert(ctx->active_img_index < ctx->swapchain_img_count);
|
||||||
|
|
||||||
memcpy(model->mvp_ptr + ctx->active_img_index, mvp, sizeof(mvp_t));
|
model->transform_ptr[ctx->active_img_index] = transform;
|
||||||
memcpy(
|
memcpy(
|
||||||
model->bone_ptr + (model->bone_count * ctx->active_img_index),
|
model->bone_ptr + (model->bone_count * ctx->active_img_index),
|
||||||
bone_matrices, model->bone_count * sizeof(mat4_t));
|
bone_matrices, model->bone_count * sizeof(mat4_t));
|
||||||
|
|||||||
@@ -10,10 +10,9 @@
|
|||||||
#define MAX_FRAMES_IN_FLIGHT 4
|
#define MAX_FRAMES_IN_FLIGHT 4
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mat4_t model;
|
|
||||||
mat4_t view;
|
mat4_t view;
|
||||||
mat4_t proj;
|
mat4_t proj;
|
||||||
} mvp_t;
|
} vp_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
VkInstance inst;
|
VkInstance inst;
|
||||||
@@ -49,15 +48,15 @@ typedef struct {
|
|||||||
} gpu_ctx_t;
|
} gpu_ctx_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mvp_t *mvp_ptr;
|
mat4_t *transform_ptr;
|
||||||
mat4_t *bone_ptr;
|
mat4_t *bone_ptr;
|
||||||
VkBuffer vertex_buf;
|
VkBuffer vertex_buf;
|
||||||
VkDeviceMemory vertex_mem;
|
VkDeviceMemory vertex_mem;
|
||||||
VkBuffer index_buf;
|
VkBuffer index_buf;
|
||||||
VkDeviceMemory index_mem;
|
VkDeviceMemory index_mem;
|
||||||
VkDescriptorSet desc_sets[MAX_FRAMES_IN_FLIGHT];
|
VkDescriptorSet desc_sets[MAX_FRAMES_IN_FLIGHT];
|
||||||
VkBuffer mvp_buf;
|
VkBuffer transform_buf;
|
||||||
VkDeviceMemory mvp_mem;
|
VkDeviceMemory transform_mem;
|
||||||
VkBuffer bone_buf;
|
VkBuffer bone_buf;
|
||||||
VkDeviceMemory bone_mem;
|
VkDeviceMemory bone_mem;
|
||||||
size_t index_count;
|
size_t index_count;
|
||||||
@@ -71,11 +70,10 @@ void gpu_model_load(
|
|||||||
const gpu_ctx_t *ctx, const model_t *model, gpu_model_t *out);
|
const gpu_ctx_t *ctx, const model_t *model, gpu_model_t *out);
|
||||||
void gpu_model_cleanup(const gpu_ctx_t *ctx, const gpu_model_t *model);
|
void gpu_model_cleanup(const gpu_ctx_t *ctx, const gpu_model_t *model);
|
||||||
|
|
||||||
void gpu_render_begin(gpu_ctx_t *ctx);
|
void gpu_render_begin(gpu_ctx_t *ctx, vp_t vp);
|
||||||
void gpu_render_model(
|
void gpu_render_model(
|
||||||
const gpu_ctx_t *ctx, const gpu_model_t *model, const mvp_t *mvp,
|
const gpu_ctx_t *ctx, const gpu_model_t *model,
|
||||||
|
const mat4_t *bone_matrices, mat4_t transform);
|
||||||
const mat4_t *bone_matrices);
|
|
||||||
void gpu_render_submit(gpu_ctx_t *ctx);
|
void gpu_render_submit(gpu_ctx_t *ctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -62,32 +62,28 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
const vec3_t cam = { 0, 4, -4 };
|
const vec3_t cam = { 0, 4, -4 };
|
||||||
const vec3_t tgt = { 0, 0.5, 0 };
|
const vec3_t tgt = { 0, 0.5, 0 };
|
||||||
mvp_t mvp1 = {
|
const vp_t vp = {
|
||||||
.model = mat4_mul(
|
|
||||||
MAT4_TRANSLATE(1, 0, 0),
|
|
||||||
(mat4_t) {
|
|
||||||
{ 0, 0, -1, 0 },
|
|
||||||
{ -1, 0, 0, 0 },
|
|
||||||
{ 0, 1, 0, 0 },
|
|
||||||
{ 0, 0, 0, 1 },
|
|
||||||
}),
|
|
||||||
.view = mat4_lookat(cam, tgt, (vec3_t) { 0, 1, 0 }),
|
|
||||||
.proj = mat4_perspective((float)W / H, PI / 8, 0.1, 10.0),
|
|
||||||
};
|
|
||||||
mvp_t mvp2 = {
|
|
||||||
.model = mat4_mul(
|
|
||||||
MAT4_TRANSLATE(2, 0, 0),
|
|
||||||
mat4_mul(
|
|
||||||
MAT4_ROTATE_Y(PI),
|
|
||||||
(mat4_t) {
|
|
||||||
{ 0, 0, -1, 0 },
|
|
||||||
{ -1, 0, 0, 0 },
|
|
||||||
{ 0, 1, 0, 0 },
|
|
||||||
{ 0, 0, 0, 1 },
|
|
||||||
})),
|
|
||||||
.view = mat4_lookat(cam, tgt, (vec3_t) { 0, 1, 0 }),
|
.view = mat4_lookat(cam, tgt, (vec3_t) { 0, 1, 0 }),
|
||||||
.proj = mat4_perspective((float)W / H, PI / 8, 0.1, 10.0),
|
.proj = mat4_perspective((float)W / H, PI / 8, 0.1, 10.0),
|
||||||
};
|
};
|
||||||
|
mat4_t transform1 = mat4_mul(
|
||||||
|
MAT4_TRANSLATE(1, 0, 0),
|
||||||
|
(mat4_t) {
|
||||||
|
{ 0, 0, -1, 0 },
|
||||||
|
{ -1, 0, 0, 0 },
|
||||||
|
{ 0, 1, 0, 0 },
|
||||||
|
{ 0, 0, 0, 1 },
|
||||||
|
});
|
||||||
|
mat4_t transform2 = mat4_mul(
|
||||||
|
MAT4_TRANSLATE(2, 0, 0),
|
||||||
|
mat4_mul(
|
||||||
|
MAT4_ROTATE_Y(PI),
|
||||||
|
(mat4_t) {
|
||||||
|
{ 0, 0, -1, 0 },
|
||||||
|
{ -1, 0, 0, 0 },
|
||||||
|
{ 0, 1, 0, 0 },
|
||||||
|
{ 0, 0, 0, 1 },
|
||||||
|
}));
|
||||||
|
|
||||||
const mat4_t rot1 = MAT4_ROTATE_Y(PI / 170);
|
const mat4_t rot1 = MAT4_ROTATE_Y(PI / 170);
|
||||||
const mat4_t rot2 = MAT4_ROTATE_Y(-PI / 340);
|
const mat4_t rot2 = MAT4_ROTATE_Y(-PI / 340);
|
||||||
@@ -96,13 +92,13 @@ int main(int argc, char *argv[])
|
|||||||
while (!glfwWindowShouldClose(window)) {
|
while (!glfwWindowShouldClose(window)) {
|
||||||
glfwPollEvents();
|
glfwPollEvents();
|
||||||
|
|
||||||
mvp1.model = mat4_mul(rot1, mvp1.model);
|
transform1 = mat4_mul(rot1, transform1);
|
||||||
mvp2.model = mat4_mul(rot2, mvp2.model);
|
transform2 = mat4_mul(rot2, transform2);
|
||||||
animation_update(&anim, &model, DT);
|
animation_update(&anim, &model, DT);
|
||||||
|
|
||||||
gpu_render_begin(&gpu);
|
gpu_render_begin(&gpu, vp);
|
||||||
gpu_render_model(&gpu, &gpu_model1, &mvp1, anim.bone_matrices);
|
gpu_render_model(&gpu, &gpu_model1, anim.bone_matrices, transform1);
|
||||||
gpu_render_model(&gpu, &gpu_model2, &mvp2, anim.bone_matrices);
|
gpu_render_model(&gpu, &gpu_model2, anim.bone_matrices, transform2);
|
||||||
gpu_render_submit(&gpu);
|
gpu_render_submit(&gpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,14 @@ layout(location = 3) in vec4 weights;
|
|||||||
|
|
||||||
layout(location = 0) out vec3 frag_normal;
|
layout(location = 0) out vec3 frag_normal;
|
||||||
|
|
||||||
layout(binding = 0) uniform mvp_t {
|
layout(push_constant) uniform vp_t {
|
||||||
mat4 model;
|
|
||||||
mat4 view;
|
mat4 view;
|
||||||
mat4 proj;
|
mat4 proj;
|
||||||
} mvp;
|
} vp;
|
||||||
|
|
||||||
|
layout(binding = 0) uniform transform_t {
|
||||||
|
mat4 model;
|
||||||
|
} transform;
|
||||||
|
|
||||||
layout(binding = 1) uniform skeleton_t {
|
layout(binding = 1) uniform skeleton_t {
|
||||||
mat4 matrices[32];
|
mat4 matrices[32];
|
||||||
@@ -23,8 +26,8 @@ void main() {
|
|||||||
+ weights.y * bones.matrices[bone_indices.y]
|
+ weights.y * bones.matrices[bone_indices.y]
|
||||||
+ weights.z * bones.matrices[bone_indices.z]
|
+ weights.z * bones.matrices[bone_indices.z]
|
||||||
+ weights.w * bones.matrices[bone_indices.w];
|
+ weights.w * bones.matrices[bone_indices.w];
|
||||||
gl_Position = mvp.proj * mvp.view * mvp.model * skinning_matrix
|
gl_Position = vp.proj * vp.view * transform.model * skinning_matrix
|
||||||
* vec4(position, 1.0);
|
* vec4(position, 1.0);
|
||||||
frag_normal
|
frag_normal = transpose(
|
||||||
= transpose(inverse(mat3(mvp.model * skinning_matrix))) * normal;
|
inverse(mat3(transform.model * skinning_matrix))) * normal;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user