From fe9a3341f2426ab0a9deffc1be2df4554cecf774 Mon Sep 17 00:00:00 2001 From: RandyGaul Date: Fri, 27 Sep 2024 16:28:35 -0700 Subject: [PATCH] draw_canvas implementation refactor --- include/cute_draw.h | 5 +- include/cute_graphics.h | 21 --- samples/scratch.cpp | 10 +- src/cute_app.cpp | 6 +- src/cute_draw.cpp | 191 ++++++++++++-------------- src/cute_graphics.cpp | 111 +-------------- src/internal/cute_app_internal.h | 3 - src/internal/cute_draw_internal.h | 3 +- src/internal/cute_graphics_internal.h | 1 + 9 files changed, 107 insertions(+), 244 deletions(-) diff --git a/include/cute_draw.h b/include/cute_draw.h index 4418af41..08ce2cee 100644 --- a/include/cute_draw.h +++ b/include/cute_draw.h @@ -1298,11 +1298,10 @@ CF_API void CF_CALL cf_draw_set_uniform_color(const char* name, CF_Color val); * @function cf_draw_mul * @category draw * @brief Applies the current draw transform to a point. - * @param m The transform to apply. * @param p The point to transform. * @related TODO */ -CF_API CF_V2 CF_CALL cf_draw_mul(CF_M3x2 m, CF_V2 p); +CF_API CF_V2 CF_CALL cf_draw_mul(CF_V2 p); /** * @function cf_draw_transform @@ -1751,7 +1750,7 @@ CF_INLINE void draw_set_uniform(const char* name, float val) { cf_draw_set_unifo CF_INLINE void draw_set_uniform(const char* name, v2 val) { cf_draw_set_uniform_v2(name, val); } CF_INLINE void draw_set_uniform(const char* name, Color val) { cf_draw_set_uniform_color(name, val); } -CF_INLINE v2 draw_mul(M3x2 m, v2 v) { return cf_draw_mul(m, v); } +CF_INLINE v2 draw_mul(v2 v) { return cf_draw_mul(v); } CF_INLINE void draw_transform(M3x2 m) { cf_draw_transform(m); } CF_INLINE void draw_scale(float w, float h) { cf_draw_scale(w, h); } CF_INLINE void draw_scale(v2 scale) { cf_draw_scale_v2(scale); } diff --git a/include/cute_graphics.h b/include/cute_graphics.h index 185cd513..029ab402 100644 --- a/include/cute_graphics.h +++ b/include/cute_graphics.h @@ -776,26 +776,6 @@ CF_API CF_Texture CF_CALL cf_canvas_get_target(CF_Canvas canvas); */ CF_API CF_Texture CF_CALL cf_canvas_get_depth_stencil_target(CF_Canvas canvas); -/** - * @function cf_canvas_blit - * @category graphics - * @brief Blits one canvas onto another. - * @param src The source texture to copy pixels from. - * @param u0 The normalized coordinate of the top-left of the source rect. - * @param v0 The normalized coordinate of the bottom-right of the source rect. - * @param src The canvas where pixels are copied from. - * @param u1 The normalized coordinate of the top-left of the destination rect. - * @param v1 The normalized coordinate of the bottom-right of the destination rect. - * @param dst The destination canvas where pixels are copied to. - * @param clear_dst Whether or not the `dst` canvas should be cleared. This matters for alpha compositing. - * @remarks The texture formats of the underlying canvas's must be `PIXEL_FORMAT_R8G8B8A8_UNORM`. Each u/v coordinate - * is normalized, meaning a number from 0 to 1. This lets the function operate on canvas's of any - * size. To convert a coordinate to a normalized coordinate, simply divide the x/y of your coordinate - * by the width/height of the canvas. - * @related CF_Canvas - */ -CF_API void CF_CALL cf_canvas_blit(CF_Canvas src, CF_V2 u0, CF_V2 v0, CF_Canvas dst, CF_V2 u1, CF_V2 v1, bool clear_dst); - //-------------------------------------------------------------------------------------------------- // Mesh. @@ -1897,7 +1877,6 @@ CF_INLINE Canvas make_canvas(CanvasParams pass_params) { return cf_make_canvas(p CF_INLINE void destroy_canvas(Canvas canvas) { cf_destroy_canvas(canvas); } CF_INLINE Texture canvas_get_target(Canvas canvas) { return cf_canvas_get_target(canvas); } CF_INLINE Texture canvas_get_depth_stencil_target(Canvas canvas) { return cf_canvas_get_depth_stencil_target(canvas); } -CF_INLINE void canvas_blit(Canvas src, v2 u0, v2 v0, Canvas dst, v2 u1, v2 v1, bool clear_dst = false) { cf_canvas_blit(src, u0, v0, dst, u1, v1, clear_dst); } CF_INLINE Mesh make_mesh(int vertex_buffer_size_in_bytes, const VertexAttribute* attributes, int attribute_count, int vertex_stride) { return cf_make_mesh(vertex_buffer_size_in_bytes, attributes, attribute_count, vertex_stride); } CF_INLINE void destroy_mesh(Mesh mesh) { cf_destroy_mesh(mesh); } CF_INLINE void mesh_update_vertex_data(Mesh mesh, void* data, int count) { cf_mesh_update_vertex_data(mesh, data, count); } diff --git a/samples/scratch.cpp b/samples/scratch.cpp index 04182bbf..7f6916e0 100644 --- a/samples/scratch.cpp +++ b/samples/scratch.cpp @@ -24,8 +24,10 @@ int main(int argc, char* argv[]) while (app_is_running()) { app_update(); - draw_circle(V2(-200,0), 30, 5); - draw_circle(V2( 200,0), 30, 5); + draw_circle(V2(-200,100), 30, 5); + draw_push_color(color_red()); + draw_circle(V2( 200,100), 30, 5); + draw_pop_color(); render_to(plain, true); draw_push_shader(shadow_shd); @@ -34,7 +36,11 @@ int main(int argc, char* argv[]) render_to(shadows, true); draw_canvas(shadows, 5, -5, w, h); + draw_push(); + //draw_scale(-1,-1); + //draw_translate(0,0); draw_canvas(plain, 0, 0, w, h); + //draw_pop(); render_to(app_get_canvas(), true); app_draw_onto_screen(); diff --git a/src/cute_app.cpp b/src/cute_app.cpp index 12d0b115..1dbef83e 100644 --- a/src/cute_app.cpp +++ b/src/cute_app.cpp @@ -392,11 +392,7 @@ void cf_destroy_app() cf_destroy_canvas(app->offscreen_canvas); cf_destroy_mesh(app->backbuffer_quad); cf_destroy_material(app->backbuffer_material); - if (app->blit_init) { - cf_destroy_mesh(app->blit_mesh); - cf_destroy_shader(app->blit_shader); - cf_destroy_material(app->blit_material); - } + cf_destroy_shader(app->blit_shader); cf_destroy_draw(); } cf_destroy_aseprite_cache(); diff --git a/src/cute_draw.cpp b/src/cute_draw.cpp index 608e486a..7fdcac0d 100644 --- a/src/cute_draw.cpp +++ b/src/cute_draw.cpp @@ -2601,19 +2601,36 @@ void cf_draw_canvas(CF_Canvas canvas, CF_V2 position, CF_V2 scale) CF_Command& cmd = draw->add_cmd(); cmd.is_canvas = true; cmd.canvas = canvas; - cmd.canvas_pos = position; - cmd.canvas_scale = scale; + Aabb bb = make_aabb(position, fabsf(scale.x), fabsf(scale.y)); + aabb_verts(cmd.canvas_verts, bb); + bool flip_x = scale.x < 0; + bool flip_y = scale.y < 0; + auto swap = [](v2& a, v2& b) { + v2 t = a; + a = b; + b = t; + }; + if (flip_x) { + swap(cmd.canvas_verts[0], cmd.canvas_verts[1]); + swap(cmd.canvas_verts[2], cmd.canvas_verts[3]); + } + if (flip_y) { + swap(cmd.canvas_verts[0], cmd.canvas_verts[3]); + swap(cmd.canvas_verts[1], cmd.canvas_verts[2]); + } + for (int i = 0; i < 4; ++i) { + cmd.canvas_verts_posH[i] = mul(draw->mvp, cmd.canvas_verts[i]); + } cmd.canvas_attributes = draw->user_params.last(); } -// Modified version of `cf_canvas_blit` to inject user-shader code. -void static s_blit(CF_Command* cmd, CF_Canvas src, Aabb canvas_bb, CF_V2 u0, CF_V2 v0, CF_Canvas dst, CF_V2 u1, CF_V2 v1, bool clear_dst) +void static s_blit(CF_Command* cmd, CF_Canvas src, CF_Canvas dst, bool clear_dst) { typedef struct Vertex { - float wx, wy; // World space x/y. - float x, y; // posH. - float u, v; // Source UV. + v2 pos; // World space x/y. + v2 posH; // posH, homogenous (multiplied by mvp). + v2 uv; // UV to read from src. CF_Color params; } Vertex; @@ -2624,13 +2641,13 @@ void static s_blit(CF_Command* cmd, CF_Canvas src, Aabb canvas_bb, CF_V2 u0, CF_ CF_VertexAttribute attrs[4] = { 0 }; attrs[0].name = "in_pos"; attrs[0].format = CF_VERTEX_FORMAT_FLOAT2; - attrs[0].offset = CF_OFFSET_OF(Vertex, wx); + attrs[0].offset = CF_OFFSET_OF(Vertex, pos); attrs[1].name = "in_posH"; attrs[1].format = CF_VERTEX_FORMAT_FLOAT2; - attrs[1].offset = CF_OFFSET_OF(Vertex, x); + attrs[1].offset = CF_OFFSET_OF(Vertex, posH); attrs[2].name = "in_uv"; attrs[2].format = CF_VERTEX_FORMAT_FLOAT2; - attrs[2].offset = CF_OFFSET_OF(Vertex, u); + attrs[2].offset = CF_OFFSET_OF(Vertex, uv); attrs[3].name = "in_params"; attrs[3].format = CF_VERTEX_FORMAT_FLOAT4; attrs[3].offset = CF_OFFSET_OF(Vertex, params); @@ -2638,85 +2655,77 @@ void static s_blit(CF_Command* cmd, CF_Canvas src, Aabb canvas_bb, CF_V2 u0, CF_ draw->blit_mesh = blit_mesh; } - // UV (0,0) is top-left of the screen, while UV (1,1) is bottom right. - // Coordinate (-1,1) is top left, while (1,-1) is bottom right. - auto fill_quad = [=](float x, float y, float sx, float sy, v2 u, v2 v, CF_Aabb canvas_bb, Vertex verts[6]) - { - // Build a quad from (-1.0f,-1.0f) to (1.0f,1.0f). - verts[0].x = -1.0f; verts[0].y = 1.0f; verts[0].u = u.x; verts[0].v = u.y; - verts[1].x = 1.0f; verts[1].y = -1.0f; verts[1].u = v.x; verts[1].v = v.y; - verts[2].x = 1.0f; verts[2].y = 1.0f; verts[2].u = v.x; verts[2].v = u.y; - - verts[3].x = -1.0f; verts[3].y = 1.0f; verts[3].u = u.x; verts[3].v = u.y; - verts[4].x = -1.0f; verts[4].y = -1.0f; verts[4].u = u.x; verts[4].v = v.y; - verts[5].x = 1.0f; verts[5].y = -1.0f; verts[5].u = v.x; verts[5].v = v.y; - - // Assign world space coordinates (wx, wy) from `canvas_bb`. - // ...These get passed into the user shader as the world space `pos` parameter. - verts[0].wx = canvas_bb.min.x; verts[0].wy = canvas_bb.max.y; - verts[1].wx = canvas_bb.max.x; verts[1].wy = canvas_bb.min.y; - verts[2].wx = canvas_bb.max.x; verts[2].wy = canvas_bb.max.y; - - verts[3].wx = canvas_bb.min.x; verts[3].wy = canvas_bb.max.y; - verts[4].wx = canvas_bb.min.x; verts[4].wy = canvas_bb.min.y; - verts[5].wx = canvas_bb.max.x; verts[5].wy = canvas_bb.min.y; - - // Scale the quad about the origin by (sx,sy), then translate it by (x,y). - for (int i = 0; i < 6; ++i) { - verts[i].x = verts[i].x * sx + x; - verts[i].y = verts[i].y * sy + y; - verts[i].params = cmd->canvas_attributes; - } - }; - CF_Shader* blit = (CF_Shader*)draw->draw_shd_to_blit_shd.try_get(cmd->shader.id); + if (!blit) { + CF_ASSERT(app->blit_shader.id); + blit = (CF_Shader*)&app->blit_shader; + } - if (blit) { - // Custom shader supplied by the user. + // Custom shader supplied by the user. - cf_apply_canvas(dst, clear_dst); + cf_apply_canvas(dst, clear_dst); - // Create a quad where positions come from dst, and UV's come from src. - float w = v1.x - u1.x; - float h = v1.y - u1.y; - float x = (u1.x + v1.x) - 1.0f; - float y = (u1.y + v1.y) - 1.0f; - Vertex verts[6]; - fill_quad(x, -y, w, h, u0, v0, canvas_bb, verts); - cf_mesh_update_vertex_data(draw->blit_mesh, verts, 6); - cf_apply_mesh(draw->blit_mesh); + // Matches index convention from `bb_verts` function. + v2 verts_world[6] = { + cmd->canvas_verts[0], + cmd->canvas_verts[1], + cmd->canvas_verts[3], + cmd->canvas_verts[1], + cmd->canvas_verts[2], + cmd->canvas_verts[3], + }; + v2 verts_posH[6] = { + cmd->canvas_verts_posH[0], + cmd->canvas_verts_posH[1], + cmd->canvas_verts_posH[3], + cmd->canvas_verts_posH[1], + cmd->canvas_verts_posH[2], + cmd->canvas_verts_posH[3], + }; + Vertex verts[6]; + for (int i = 0; i < 6; ++i) { + verts[i].pos = verts_world[i]; + verts[i].posH = verts_posH[i]; + } + verts[0].uv = V2(0,1); + verts[1].uv = V2(1,1); + verts[2].uv = V2(0,0); + verts[3].uv = V2(1,1); + verts[4].uv = V2(1,0); + verts[5].uv = V2(0,0); - // Read pixels from src. - cf_material_set_texture_fs(draw->material, "u_image", cf_canvas_get_target(src)); + cf_mesh_update_vertex_data(draw->blit_mesh, verts, 6); + cf_apply_mesh(draw->blit_mesh); - // Apply uniforms. - cf_material_set_uniform_fs(draw->material, "u_texture_size", &cmd->canvas_scale, CF_UNIFORM_TYPE_FLOAT2, 1); - cf_material_set_uniform_fs(draw->material, "u_alpha_discard", &cmd->alpha_discard, CF_UNIFORM_TYPE_FLOAT, 1); - - // Apply render state. - cf_material_set_render_state(draw->material, cmd->render_state); + // Read pixels from src. + cf_material_set_texture_fs(draw->material, "u_image", cf_canvas_get_target(src)); - // Apply shader. - cf_apply_shader(*blit, draw->material); + // Apply uniforms. + CF_CanvasInternal* canvas_internal = (CF_CanvasInternal*)cmd->canvas.id; + v2 canvas_dims = V2((float)canvas_internal->w, (float)canvas_internal->h); + cf_material_set_uniform_fs(draw->material, "u_texture_size", &canvas_dims, CF_UNIFORM_TYPE_FLOAT2, 1); + cf_material_set_uniform_fs(draw->material, "u_alpha_discard", &cmd->alpha_discard, CF_UNIFORM_TYPE_FLOAT, 1); + + // Apply render state. + cf_material_set_render_state(draw->material, cmd->render_state); - // Apply viewport. - Rect viewport = cmd->viewport; - if (viewport.w >= 0 && viewport.h >= 0) { - cf_apply_viewport(viewport.x, viewport.y, viewport.w, viewport.h); - } + // Apply shader. + cf_apply_shader(*blit, draw->material); - // Apply scissor. - Rect scissor = cmd->scissor; - if (scissor.w >= 0 && scissor.h >= 0) { - cf_apply_scissor(scissor.x, scissor.y, scissor.w, scissor.h); - } + // Apply viewport. + Rect viewport = cmd->viewport; + if (viewport.w >= 0 && viewport.h >= 0) { + cf_apply_viewport(viewport.x, viewport.y, viewport.w, viewport.h); + } - // Blit onto dst. - cf_draw_elements(); - } else { - // No custom shader supplied, use the default one. - cf_canvas_blit(src, u0, v0, dst, u1, v1, clear_dst); + // Apply scissor. + Rect scissor = cmd->scissor; + if (scissor.w >= 0 && scissor.h >= 0) { + cf_apply_scissor(scissor.x, scissor.y, scissor.w, scissor.h); } + + // Blit onto dst. + cf_draw_elements(); } void cf_render_to(CF_Canvas canvas, bool clear) @@ -2753,28 +2762,8 @@ void cf_render_to(CF_Canvas canvas, bool clear) // Blit canvas. // ...Incurs an entire extra draw call by itself. if (cmd->is_canvas) { - Aabb canvas_bb_world = make_aabb(cmd->canvas_pos, cmd->canvas_scale.x, cmd->canvas_scale.y); - - // Move the canvas_bb to screen space. - v2 a = world_to_screen(canvas_bb_world.min); - v2 b = world_to_screen(canvas_bb_world.max); - Aabb canvas_bb = make_aabb(min(a, b), max(a, b)); - Aabb screen_bb = make_aabb(V2(0,0), V2((float)app->w, (float)app->h)); - if (aabb_to_aabb(canvas_bb, screen_bb)) { - v2 lo = max(canvas_bb.min, screen_bb.min); - v2 hi = min(canvas_bb.max, screen_bb.max); - float src_w = canvas_bb.max.x - canvas_bb.min.x; - float src_h = (canvas_bb.max.y - canvas_bb.min.y); - float dst_w = (screen_bb.max.x - screen_bb.min.x); - float dst_h = (screen_bb.max.y - screen_bb.min.y); - if (src_w == 0 || src_h == 0 || dst_w == 0 || dst_h == 0) continue; - v2 src_lo = V2((lo.x-canvas_bb.min.x)/src_w, (lo.y-canvas_bb.min.y)/src_h); - v2 src_hi = V2((hi.x-canvas_bb.min.x)/src_w, (hi.y-canvas_bb.min.y)/src_h); - v2 dst_lo = V2((lo.x-screen_bb.min.x)/dst_w, (lo.y-screen_bb.min.y)/dst_h); - v2 dst_hi = V2((hi.x-screen_bb.min.x)/dst_w, (hi.y-screen_bb.min.y)/dst_h); - s_blit(cmd, cmd->canvas, canvas_bb_world, src_lo, src_hi, canvas, dst_lo, dst_hi, clear); - clear = false; // Only clear `canvas` once. - } + s_blit(cmd, cmd->canvas, canvas, clear); + clear = false; // Only clear `canvas` once. draw->has_drawn_something = true; continue; } @@ -2826,7 +2815,7 @@ void cf_render_to(CF_Canvas canvas, bool clear) draw->verts.clear(); } -CF_V2 cf_draw_mul(CF_M3x2 m, CF_V2 v) +CF_V2 cf_draw_mul(CF_V2 v) { return mul(draw->cam_stack.last(), v); } diff --git a/src/cute_graphics.cpp b/src/cute_graphics.cpp index 6ef8ff11..542d0b6d 100644 --- a/src/cute_graphics.cpp +++ b/src/cute_graphics.cpp @@ -1155,6 +1155,7 @@ void cf_load_internal_shaders() app->draw_shader = s_compile(s_draw_vs, s_draw_fs, true, NULL); app->basic_shader = s_compile(s_basic_vs, s_basic_fs, true, NULL); app->backbuffer_shader = s_compile(s_backbuffer_vs, s_backbuffer_fs, true, NULL); + app->blit_shader = s_compile(s_blit_vs, s_blit_fs, true, NULL); } void cf_unload_internal_shaders() @@ -1292,6 +1293,8 @@ CF_Canvas cf_make_canvas(CF_CanvasParams params) { CF_CanvasInternal* canvas = (CF_CanvasInternal*)CF_CALLOC(sizeof(CF_CanvasInternal)); if (params.target.width > 0 && params.target.height > 0) { + canvas->w = params.target.width; + canvas->h = params.target.height; canvas->cf_texture = cf_make_texture(params.target); if (canvas->cf_texture.id) { canvas->texture = ((CF_TextureInternal*)canvas->cf_texture.id)->tex; @@ -1333,114 +1336,6 @@ CF_Texture cf_canvas_get_depth_stencil_target(CF_Canvas canvas_handle) return canvas->cf_depth_stencil; } -void cf_canvas_blit(CF_Canvas src, CF_V2 u0, CF_V2 v0, CF_Canvas dst, CF_V2 u1, CF_V2 v1, bool clear_dst) -{ - typedef struct Vertex - { - float x, y; - float u, v; - } Vertex; - - if (!app->blit_init) { - app->blit_init = true; - - // Create a full-screen quad mesh. - CF_VertexAttribute attrs[2] = { 0 }; - attrs[0].name = "in_pos"; - attrs[0].format = CF_VERTEX_FORMAT_FLOAT2; - attrs[0].offset = CF_OFFSET_OF(Vertex, x); - attrs[1].name = "in_uv"; - attrs[1].format = CF_VERTEX_FORMAT_FLOAT2; - attrs[1].offset = CF_OFFSET_OF(Vertex, u); - CF_Mesh blit_mesh = cf_make_mesh(sizeof(Vertex) * 1024, attrs, 2, sizeof(Vertex)); - app->blit_mesh = blit_mesh; - - // Create material + shader for blitting. - CF_Material blit_material = cf_make_material(); - cf_material_set_texture_fs(blit_material, "u_image", cf_canvas_get_target(src)); - CF_RenderState state = cf_render_state_defaults(); - state.blend.enabled = true; - state.blend.rgb_src_blend_factor = CF_BLENDFACTOR_ONE; - state.blend.rgb_dst_blend_factor = CF_BLENDFACTOR_ONE_MINUS_SRC_ALPHA; - state.blend.rgb_op = CF_BLEND_OP_ADD; - state.blend.alpha_src_blend_factor = CF_BLENDFACTOR_ONE; - state.blend.alpha_dst_blend_factor = CF_BLENDFACTOR_ONE_MINUS_SRC_ALPHA; - state.blend.alpha_op = CF_BLEND_OP_ADD; - cf_material_set_render_state(blit_material, state); - - const char* vs = R"( - layout (location = 0) in vec2 in_pos; - layout (location = 1) in vec2 in_uv; - - layout (location = 0) out vec2 uv; - - void main() { - vec4 posH = vec4(in_pos, 0, 1); - uv = in_uv; - gl_Position = posH; - } - )"; - - const char* fs = R"( - layout (location = 0) in vec2 uv; - - layout (location = 0) out vec4 result; - - layout (set = 2, binding = 0) uniform sampler2D u_image; - - void main() { - vec4 color = texture(u_image, uv); - result = color; - } - )"; - - CF_Shader blit_shader = cf_make_shader_from_source(vs, fs); - - app->blit_material = blit_material; - app->blit_shader = blit_shader; - } - - // UV (0,0) is top-left of the screen, while UV (1,1) is bottom right. - // Coordinate (-1,1) is top left, while (1,-1) is bottom right. - auto fill_quad = [](float x, float y, float sx, float sy, v2 u, v2 v, Vertex verts[6]) - { - // Build a quad from (-1.0f,-1.0f) to (1.0f,1.0f). - verts[0].x = -1.0f; verts[0].y = 1.0f; verts[0].u = u.x; verts[0].v = u.y; - verts[1].x = 1.0f; verts[1].y = -1.0f; verts[1].u = v.x; verts[1].v = v.y; - verts[2].x = 1.0f; verts[2].y = 1.0f; verts[2].u = v.x; verts[2].v = u.y; - - verts[3].x = -1.0f; verts[3].y = 1.0f; verts[3].u = u.x; verts[3].v = u.y; - verts[4].x = -1.0f; verts[4].y = -1.0f; verts[4].u = u.x; verts[4].v = v.y; - verts[5].x = 1.0f; verts[5].y = -1.0f; verts[5].u = v.x; verts[5].v = v.y; - - // Scale the quad about the origin by (sx,sy), then translate it by (x,y). - for (int i = 0; i < 6; ++i) { - verts[i].x = verts[i].x * sx + x; - verts[i].y = verts[i].y * sy + y; - } - }; - - // We're going to blit onto dst. - cf_apply_canvas(dst, clear_dst); - - // Create a quad where positions come from dst, and UV's come from src. - float w = v1.x - u1.x; - float h = v1.y - u1.y; - float x = (u1.x + v1.x) - 1.0f; - float y = (u1.y + v1.y) - 1.0f; - Vertex verts[6]; - fill_quad(x, -y, w, h, u0, v0, verts); - cf_mesh_update_vertex_data(app->blit_mesh, verts, 6); - - // Read pixels from src. - cf_material_set_texture_fs(app->blit_material, "u_image", cf_canvas_get_target(src)); - - // Blit onto dst. - cf_apply_mesh(app->blit_mesh); - cf_apply_shader(app->blit_shader, app->blit_material); - cf_draw_elements(); -} - CF_Mesh cf_make_mesh(int vertex_buffer_size, const CF_VertexAttribute* attributes, int attribute_count, int vertex_stride) { CF_MeshInternal* mesh = (CF_MeshInternal*)CF_CALLOC(sizeof(CF_MeshInternal)); diff --git a/src/internal/cute_app_internal.h b/src/internal/cute_app_internal.h index a45ae1d9..33d6481e 100644 --- a/src/internal/cute_app_internal.h +++ b/src/internal/cute_app_internal.h @@ -116,10 +116,7 @@ struct CF_App void* on_sound_finish_udata = NULL; void* on_music_finish_udata = NULL; CF_Mutex on_sound_finish_mutex = cf_make_mutex(); - bool blit_init = false; - CF_Mesh blit_mesh = { 0 }; CF_Shader blit_shader = { 0 }; - CF_Material blit_material = { 0 }; // Input stuff. Cute::Array ime_composition; diff --git a/src/internal/cute_draw_internal.h b/src/internal/cute_draw_internal.h index f6601bf6..e0923b53 100644 --- a/src/internal/cute_draw_internal.h +++ b/src/internal/cute_draw_internal.h @@ -83,7 +83,8 @@ struct CF_Command CF_DrawUniform u; bool is_canvas = false; CF_Canvas canvas = { 0 }; - CF_V2 canvas_pos, canvas_scale; + CF_V2 canvas_verts[4]; + CF_V2 canvas_verts_posH[4]; CF_Color canvas_attributes = cf_color_clear(); }; diff --git a/src/internal/cute_graphics_internal.h b/src/internal/cute_graphics_internal.h index 905b772b..b1977418 100644 --- a/src/internal/cute_graphics_internal.h +++ b/src/internal/cute_graphics_internal.h @@ -28,6 +28,7 @@ CF_INLINE SDL_GPUTextureCreateInfo SDL_GPUTextureCreateInfoDefaults(int w, int h struct CF_CanvasInternal { + int w, h; CF_Texture cf_texture; CF_Texture cf_depth_stencil; SDL_GPUTexture* texture;