Open waqs102 opened 2 days ago
Basically lifetimes. Try changing the lib to work like you put in your post, you will very quickly face lifetime problems. Now we could add a unsafe
way of doing what you want, but safe, I don't it's possible.
Basically lifetimes. Try changing the lib to work like you put in your post, you will very quickly face lifetime problems. Now we could add a
unsafe
way of doing what you want, but safe, I don't it's possible.
Thanks for the reply. I didn't quite understand the problem with lifetimes, but an unsafe
option would suit me perfectly. Is it possible at the moment? Unfortunately, I'm new to programming – in which direction should I look? Should I somehow use sdl2_sys::SDL_SetRenderTarget
and raw pointers?
With Canvas.raw()
you can obtain the raw pointer of the Renderer. https://docs.rs/sdl2/latest/sdl2/render/struct.Canvas.html#method.raw .
Before anything, get the current target (Surface, Window, etc): sys::SDL_GetRenderTarget
you will need it later.
From that: sys::SDL_SetRenderTarget(raw_renderer_ptr, raw_texture_ptr)
.
Then do your calls, and at the end sys::SDL_SetRenderTarget(raw_renderer_ptr, original_target_ptr)
I do have to say I don't really understand your use case. Everything that you said should be possible to do with with_multiple_texture_canvas
. Perhaps your methology is un-rust-y? If I understand right, you want to do direct calls to the render API from the poll_iter events. Why not push "Change"s to a vector, and then group them and process them with with_multiple_texture_canvas
later?
@Cobrand Thank you so much for the tips!
Yes, in my case the user's actions directly affect which parts of the screen will be updated (there are many of these parts and they are small, but they are not updated too often). So I decided not to iterate all the states of the parts on each frame. Therefore, I draw changes on the main texture first (acting with it as a kind of a buffer, since SDL does not guarantee the backbuffer of the previous frame will remain valid), and then I just draw that texture on the screen.
Yes, at the moment I really use draw_buffer: Vec<(Rect, Rect)>
to perform everything inside single closure (and if it is empty then nothing happens). The first Rect
indicates src
, the second one dst
to call canvas.copy
then. However, this action looks unnecessary and could be 100% avoided using the option I have given. That's why I asked this question. As I understood from your answers – the problem lies in the unsafe approach of the C language in contrast to Rust. And I can't understand your answer about lifetimes yet (but I will try).
Also, should I close the issue, since its solution does not correspond to the concepts of safety of the crate?
Canvas
has two methods for working with drawing on textures:with_texture_canvas
andwith_multiple_texture_canvas
. The first one is used for single drawing on single texture (meaning single closure). The second one is used for single drawing on multiple textures (meaning single closure is called multiple times).But there is no way to use multiple function calls for one or more textures, avoiding useless checks and returning the target to the original one each time the closure ends (or without using some kind of buffer with rectangles to perform all partial drawings within a single closure, for example).
This is especially true for external event processing, where each event in
poll_iter
needs to call its own separate drawing function before the whole texture will be presented. There is no problem if you draw onWindow
orSurface
using aCanvas
draw API, but this isn't true for drawing onTexture
.So my question is: why? As I understood it could look something like this:
instead of this: