Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide built-in API for generating "render target texture" and/or simplify "Render to Texture" example #7358

Open
tigregalis opened this issue Jan 25, 2023 · 0 comments · May be fixed by #17209
Labels
A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it!

Comments

@tigregalis
Copy link
Contributor

tigregalis commented Jan 25, 2023

What problem does this solve or what need does it fill?

A snippet from the Render to Texture example on main:

fn setup(
    // ...
) {
    let size = Extent3d {
        width: 512,
        height: 512,
        ..default()
    };

    // This is the texture that will be rendered to.
    let mut image = Image {
        texture_descriptor: TextureDescriptor {
            label: None,
            size,
            dimension: TextureDimension::D2,
            format: TextureFormat::Bgra8UnormSrgb,
            mip_level_count: 1,
            sample_count: 1,
            usage: TextureUsages::TEXTURE_BINDING
                | TextureUsages::COPY_DST
                | TextureUsages::RENDER_ATTACHMENT,
        },
        ..default()
    };

    // fill image.data with zeroes
    image.resize(size);
    
    // ...
}

There's quite a lot going on in this snippet that, not coming from a rendering background, and just wanting to make pretty pictures, I simply don't understand.

What solution would you like?

My less-preferred solution is to simplify the example by creating a helper function, that uses the Default impl for Image, and calling it in the setup.

fn create_render_target_texture(width: u32, height: u32) -> Image {
    let mut image = Image::default();

    // `Image::resize` replaces `Image.texture_descriptor.size` as well as fills `Image.data` with zeroes.
    image.resize(Extent3d {
        width,
        height,
        ..default()
    });

    image.texture_descriptor.usage =
        TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST | TextureUsages::RENDER_ATTACHMENT;

    image
}

fn setup(
    // ...
) {
    let image = create_render_target_texture(512, 512);
    // ...
}

By using the Default impl it also removes 3 uses, and perhaps the remaining uses within fn create_render_target_texture could be put into the body or fully qualified.

My more-preferred solution would be to expose this same helper function (with a better name) as a constructor on Image. The example can simply call that constructor.

What alternative(s) have you considered?

Leave it as it is, and force future users to dive into (some of) the implementation details to understand what's going on.

Perhaps there is a missing higher level API to achieve the same outcomes?

Being new to rendering in general, there are a large number of properties that I'm not really sure what they do (hence my reliance on the Default impl). Maybe some of these it makes sense to expose as parameters for the helper function / constructor.

Additional context

Initially all I had read was the Bevy 0.8 release notes, and just tried to construct an Image and see if I could get it working
(I thought it couldn't be that hard), then I got a few crashes / things I had to import / all these weird rendering concepts / etc., until I folded and decided to see if there was an example (and of course there was).

Strictly speaking, there are two small differences between my proposed version and the example:

  1. The example sets the size when initially constructing the Image, then resizes, but resize sets the size anyway so we don't need to do this extra step.

  2. The example sets Image.texture_descriptor.format to TextureFormat::Bgra8UnormSrgb, but the default impl sets this to TextureFormat::Rgba8UnormSrgb via wgpu::TextureFormat::bevy_default(). I don't know what sort of impact this has, but it works on my machine.

@tigregalis tigregalis added C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Jan 25, 2023
@tigregalis tigregalis changed the title Provide built-in API for generating "render to target" texture and/or simplify example Provide built-in API for generating "render target texture" and/or simplify "Render to Texture" example Jan 25, 2023
@alice-i-cecile alice-i-cecile added A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use and removed C-Feature A new feature, making something new possible S-Needs-Triage This issue needs to be labelled labels Jan 25, 2023
@BenjaminBrienen BenjaminBrienen added S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! D-Straightforward Simple bug fixes and API improvements, docs, test and examples labels Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Usability A targeted quality-of-life change that makes Bevy easier to use D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it!
Projects
None yet
3 participants