0 votes

I'm working on a little prototype, and I need to edit the Pixel data at run time.

My plan is to use GD native, and have a class that contains a reference to an image. Then I can use the images pixel data and modify it how I need.

I've done this before using SFML, and it was a little more straightforward, maybe because I knew the library better, but I could see how to get it to reupload to the GPU after I changed it.

Does anyone have any hints or tips on how to accomplish this using Godot?

in Engine by (30 points)

Basically textures/images can be modified with the Image class:

https://docs.godotengine.org/en/3.1/classes/class_image.html

It contains simple get/set pixel methods but has also a createfromdata method which can receive various formats.

My experience with the image class is very limited though (and I did GDScript only).

1 Answer

+3 votes
Best answer

To be modifiable at runtime from a script, a texture needs to be an ImageTexture, because you need pixel data in RAM to be able to edit it using the CPU. If it's not, it would need to be converted and re-assigned to whatever uses it.

If you generate such textures from scratch, you may keep an Image in a variable and use ImageTexture to render it. Then editing would be something like this:

var _image : Image
var _texture : ImageTexture

func edit_pixels():

    _image.lock()

    _image.set_pixel(x, y, color)
    ...

    _image.unlock()

    # If it's the first time, or if you want to upload the whole image
    _texture.create_from_image(_image, Texture.FLAGS_FILTER | Texture.FLAGS_REPEAT)

    # If the texture already has data,
    # you can upload pixels partially by providing the sub-rectangle you edited
    VisualServer.texture_set_data_partial(_texture.get_rid(), _image, min_x, min_y, size_x, size_y, dst_x, dst_y, 0, 0)

Note: there is another way to "edit" textures at runtime, using the GPU instead, is by directly rendering onto them with Viewport (a bit like SFML's RenderTexture). Viewports can also be treated as a texture if you get_texture() from them, so whatever you draw inside will be reflected on nodes you used their texture from.

by (27,784 points)
selected by

Perfect! This is exactly what I was looking for, thanks! I'm prototyping some pixel destruction similar to worms, so the partial upload will be a huge help.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.