Thanks for the reply. This is what I've found that basically works. In process:
Image im = Image::new();
ImageTexture imTex = ImageTexture::_new();
im->create(width, height, false, Image::FORMAT_RGBA8);
im->lock();
for(int x=0; x<width; x++){
for(int y=0; y < height; y++){
// call im->set_pixel to create the image
}
}
im->unlock();
imTex->set_storage(ImageTexture::STORAGE_RAW);
imTex->create_from_image(Ref<Image>(im));
set_texture(Ref<ImageTexture>(imTex));
It's not totally ideal because, first, I'm calling set_pixel a lot of times instead of loading the image directly from a byte array, and second, I'm having to create a new image and new texture every frame instead of changing an existing one, and that ought to have some overhead. The program crashes if I try to lock an Image that was already used to create an ImageTexture. It also crashes if I try to call set_data on an ImageTexture more than once.
Fortunately I am still getting a decent framerate (with some flickering, though...), and there doesn't appear to be a memory leak.