diff --git a/docs/topics/low_level_graphics.md b/docs/topics/low_level_graphics.md index 287621b1f..b5859b656 100644 --- a/docs/topics/low_level_graphics.md +++ b/docs/topics/low_level_graphics.md @@ -33,7 +33,7 @@ for each canvas { cf_material_set_uniform_vs(material, ...); cf_material_set_uniform_fs(material, ...); for each shader { - cf_apply_shader(shader, material); + cf_apply_shader(shader, material, mesh); cf_draw_elements(...); } } diff --git a/docs/topics/renderer.md b/docs/topics/renderer.md index 92f59ac48..ab0a80423 100644 --- a/docs/topics/renderer.md +++ b/docs/topics/renderer.md @@ -357,7 +357,7 @@ CF renders through `SDL_Gpu`(https://wiki.libsdl.org/SDL3/CategoryGPU), a well-w * cf_material_set_uniform_vs(material, ...); * cf_material_set_uniform_fs(material, ...); * for each shader { - * cf_apply_shader(shader, material); + * cf_apply_shader(shader, material, mesh); * cf_draw_elements(...); * } * } diff --git a/include/cute_graphics.h b/include/cute_graphics.h index 0b621e53b..466df68b6 100644 --- a/include/cute_graphics.h +++ b/include/cute_graphics.h @@ -43,13 +43,12 @@ extern "C" { * cf_apply_canvas(canvas); * for each mesh { * cf_mesh_update_vertex_data(mesh, ...); - * cf_apply_mesh(mesh); * for each material { * cf_material_set_uniform_vs(material, ...); * cf_material_set_uniform_fs(material, ...); * for each shader { - * cf_apply_shader(shader, material); - * cf_draw_elements(...); + * cf_apply_shader(shader, material, mesh); + * cf_draw_elements(mesh); * } * } * } @@ -1849,16 +1848,6 @@ CF_API void CF_CALL cf_apply_stencil_reference(int reference); */ CF_API void CF_CALL cf_apply_blend_constants(float r, float g, float b, float a); -/** - * @function cf_apply_mesh - * @category graphics - * @brief Uses a specific mesh for rendering. - * @remarks The mesh contains vertex data, defining the geometry to be rendered. The mesh vertices are sent to the GPU as inputs to - * the vertex shader. See `CF_Mesh` for an overview. - * @related CF_Mesh cf_create_mesh cf_apply_shader cf_draw_elements - */ -CF_API void CF_CALL cf_apply_mesh(CF_Mesh mesh); - /** * @function cf_apply_shader * @category graphics @@ -1867,15 +1856,17 @@ CF_API void CF_CALL cf_apply_mesh(CF_Mesh mesh); * vertex shader. A `CF_Material` defines uniform and texture inputs to the shader. * @related CF_Mesh cf_create_mesh cf_apply_shader cf_draw_elements */ -CF_API void CF_CALL cf_apply_shader(CF_Shader shader, CF_Material material); +CF_API void CF_CALL cf_apply_shader(CF_Shader shader, CF_Material material, CF_Mesh mesh); /** * @function cf_draw_elements * @category graphics * @brief Draws all elements within the last applied mesh. + * @remarks The mesh contains vertex data, defining the geometry to be rendered. The mesh vertices are sent to the GPU as inputs to + * the vertex shader. See `CF_Mesh` for an overview. * @related CF_Mesh cf_create_mesh cf_apply_shader cf_apply_canvas */ -CF_API void CF_CALL cf_draw_elements(void); +CF_API void CF_CALL cf_draw_elements(CF_Mesh mesh); #ifdef __cplusplus } @@ -1928,9 +1919,9 @@ CF_INLINE void material_clear_uniforms(CF_Material material) { cf_material_clear CF_INLINE void apply_canvas(CF_Canvas canvas, bool clear = false) { cf_apply_canvas(canvas, clear); } CF_INLINE void apply_viewport(int x, int y, int w, int h) { cf_apply_viewport(x, y, w, h); } CF_INLINE void apply_scissor(int x, int y, int w, int h) { cf_apply_scissor(x, y, w, h); } -CF_INLINE void apply_mesh(CF_Mesh mesh) { cf_apply_mesh(mesh); } +CF_INLINE void apply_shader(CF_Shader shader, CF_Material material, CF_Mesh mesh) { cf_apply_shader(shader, material, mesh); } CF_INLINE void apply_shader(CF_Shader shader, CF_Material material) { cf_apply_shader(shader, material); } -CF_INLINE void draw_elements() { cf_draw_elements(); } +CF_INLINE void draw_elements(CF_Mesh mesh) { cf_draw_elements(mesh); } } void cf_clear_canvas(CF_Canvas canvas_handle); diff --git a/samples/basic_indexed_rendering.c b/samples/basic_indexed_rendering.c index 652888325..10f2e3aaa 100644 --- a/samples/basic_indexed_rendering.c +++ b/samples/basic_indexed_rendering.c @@ -65,9 +65,8 @@ int main(int argc, char* argv[]) while (cf_app_is_running()) { cf_app_update(NULL); cf_apply_canvas(cf_app_get_canvas(), true); - cf_apply_mesh(mesh); - cf_apply_shader(shader, material); - cf_draw_elements(); + cf_apply_shader(shader, material, mesh); + cf_draw_elements(mesh); cf_app_draw_onto_screen(false); } diff --git a/samples/basic_instancing.c b/samples/basic_instancing.c index 69071276f..7127beec5 100644 --- a/samples/basic_instancing.c +++ b/samples/basic_instancing.c @@ -83,9 +83,8 @@ int main(int argc, char* argv[]) while (cf_app_is_running()) { cf_app_update(NULL); cf_apply_canvas(cf_app_get_canvas(), true); - cf_apply_mesh(mesh); - cf_apply_shader(shader, material); - cf_draw_elements(); + cf_apply_shader(shader, material, mesh); + cf_draw_elements(mesh); cf_app_draw_onto_screen(false); } diff --git a/samples/hello_triangle.c b/samples/hello_triangle.c index c091698e8..bd635dee8 100644 --- a/samples/hello_triangle.c +++ b/samples/hello_triangle.c @@ -80,9 +80,8 @@ int main(int argc, char* argv[]) cf_apply_canvas(app_canvas, true); // Draw the triangle. - cf_apply_mesh(mesh); - cf_apply_shader(shader, material); - cf_draw_elements(); + cf_apply_shader(shader, material, mesh); + cf_draw_elements(mesh); cf_app_draw_onto_screen(false); } diff --git a/samples/screen_shatter.cpp b/samples/screen_shatter.cpp index 778ec15c7..e24f8da10 100644 --- a/samples/screen_shatter.cpp +++ b/samples/screen_shatter.cpp @@ -325,10 +325,9 @@ int main(int argc, char *argv[]) cf_material_set_uniform_fs(draw.material, "u_texture_size", &canvas_dims, CF_UNIFORM_TYPE_FLOAT2, 1); cf_mesh_update_vertex_data(draw.mesh, draw.verts, cf_array_count(draw.verts)); - cf_apply_mesh(draw.mesh); - cf_apply_shader(draw.shader, draw.material); - cf_draw_elements(); + cf_apply_shader(draw.shader, draw.material, draw.mesh); + cf_draw_elements(draw.mesh); cf_draw_pop_shader(); } diff --git a/samples/sprite_shatter.cpp b/samples/sprite_shatter.cpp index 5a31ca663..0c41b0917 100644 --- a/samples/sprite_shatter.cpp +++ b/samples/sprite_shatter.cpp @@ -321,10 +321,9 @@ int main(int argc, char *argv[]) cf_material_set_uniform_fs(draw.material, "u_texture_size", &atlas_dims, CF_UNIFORM_TYPE_FLOAT2, 1); cf_mesh_update_vertex_data(draw.mesh, draw.verts, cf_array_count(draw.verts)); - cf_apply_mesh(draw.mesh); - cf_apply_shader(draw.shader, draw.material); - cf_draw_elements(); + cf_apply_shader(draw.shader, draw.material, draw.mesh); + cf_draw_elements(draw.mesh); cf_draw_pop_shader(); } diff --git a/samples/sprite_slice.cpp b/samples/sprite_slice.cpp index ddda57381..cc34b7674 100644 --- a/samples/sprite_slice.cpp +++ b/samples/sprite_slice.cpp @@ -306,10 +306,9 @@ int main(int argc, char *argv[]) cf_material_set_uniform_fs(draw.material, "u_texture_size", &atlas_dims, CF_UNIFORM_TYPE_FLOAT2, 1); cf_mesh_update_vertex_data(draw.mesh, draw.verts, cf_array_count(draw.verts)); - cf_apply_mesh(draw.mesh); - cf_apply_shader(draw.shader, draw.material); - cf_draw_elements(); + cf_apply_shader(draw.shader, draw.material, draw.mesh); + cf_draw_elements(draw.mesh); cf_draw_pop_shader(); } diff --git a/src/cute_draw.cpp b/src/cute_draw.cpp index 62c4aeaae..f1aa85dee 100644 --- a/src/cute_draw.cpp +++ b/src/cute_draw.cpp @@ -349,7 +349,6 @@ static void s_draw_report(spritebatch_sprite_t* sprites, int count, int texture_ // Map the vertex buffer with sprite vertex data. cf_mesh_update_vertex_data(draw->mesh, verts, vert_count); - cf_apply_mesh(draw->mesh); // Apply the atlas texture. CF_Texture atlas = { sprites->texture_id }; @@ -366,7 +365,7 @@ static void s_draw_report(spritebatch_sprite_t* sprites, int count, int texture_ cf_material_set_render_state(draw->material, cmd.render_state); // Kick off a draw call. - cf_apply_shader(cmd.shader, draw->material); + cf_apply_shader(cmd.shader, draw->material, draw->mesh); // Apply viewport. CF_Rect viewport = cmd.viewport; @@ -380,7 +379,7 @@ static void s_draw_report(spritebatch_sprite_t* sprites, int count, int texture_ cf_apply_scissor(scissor.x, scissor.y, scissor.w, scissor.h); } - cf_draw_elements(); + cf_draw_elements(draw->mesh); draw->has_drawn_something = true; } @@ -3254,7 +3253,6 @@ void static s_blit(CF_Command* cmd, CF_Canvas src, CF_Canvas dst, bool clear_dst verts[5].uv = V2(0,0); cf_mesh_update_vertex_data(draw->blit_mesh, verts, 6); - cf_apply_mesh(draw->blit_mesh); // Read pixels from src. cf_material_set_texture_fs(draw->material, "u_image", cf_canvas_get_target(src)); @@ -3270,7 +3268,7 @@ void static s_blit(CF_Command* cmd, CF_Canvas src, CF_Canvas dst, bool clear_dst cf_material_set_render_state(draw->material, cmd->render_state); // Apply shader. - cf_apply_shader(*blit, draw->material); + cf_apply_shader(*blit, draw->material, draw->blit_mesh); // Apply viewport. CF_Rect viewport = cmd->viewport; @@ -3285,7 +3283,7 @@ void static s_blit(CF_Command* cmd, CF_Canvas src, CF_Canvas dst, bool clear_dst } // Blit onto dst. - cf_draw_elements(); + cf_draw_elements(draw->blit_mesh); } static void s_process_command(CF_Canvas canvas, CF_Command* cmd, CF_Command* next, bool& clear) diff --git a/src/cute_graphics.cpp b/src/cute_graphics.cpp index b1754cb32..340a053de 100644 --- a/src/cute_graphics.cpp +++ b/src/cute_graphics.cpp @@ -631,21 +631,20 @@ CF_DISPATCH_SHIM_VOID(destroy_mesh, (CF_Mesh mesh_handle), mesh_handle) CF_DISPATCH_SHIM_VOID(mesh_update_vertex_data, (CF_Mesh mesh_handle, void* data, int count), mesh_handle, data, count) CF_DISPATCH_SHIM_VOID(mesh_update_index_data, (CF_Mesh mesh_handle, void* data, int count), mesh_handle, data, count) CF_DISPATCH_SHIM_VOID(mesh_update_instance_data, (CF_Mesh mesh_handle, void* data, int count), mesh_handle, data, count) -CF_DISPATCH_SHIM_VOID(apply_mesh, (CF_Mesh mesh_handle), mesh_handle) CF_DISPATCH_SHIM(CF_Shader, make_shader_from_bytecode, (CF_ShaderBytecode vertex_bytecode, CF_ShaderBytecode fragment_bytecode), vertex_bytecode, fragment_bytecode) CF_DISPATCH_SHIM_VOID(destroy_shader_internal, (CF_Shader shader_handle), shader_handle) -CF_DISPATCH_SHIM_VOID(apply_shader, (CF_Shader shader_handle, CF_Material material_handle), shader_handle, material_handle) +CF_DISPATCH_SHIM_VOID(apply_shader, (CF_Shader shader_handle, CF_Material material_handle, CF_Mesh mesh_handle), shader_handle, material_handle, mesh_handle) -void cf_sdlgpu_draw_elements(); -void cf_gles_draw_elements(); -void cf_draw_elements() +void cf_sdlgpu_draw_elements(CF_Mesh mesh_handle); +void cf_gles_draw_elements(CF_Mesh mesh_handle); +void cf_draw_elements(CF_Mesh mesh_handle) { if (app->gfx_backend_type == CF_BACKEND_TYPE_GLES3) { - cf_gles_draw_elements(); + cf_gles_draw_elements(mesh_handle); } else { #ifndef CF_EMSCRIPTEN - cf_sdlgpu_draw_elements(); + cf_sdlgpu_draw_elements(mesh_handle); #endif } } diff --git a/src/cute_graphics_gles.cpp b/src/cute_graphics_gles.cpp index bb8a47d59..dc6fb58d7 100644 --- a/src/cute_graphics_gles.cpp +++ b/src/cute_graphics_gles.cpp @@ -1259,12 +1259,6 @@ void cf_gles_destroy_mesh(CF_Mesh mh) CF_FREE(m); } -void cf_gles_apply_mesh(CF_Mesh mesh_handle) -{ - CF_GL_Mesh* mesh = (CF_GL_Mesh*)(uintptr_t)mesh_handle.id; - g_ctx.mesh = mesh; -} - static void s_build_uniforms(GLuint program, CF_GL_ShaderInfo* shader_info, const CF_ShaderInfo* uniform_info, GLuint* binding_point) { shader_info->uniform_members = (CF_ShaderUniformMemberInfo*)CF_ALLOC(sizeof(CF_ShaderUniformMemberInfo) * uniform_info->num_uniform_members); @@ -1501,10 +1495,11 @@ static void s_apply_vertex_attributes(CF_GL_Shader* shader, CF_GL_Mesh* mesh) CF_POLL_OPENGL_ERROR(); } -void cf_gles_apply_shader(CF_Shader shader_handle, CF_Material material_handle) +void cf_gles_apply_shader(CF_Shader shader_handle, CF_Material material_handle, CF_Mesh mesh_handle) { CF_GL_Shader* shader = (CF_GL_Shader*)(uintptr_t)shader_handle.id; CF_MaterialInternal* material = (CF_MaterialInternal*)(uintptr_t)material_handle.id; + CF_GL_Mesh* mesh = (CF_GL_Mesh*)(uintptr_t)mesh_handle.id; g_ctx.material = material; // Render state. @@ -1596,15 +1591,14 @@ void cf_gles_apply_shader(CF_Shader shader_handle, CF_Material material_handle) } CF_POLL_OPENGL_ERROR(); - CF_GL_Mesh* mesh = g_ctx.mesh; CF_ASSERT(mesh != NULL); s_apply_vertex_attributes(shader, mesh); } -void cf_gles_draw_elements() +void cf_gles_draw_elements(CF_Mesh mesh_handle) { - CF_GL_Mesh* mesh = g_ctx.mesh; + CF_GL_Mesh* mesh = (CF_GL_Mesh*)(uintptr_t)mesh_handle.id; CF_MaterialInternal* material = g_ctx.material; CF_ASSERT(mesh != NULL); CF_ASSERT(material != NULL); diff --git a/src/cute_graphics_sdlgpu.cpp b/src/cute_graphics_sdlgpu.cpp index ec5e56d7d..773bf7d7a 100644 --- a/src/cute_graphics_sdlgpu.cpp +++ b/src/cute_graphics_sdlgpu.cpp @@ -1222,13 +1222,6 @@ void cf_sdlgpu_apply_blend_constants(float r, float g, float b, float a) SDL_SetGPUBlendConstants(g_ctx.canvas->pass, color); } -void cf_sdlgpu_apply_mesh(CF_Mesh mesh_handle) -{ - CF_ASSERT(g_ctx.canvas); - CF_MeshInternal* mesh = (CF_MeshInternal*)mesh_handle.id; - g_ctx.canvas->mesh = mesh; -} - static void s_copy_uniforms(SDL_GPUCommandBuffer* cmd, CF_Arena* arena, CF_ShaderInternal* shd, CF_MaterialState* mstate, bool vs) { // Create any required uniform blocks for all uniforms matching between which uniforms @@ -1389,13 +1382,12 @@ static SDL_GPUGraphicsPipeline* s_build_pipeline(CF_ShaderInternal* shader, CF_R return pip; } -void cf_sdlgpu_apply_shader(CF_Shader shader_handle, CF_Material material_handle) +void cf_sdlgpu_apply_shader(CF_Shader shader_handle, CF_Material material_handle, CF_Mesh mesh_handle) { CF_ASSERT(g_ctx.canvas); - CF_ASSERT(g_ctx.canvas->mesh); - CF_MeshInternal* mesh = g_ctx.canvas->mesh; - CF_MaterialInternal* material = (CF_MaterialInternal*)material_handle.id; CF_ShaderInternal* shader = (CF_ShaderInternal*)shader_handle.id; + CF_MaterialInternal* material = (CF_MaterialInternal*)material_handle.id; + CF_MeshInternal* mesh = (CF_MeshInternal*)mesh_handle.id; CF_RenderState* state = &material->state; // Cache the pipeline to avoid create/release each frame. @@ -1511,9 +1503,12 @@ void cf_sdlgpu_apply_shader(CF_Shader shader_handle, CF_Material material_handle g_ctx.canvas->clear = false; } -void cf_sdlgpu_draw_elements() +void cf_sdlgpu_draw_elements(CF_Mesh mesh_handle) { - CF_MeshInternal* mesh = g_ctx.canvas->mesh; + CF_MeshInternal* mesh = (CF_MeshInternal*)mesh_handle.id; + CF_ASSERT(mesh != NULL); + CF_ASSERT(g_ctx.canvas); + if (mesh->instances.buffer) { if (mesh->indices.buffer) { SDL_DrawGPUIndexedPrimitives(g_ctx.canvas->pass, mesh->indices.element_count, mesh->instances.element_count, 0, 0, 0);