Added rect draw api
Added some new maths types Updated shaders to use new D_Rect structure Added rect buffers to frames Misc cleanup
This commit is contained in:
132
code/draw/core.c
Normal file
132
code/draw/core.c
Normal file
@@ -0,0 +1,132 @@
|
||||
void D_Begin(D_Context *draw, Vk_Frame *frame, U32 max_rects) {
|
||||
Vk_Buffer *rbo = &frame->rbo;
|
||||
|
||||
draw->rbo = rbo;
|
||||
draw->n_rects = 0;
|
||||
draw->max_rects = max_rects;
|
||||
draw->rects = rbo->data;
|
||||
}
|
||||
|
||||
void D_End(D_Context *draw, Vk_Frame *frame) {
|
||||
VkCommandBuffer cmd = frame->cmd;
|
||||
Vk_Pipeline *basic = &draw->pipelines[0];
|
||||
|
||||
// We can probably stop doing this at some point
|
||||
VkDescriptorSet set;
|
||||
VkDescriptorSetAllocateInfo alloc_info = { 0 };
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
alloc_info.descriptorPool = frame->descriptors;
|
||||
alloc_info.descriptorSetCount = 1;
|
||||
alloc_info.pSetLayouts = &basic->layout.set;
|
||||
|
||||
vk.AllocateDescriptorSets(vk.device, &alloc_info, &set);
|
||||
|
||||
// 'update' the descriptor sets for binding
|
||||
M_TempScope(0, 0) {
|
||||
VkWriteDescriptorSet writes[2] = { 0 };
|
||||
|
||||
VkDescriptorBufferInfo rbo_info = { 0 };
|
||||
rbo_info.buffer = draw->rbo->handle;
|
||||
rbo_info.offset = 0;
|
||||
rbo_info.range = VK_WHOLE_SIZE;
|
||||
|
||||
VkDescriptorImageInfo *image_info = M_ArenaPush(temp.arena, VkDescriptorImageInfo, .count = draw->n_images);
|
||||
|
||||
for (U32 it = 0; it < draw->n_images; ++it) {
|
||||
image_info[it].imageView = draw->images[it].image.view;
|
||||
image_info[it].sampler = vk.sampler;
|
||||
image_info[it].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
}
|
||||
|
||||
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writes[0].dstSet = set;
|
||||
writes[0].dstBinding = 0;
|
||||
writes[0].descriptorCount = 1;
|
||||
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
writes[0].pBufferInfo = &rbo_info;
|
||||
|
||||
writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
writes[1].dstSet = set;
|
||||
writes[1].dstBinding = 1;
|
||||
writes[1].descriptorCount = draw->n_images;
|
||||
writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
writes[1].pImageInfo = image_info;
|
||||
|
||||
vk.UpdateDescriptorSets(vk.device, ArraySize(writes), writes, 0, 0);
|
||||
}
|
||||
|
||||
vk.CmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, basic->handle);
|
||||
vk.CmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, basic->layout.pipeline, 0, 1, &set, 0, 0);
|
||||
vk.CmdPushConstants(cmd, basic->layout.pipeline, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(Mat4x4F), &draw->camera->proj.fwd);
|
||||
|
||||
VkViewport viewport = { 0, 0, (F32) draw->window_width, (F32) draw->window_height, 0.0f, 1.0f };
|
||||
VkRect2D scissor = { 0, 0, draw->window_width, draw->window_height };
|
||||
|
||||
vk.CmdSetViewport(cmd, 0, 1, &viewport);
|
||||
vk.CmdSetScissor(cmd, 0, 1, &scissor);
|
||||
|
||||
vk.CmdDraw(cmd, 6, draw->n_rects, 0, 0);
|
||||
}
|
||||
|
||||
internal U32 V4f_UnormColour(V4f c) {
|
||||
// @Todo: SRGB handling
|
||||
U32 result =
|
||||
((U8) (255.0f * c.a)) << 24 |
|
||||
((U8) (255.0f * c.r)) << 16 |
|
||||
((U8) (255.0f * c.g)) << 8 |
|
||||
((U8) (255.0f * c.b)) << 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void _D_Rect(D_Context *draw, D_RectOpts *opts) {
|
||||
if (draw->n_rects < draw->max_rects) {
|
||||
D_Rect *rect = &draw->rects[draw->n_rects];
|
||||
|
||||
rect->texture = opts->texture;
|
||||
|
||||
rect->x = opts->p.x;
|
||||
rect->y = opts->p.y;
|
||||
|
||||
rect->uv[0] = opts->uv.min.x;
|
||||
rect->uv[1] = opts->uv.min.y;
|
||||
rect->uv[2] = opts->uv.max.x;
|
||||
rect->uv[3] = opts->uv.max.y;
|
||||
|
||||
rect->angle = opts->angle;
|
||||
|
||||
if (opts->flags & D_RECT_PER_VERTEX_COLOUR) {
|
||||
rect->c[0] = V4f_UnormColour(opts->vtxc[0]);
|
||||
rect->c[1] = V4f_UnormColour(opts->vtxc[1]);
|
||||
rect->c[2] = V4f_UnormColour(opts->vtxc[2]);
|
||||
rect->c[3] = V4f_UnormColour(opts->vtxc[3]);
|
||||
}
|
||||
else {
|
||||
U32 unorm = V4f_UnormColour(opts->c);
|
||||
|
||||
rect->c[0] = unorm;
|
||||
rect->c[1] = unorm;
|
||||
rect->c[2] = unorm;
|
||||
rect->c[3] = unorm;
|
||||
}
|
||||
|
||||
if (opts->flags & D_RECT_IGNORE_ASPECT) {
|
||||
rect->w = opts->w;
|
||||
rect->h = opts->h;
|
||||
}
|
||||
else {
|
||||
Vk_Image *image = &draw->images[opts->texture].image;
|
||||
|
||||
if (image->width > image->height) {
|
||||
rect->w = opts->scale * ((F32) image->width / (F32) image->height);
|
||||
rect->h = opts->scale;
|
||||
}
|
||||
else {
|
||||
rect->w = opts->scale;
|
||||
rect->h = opts->scale * ((F32) image->height / (F32) image->width);
|
||||
}
|
||||
}
|
||||
|
||||
draw->n_rects += 1;
|
||||
}
|
||||
}
|
||||
85
code/draw/core.h
Normal file
85
code/draw/core.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#if !defined(LD_DRAW_CORE_H_)
|
||||
#define LD_DRAW_CORE_H_
|
||||
|
||||
#define D_MAX_RECTS 1024
|
||||
|
||||
typedef struct D_Image D_Image;
|
||||
struct D_Image {
|
||||
Str8 name;
|
||||
Vk_Image image;
|
||||
};
|
||||
|
||||
typedef struct D_Rect D_Rect;
|
||||
struct D_Rect {
|
||||
U32 texture;
|
||||
|
||||
U32 c[4]; // per-vertex colours
|
||||
F32 uv[4];
|
||||
|
||||
F32 angle;
|
||||
F32 x, y;
|
||||
F32 w, h;
|
||||
|
||||
U32 p0, p1;
|
||||
};
|
||||
|
||||
StaticAssert(sizeof(D_Rect) == 64);
|
||||
|
||||
struct G_Camera;
|
||||
|
||||
typedef struct D_Context D_Context;
|
||||
struct D_Context {
|
||||
Vk_Buffer *rbo;
|
||||
|
||||
U32 n_pipelines;
|
||||
Vk_Pipeline *pipelines;
|
||||
|
||||
U32 n_images;
|
||||
D_Image *images;
|
||||
|
||||
U32 max_rects;
|
||||
U32 n_rects;
|
||||
D_Rect *rects;
|
||||
|
||||
U32 window_width;
|
||||
U32 window_height;
|
||||
|
||||
struct G_Camera *camera;
|
||||
};
|
||||
|
||||
typedef U32 D_RectFlags;
|
||||
enum D_RectFlags {
|
||||
D_RECT_IGNORE_ASPECT = (1 << 0), // by default only width is used as a "dimension"
|
||||
D_RECT_PER_VERTEX_COLOUR = (1 << 1), // split colours per vertex
|
||||
};
|
||||
|
||||
typedef struct D_RectOpts D_RectOpts;
|
||||
struct D_RectOpts {
|
||||
D_RectFlags flags;
|
||||
|
||||
U32 texture;
|
||||
|
||||
R2f uv;
|
||||
V2f p;
|
||||
|
||||
F32 angle;
|
||||
|
||||
union {
|
||||
F32 w, h;
|
||||
F32 scale, _h;
|
||||
V2f dim;
|
||||
};
|
||||
|
||||
union {
|
||||
V4f c;
|
||||
V4f vtxc[4];
|
||||
};
|
||||
};
|
||||
|
||||
function void D_Begin(D_Context *draw, Vk_Frame *frame, U32 max_rects);
|
||||
function void D_End(D_Context *draw, Vk_Frame *frame);
|
||||
|
||||
function void _D_Rect(D_Context *draw, D_RectOpts *opts);
|
||||
#define D_Rect(draw, x, y, ...) _D_Rect(draw, &(D_RectOpts) { .p = V2F(x, y), .uv = R2F(V2F(0, 0), V2F(1, 1)), .scale = 1, .c = V4F(1, 1, 1, 1), ##__VA_ARGS__ })
|
||||
|
||||
#endif // LD_DRAW_CORE_H_
|
||||
Reference in New Issue
Block a user