Class: ExampleApp::DoubleBufferRenderTest

Inherits:
ZifExampleScene show all
Defined in:
app/scenes/double_buffer_render_test.rb

Overview

Demonstration of the performance improvement by using the double buffering technique for RenderTargets

Instance Attribute Summary collapse

Attributes inherited from ZifExampleScene

#next_scene, #scene_timer, #tracer_service_name

Attributes included from Zif::Traceable

#tracer_service_name

Instance Method Summary collapse

Methods inherited from ZifExampleScene

#display_context_labels, #display_timer_bar

Methods included from Zif::Traceable

#mark, #mark_and_print, #mark_prefix, #tracer

Methods inherited from Zif::Scene

#unload_scene

Methods included from Zif::Serializable

#exclude_from_serialize, #inspect, #serialize, #to_s

Constructor Details

#initializeDoubleBufferRenderTest

Returns a new instance of DoubleBufferRenderTest.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/scenes/double_buffer_render_test.rb', line 6

def initialize
  super
  @next_scene = :load_compound_sprite_test
  # Turn the threshold down to see a breakdown of performance:
  # tracer.time_threshold = 0.002

  mark('#initialize: Begin')

  @map = Zif::Layers::LayerGroup.new(name: 'double_buffered_test', logical_width: 20, logical_height: 12)
  @map.new_simple_layer(:fully_rerender)
  @map.new_simple_layer(:double_buffered_rerender)

  @map.layers[:fully_rerender].source_sprites = initialize_sprites(:fully_rerender)
  @map.layers[:double_buffered_rerender].source_sprites = initialize_sprites(:double_buffered_rerender, 1)

  @rendering = true
  @full_render = false
  @never_rendered = true
  mark('#initialize: Finished')
end

Instance Attribute Details

#mapObject

Returns the value of attribute map.



4
5
6
# File 'app/scenes/double_buffer_render_test.rb', line 4

def map
  @map
end

Instance Method Details

#flags_from_clicks(layer) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
# File 'app/scenes/double_buffer_render_test.rb', line 56

def flags_from_clicks(layer)
  if (@full_render && (layer == :fully_rerender)) || (!@full_render && (layer == :double_buffered_rerender))
    @rendering = !@rendering
  end

  if (@full_render && (layer == :double_buffered_rerender)) || (!@full_render && (layer == :fully_rerender))
    @full_render = !@full_render
    @rendering   = true
  end

  puts "Clicked #{layer}.  Rendering #{@rendering}, active layer #{@full_render}"
end

#initialize_sprites(name, page = 0) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'app/scenes/double_buffer_render_test.rb', line 27

def initialize_sprites(name, page=0)
  992.times.map do |i|
    y_i, x_i = i.divmod(32)
    $game.services[:sprite_registry].construct(:white_1).tap do |s|
      s.name = "#{name}_#{x_i}_#{y_i}"
      s.b = page.zero? ? 200 : 0
      s.r = 100 + x_i
      s.g = 100 + y_i
      s.x = (x_i * (16 + 1)) + (page * 640) + 50
      s.y = (y_i * (16 + 1)) + 70
      s.w = 16
      s.h = 16
      s.on_mouse_up = lambda do |_sprite, _point|
        flags_from_clicks(name)
      end
    end
  end
end

#perform_tickObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'app/scenes/double_buffer_render_test.rb', line 69

def perform_tick
  mark('#perform_tick: Begin')

  $gtk.args.outputs.background_color = [0, 0, 0, 0]
  mark('#perform_tick: Init')

  @full_render = !@full_render if $gtk.args.inputs.keyboard.key_up.x
  @rendering   = !@rendering if $gtk.args.inputs.keyboard.key_up.z

  rerender_focus
  mark('#perform_tick: rerender_focus')

  perform_tick_debug_labels

  mark('#perform_tick: Finished')
  super
end

#perform_tick_debug_labelsObject

rubocop:disable Layout/LineLength rubocop:disable Style/NestedTernaryOperator



108
109
110
111
112
113
114
# File 'app/scenes/double_buffer_render_test.rb', line 108

def perform_tick_debug_labels
  color = {r: 255, g: 255, b: 255, a: 255}
  active_color = {r: 255, g: 0, b: 0, a: 255}
  $gtk.args.outputs.labels << { x: 8, y: 720 - 48, text: "Render mode (press X to change, Z for off): #{@rendering ? (@full_render ? 'Full re-render' : 'Double buffer re-render') : 'Off'}" }.merge(color)
  $gtk.args.outputs.labels << { x: 50,  y: 720 - 100, text: 'Full re-render' }.merge(@rendering && @full_render ? active_color : color)
  $gtk.args.outputs.labels << { x: 690, y: 720 - 100, text: 'Double buffered re-render' }.merge(@rendering && !@full_render ? active_color : color)
end

#prepare_sceneObject



46
47
48
49
50
51
52
53
54
# File 'app/scenes/double_buffer_render_test.rb', line 46

def prepare_scene
  super

  $game.services[:input_service].register_clickable(@map.layers[:fully_rerender].containing_sprite)
  $game.services[:input_service].register_clickable(@map.layers[:double_buffered_rerender].containing_sprite)

  cs = @map.layer_containing_sprites
  $gtk.args.outputs.static_sprites << cs
end

#rerender_focusObject



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'app/scenes/double_buffer_render_test.rb', line 87

def rerender_focus
  if @rendering
    cur_layer = @full_render ? :fully_rerender : :double_buffered_rerender
    s = @map.layers[cur_layer].source_sprites.sample
    s.r, s.g, s.b = Zif.hsv_to_rgb($gtk.args.tick_count % 360, 100, 100)

    # This is the magic.
    @map.layers[cur_layer].rerender_rect = s.rect if (cur_layer == :double_buffered_rerender) && !@never_rendered
  end

  @map.layers[:fully_rerender].should_render           = @never_rendered || (@rendering && @full_render)
  @map.layers[:double_buffered_rerender].should_render = @never_rendered || (@rendering && !@full_render)

  mark('#rerender_focus: Setup')
  @map.refresh
  mark('#rerender_focus: Refresh')
  @never_rendered = false
end