#-------------------------------------------------------------------------- # * Draw A Layer #-------------------------------------------------------------------------- def draw_layer(layer, rect=nil, force=false) pos = {} if rect.nil? pos['x1'] = 0 pos['y1'] = 0 pos['x2'] = get_selected_map.width pos['y2'] = get_selected_map.height else pos['x1'] = rect.x pos['y1'] = rect.y pos['x2'] = rect.x + rect.width pos['y2'] = rect.y + rect.height end # If layer has not been cached yet or is force to be draw, redraw it unless ($project.cache.layer_cached?(get_selected_map.id, layer.id) && force == false) layer_bitmap = get_layer_bitmap(layer) # Draw everything inside the given Rect for x in pos['x1']...pos['x2'] for y in pos['y1']...pos['y2'] tile = layer.tiles[x,y] next if tile.tile_id == -1 bitmap = get_tile_bitmap(tile) image = bitmap.convert_to_image layer_bitmap.draw {|dc| dc.draw_bitmap(bitmap, x*32,y*32, true) } end end else layer_bitmap = get_layer_bitmap(layer) end # Store layer bitmap back into cache $project.cache.store_layer(get_selected_map.id, layer.id, layer_bitmap) end #-------------------------------------------------------------------------- # * Draw All Layers #-------------------------------------------------------------------------- def draw_layers(rect=nil,force=false) # Draw layer bitmaps for layer in get_selected_map.layers next if ($project.cache.layer_cached?(get_selected_map.id, layer.id) && force == false) next unless layer.enabled draw_layer(layer, rect, force) end end #-------------------------------------------------------------------------- # * Draw Tilemap # rect :portion to draw, redraw full layer if not specified # layer_index : layer to start drawing from # force :force to redraw everything #-------------------------------------------------------------------------- def draw_tilemap(rect=nil,layer_index=0,force=false) return if get_selected_map.nil? width = get_selected_map.width * 32 height = get_selected_map.height * 32 start_time = Time.now unless $project.cache.tilemap_cached?(get_selected_map.id) draw_layers(rect, force) tilemap_bitmap = get_tilemap_bitmap # Draw All Layers on the window if get_selected_map.nil? @scrollwin_map.paint {|dc| dc.clear} else # If no Rect specified # Redraw th whole tilemap (slower) if rect.nil? # Draw Background tilemap_bitmap.draw {|dest_dc| dest_dc.set_pen(Wx::Pen.new(Wx::Colour.new($project.config.transparent_color,1))) dest_dc.set_brush(Wx::Brush.new(Wx::Colour.new($project.config.transparent_color,1))) dest_dc.draw_rectangle(0,0,width,height) } # Draw layers for i in layer_index...get_selected_map.layers.size Wx::log_message("Drawing layer #{i} on tilemap") layer = get_selected_map.layers[i] next unless layer.enabled bitmap = get_layer_bitmap(layer) $project.cache.store_layer(get_selected_map.id, layer.id, bitmap) # Convert bitmap to image image = bitmap.convert_to_image # Convert image back to bitmap bitmap = image.convert_to_bitmap bitmap.set_mask(Wx::Mask.new(bitmap, Wx::BLACK)) tilemap_bitmap.draw {|dc| dc.draw_bitmap(bitmap,0,0,true)} end Wx::log_message("Drawing full layers completed on tilemap") else # Otherwise, only blit the specified portion for all layers (faster) x = rect.x * 32 y = rect.y * 32 width = rect.width * 32 height = rect.height * 32 # Draw Background tilemap_bitmap.draw {|dest_dc| dest_dc.set_pen(Wx::Pen.new(Wx::Colour.new($project.config.transparent_color,1))) dest_dc.set_brush(Wx::Brush.new(Wx::Colour.new($project.config.transparent_color,1))) dest_dc.draw_rectangle(x,y,width,height) } l_time = Time.now for i in layer_index...get_selected_map.layers.size Wx::log_message("Drawing portion of layer #{i} on tilemap") layer = get_selected_map.layers[i] # Get Layer Bitmap bitmap = get_layer_bitmap(layer) $project.cache.store_layer(get_selected_map.id, layer.id, bitmap) # Convert bitmap to image image = bitmap.convert_to_image # Convert image back to bitmap bitmap = image.convert_to_bitmap bitmap.set_mask(Wx::Mask.new(bitmap, Wx::BLACK)) bitmap.draw {|src_dc| # Draw on tilemap tilemap_bitmap.draw {|dest_dc| dest_dc.blit(x,y,width,height, src_dc,x,y,Wx::COPY,true) } } end Wx::log_message("Cycle took #{Time.now-l_time} seconds") end end else Wx::log_message("Drawing skipped, tilemap bitmap retrieved from cache") tilemap_bitmap = get_tilemap_bitmap end # Store tilemap bitmap back into cache (before drawing grid, etc. because we don 1 or event.height > 1 dc.set_pen(Wx::Pen.new(Wx::BLACK,1)) dc.set_brush(Wx::Brush.new(Wx::BLACK,1)) dc.draw_rectangle(x+3,y+28,28,4) dc.draw_rectangle(x+28,y+3,4,29) dc.set_pen(Wx::Pen.new(color,1)) dc.set_brush(Wx::Brush.new(color,1)) # Large horizontal events if event.width > 1 && event.height == 1 dc.draw_rectangle(x+3,y+29,29,2) else dc.draw_rectangle(x+3,y+29,27,2) end # Large vertical events if event.width == 1 && event.height > 1 dc.draw_rectangle(x+29,y+3,2,29) else dc.draw_rectangle(x+29,y+3,2,28) end end end end # Draw grid on tilemap dc.draw_bitmap(draw_grid,0,0,true) if @enable_grid } image = tilemap_bitmap.convert_to_image image.rescale((image.get_width * @zoom_level).floor, (image.get_height * @zoom_level).floor) tilemap_bitmap = image.convert_to_bitmap # Draw on window @scrollwin_map.paint {|dc| # Prepare DC @scrollwin_map.do_prepare_dc(dc) # Draw tilemap on window dc.draw_bitmap(tilemap_bitmap,0,0,true) } # Remember bitmap to draw when scrolling @scrollwin_map.draw_bitmap(tilemap_bitmap) @new_map = false # DEBUG is_cached = $project.cache.tilemap_cached?(get_selected_map.id) ? "Tilemap is cached" : "Tilemap is NOT cached" Wx::log_message("Drawing took #{Time.now - start_time} seconds (#{is_cached})") end