Draw render target to screen (SOLVED)

I make my render_target. Then draw something on it. How can i draw render_target to screen?

local function render_occlusion_map(self)
	render.enable_render_target(self.occlusion_map_target)
	render.clear({[render.BUFFER_COLOR_BIT] = self.white_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0})
	render.enable_material("block_light")
	render.draw(self.block_light_pred)
	render.disable_material("block_light")
	render.disable_render_target(self.occlusion_map_target)
	render.enable_texture(0, self.occlusion_map_target, render.BUFFER_COLOR_BIT)
	render.draw(???)
	render.disable_texture(0, self.occlusion_map_target, render.BUFFER_COLOR_BIT)
end
1 Like

You set the render target as texture, then draw a predicate that contains stuff with a material that uses texture (0 in your case).


function init(self)
    self.some_pred = render.predicate({"material_tag"})
    ....
end

function update(self)
    ...
    render.enable_texture(0, self.my_target, render.BUFFER_COLOR_BIT)
    render.draw(self.some_pred)
    render.disable_texture(0, self.my_target)
end

Set up the material with the texture 0:

And use it in the fragment shader:

varying mediump vec2 var_texcoord0;
varying mediump vec3 var_position;

uniform lowp sampler2D TEX0;

void main() {	
    gl_FragColor = texture2D(TEX0, var_texcoord0.xy);
}
1 Like

You can check out the “examples” project here: https://github.com/defold/defold-examples

The “3d material” example contains a simple anaglyghic 3d rendering that renders to 2 targets and then joins them in a shader.

2 Likes

I have no predicate that uses texture. I need to draw all pixels from render_target to screen.

You must draw the texture through a shader onto some vertices that are textured (with fragment shader).

To cover the screen, create a model with a quad, use the material on the model and set the view and projection accordingly.

More information on how it works here:


3 Likes

Ok i make a sprite with custom material.
but when i draw on it, render target texture, have only part of screen that i draw on it.(red/white sprite, red - is stone wall) What am i doing wrong? projection - is same for all draw.

local function init_occlusion_map_target(self)
  self.occlusion_map_color_params = {
    format = render.FORMAT_RGBA,
    width = render.get_width(),
    height = render.get_height(),
    min_filter = render.FILTER_LINEAR,
    mag_filter = render.FILTER_LINEAR,
    u_wrap = render.WRAP_CLAMP_TO_EDGE,
    v_wrap = render.WRAP_CLAMP_TO_EDGE }
  self.occlusion_map_depth_params = {
    format = render.FORMAT_DEPTH,
    width = render.get_width(),
    height = render.get_height(),
    u_wrap = render.WRAP_CLAMP_TO_EDGE,
    v_wrap = render.WRAP_CLAMP_TO_EDGE }
  self.occlusion_map_target = render.render_target("occlusion_map", {
    [render.BUFFER_COLOR_BIT] = self.occlusion_map_color_params,
    [render.BUFFER_DEPTH_BIT] = self.occlusion_map_depth_params })
end

function init(self)
    self.tile_pred = render.predicate({"tile"})
    self.gui_pred = render.predicate({"gui"})
    self.text_pred = render.predicate({"text"})
    self.particle_pred = render.predicate({"particle"})
    self.block_light_pred = render.predicate({"block_light"})
    self.screen_pred = render.predicate({"screen"})

    self.clear_color = vmath.vector4(0, 0, 0, 0)
    self.clear_color.x = sys.get_config("render.clear_color_red", 0)
    self.clear_color.y = sys.get_config("render.clear_color_green", 0)
    self.clear_color.z = sys.get_config("render.clear_color_blue", 0)
    self.clear_color.w = sys.get_config("render.clear_color_alpha", 0)
    self.white_color=vmath.vector4(1, 1, 1, 1)

    self.view = vmath.matrix4()
    init_occlusion_map_target(self)
end



local function render_occlusion_map(self)
render.set_projection(vmath.matrix4_orthographic(0, render.get_width(), 0, render.get_height(), -1, 1))
	render.enable_render_target(self.occlusion_map_target)
	render.clear({[render.BUFFER_COLOR_BIT] = self.white_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0})
	render.enable_material("block_light")
	render.draw(self.block_light_pred)
	render.disable_material("block_light")
	render.disable_render_target(self.occlusion_map_target)
	render.enable_texture(0, self.occlusion_map_target, render.BUFFER_COLOR_BIT)
	render.draw(self.screen_pred)
	render.disable_texture(0, self.occlusion_map_target, render.BUFFER_COLOR_BIT)
end

function update(self)
render.set_depth_mask(true)
    render.clear({[render.BUFFER_COLOR_BIT] = self.clear_color, [render.BUFFER_DEPTH_BIT] = 1, [render.BUFFER_STENCIL_BIT] = 0})

    render.set_viewport(0, 0, render.get_window_width(), render.get_window_height())
    render.set_view(self.view)

    render.set_depth_mask(false)
    render.disable_state(render.STATE_DEPTH_TEST)
    render.disable_state(render.STATE_STENCIL_TEST)
    render.enable_state(render.STATE_BLEND)
    render.set_blend_func(render.BLEND_SRC_ALPHA, render.BLEND_ONE_MINUS_SRC_ALPHA)
    render.disable_state(render.STATE_CULL_FACE)

    render.set_projection(vmath.matrix4_orthographic(0, render.get_width(), 0, render.get_height(), -1, 1))

  
    render_occlusion_map(self)
    render.draw(self.tile_pred)
    --[[render.draw(self.tile_pred)
    render.draw(self.particle_pred)
    render.draw_debug3d()

    render.set_view(vmath.matrix4())
    render.set_projection(vmath.matrix4_orthographic(0, render.get_window_width(), 0, render.get_window_height(), -1, 1))

    render.enable_state(render.STATE_STENCIL_TEST)
    render.draw(self.gui_pred)
    render.draw(self.text_pred)
    render.disable_state(render.STATE_STENCIL_TEST)

    render.set_depth_mask(false)
    render.draw_debug2d()--]]
end

The projection and viewport sets how the coordinate system maps to screen space. Normally you want a sprite to cover the number of pixels that corresponds
to its width and height.

Some options:

  1. Position and resize the sprite so it covers the screen.

  2. Change the projection to match the size of the sprite before drawing it.

  3. Take a look at the example I linked. There I set up rendering of a small quad at origo so it covers the whole screen when rendered.

1 Like

Thx, i understand my problem. I am using sprite instead of model. In Vertex Shader i changed verticles positions. But when use var_texcoord0 in fragment shader it return me my sprite texture coords. When i changed to model everything work ok=)

1 Like