Example of using a render target resource in a GUI

Someone asked for an example on how to use render target resources in GUI in some thread a while back. And it turned out it was a bit tricky so we needed to add / fix a small thing related to render target resources in the engine (Add attachment texture resource path into resource.get_render_target_… · defold/defold@9a0000d · GitHub).

Anyway, here’s a small example on how you can use a render target in a GUI:
GH: https://github.com/Jhonnyg/my-public-defold-examples/tree/master/render-target-resource
HTML5: Render Target Resource 1.0

The setup is somewhat simple:

  • A dummy atlas is created with a single animation, which is added to the GUI and a box node is set to use the dummy animation/texture in the editor
  • The dummy atlas animation is updated once in runtime - the backing texture of the atlas is set to the render target resource and the animation is updated to match the dimensions of the render target
  • The render script renders the map (and applies a post-process effect) onto the RT every frame, which is now successfully connected to the render target resource texture!
17 Likes

Think that may have been me - thank you, can’t wait to try it out and release my game!

2 Likes

Yes that’s right, it was you! Sorry for the delay :sweat_smile:

1 Like

Trying to run the project (on latest Defold) and gettings errors. Could I be missing an extension/plugin?

/main/car/yellow_car.tilemap
	The file '/main/car/yellow_car.tilemap' could not be loaded: Message missing required fields: layers[0].is_visible
/main/main.tilemap
	The file '/main/main.tilemap' could not be loaded: Message missing required fields: layers[0].is_visible, layers[1].is_visible

I think you need the 1.9.1 beta: Defold 1.9.1 BETA

1 Like

I think I’m getting close with this - hopefully - but what predicates do I use to draw the GUI objects I want to render to the texture? (I’ve tried predicates.gui but I’m coming up, literally, blank)

This is in my render code, with a message sent when a draw is needed. The values for the capture area should be on screen for testing, then I’ll point it off screen to the avatars.

    if is_render_avatars == true then
        is_render_avatars = false
        render.enable_material("my_material")
        render.set_render_target("avatar_boy")
        local rt_width = render.get_render_target_width("avatar_boy", render.BUFFER_COLOR_BIT)
        local rt_height = render.get_render_target_width("avatar_boy", render.BUFFER_COLOR_BIT)
        render.set_viewport(0, 0, rt_width, rt_height)
        render.clear({[render.BUFFER_COLOR_BIT] = vmath.vector4(0,0,0,0)})

        -- * set projection to off-screen avatar (boy)
        local avatar_half_x = 340 / 2 -- * set to avatar width
        local avatar_half_y = 300 / 2 -- * set to avatar height
        local pos_x = 0 -- * set to avatar off-screen position x
        local pos_y = 0 -- * set to avatar off-screen position y
        local window_proj = vmath.matrix4_orthographic(pos_x - avatar_half_x, pos_x + avatar_half_x, pos_y - avatar_half_y, pos_y + avatar_half_y, DEFAULT_NEAR, DEFAULT_FAR)
        render.set_projection(window_proj)


        -- * this is the actual draw
        local predicates = self.predicates
        local state = self.state
        local camera_gui = state.cameras.camera_gui
        render.draw(predicates.gui, camera_gui.frustum)
        -- * Reset the render target.
        render.disable_material()
        render.set_render_target(render.RENDER_TARGET_DEFAULT)
    end

Just one last piece of the puzzle with this one!

If I have something positioned at 400x400 on my GUI, with a size of 200x200, how do I get convert the position/size values so the render script can use them to capture the area to the render texture?