Class: Gosu::Window

Inherits:
Object
  • Object
show all
Defined in:
lib/texplay.rb

Direct Known Subclasses

WinClass

Instance Method Summary collapse

Instance Method Details

#render_to_image(image, options = {}) { ... } ⇒ Gosu::Image

Note:

Warning! This operation will corrupt an area of the screen, at the bottom left corner, equal in size to the image rendered to (or the clipped area), so should be performed in #draw before any other rendering.

Note:

The final alpha of the image will be 255, regardless of what it started with or what is drawn onto it.

Render directly into an existing image, optionally only to a specific region of that image.

Since this operation utilises the window’s back buffer, the image (or clipped area, if specified) cannot be larger than the window itself. Larger images can be rendered to only in separate sections using :clip_to areas, each no larger than the window).

Examples:

class Gosu
  class Window
    def draw
      # Always render images before regular drawing to the screen.
      unless @rendered_image
        @rendered_image = TexPlay.create_image(self, 300, 300, :color => :blue)
        render_to_image(@rendered_image) do
          @an_image.draw 0, 0, 0
          @another_image.draw 130, 0, 0
          draw_line(0, 0, Color.new(255, 0, 0, 0), 100, 100, Color.new(255, 0, 0, 0), 0)
          @font.draw("Hello world!", 0, 50, 0)
        end
      end

      # Perform regular screen rendering.
      @rendered_image.draw 0, 0
    end
  end
end

Parameters:

  • image (Gosu::Image)

    Existing image to render onto.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :clip_to (Array<Integer>) — default: [0, 0, image.width, image.height]

    Area of the image to render into. This area cannot be larger than the window, though the image may be.

Yields:

  • to a block that renders to the image.

Returns:

  • (Gosu::Image)

    The image that has been rendered to.

Raises:

  • (ArgumentError)


278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
# File 'lib/texplay.rb', line 278

def render_to_image(image, options = {})
  raise ArgumentError, "image parameter must be a Gosu::Image to be rendered to" unless image.is_a? Gosu::Image
  raise ArgumentError, "rendering block required" unless block_given?

  options = {
    :clip_to => [0, 0, image.width, image.height],
  }.merge! options

  texture_info = image.gl_tex_info
  tex_name = texture_info.tex_name
  x_offset = (texture_info.left * Gosu::MAX_TEXTURE_SIZE).to_i
  y_offset = (texture_info.top * Gosu::MAX_TEXTURE_SIZE).to_i

  raise ArgumentError, ":clip_to rectangle must contain exactly 4 elements" unless options[:clip_to].size == 4

  left, top, width, height = *(options[:clip_to].map {|n| n.to_i })

  raise ArgumentError, ":clip_to rectangle cannot be wider or taller than the window" unless width <= self.width and height <= self.height
  raise ArgumentError, ":clip_to rectangle width and height must be positive" unless width > 0 and height > 0

  right = left + width - 1
  bottom = top + height - 1

  unless (0...image.width).include? left and (0...image.width).include? right and
      (0...image.height).include? top and (0...image.height).include? bottom
    raise ArgumentError, ":clip_to rectangle out of bounds of the image"
  end

  # Since to_texture copies an inverted copy of the screen, what the user renders needs to be inverted first.
  scale(1, -1) do
    translate(-left, -top - self.height) do
      # TODO: Once Gosu is fixed, we can just pass width/height to clip_to
      clip_to(left, top, width, height) do
        # Draw over the background (which is assumed to be blank) with the original image texture,
        # to get us to the base image.
        image.draw(0, 0, 0)
        flush

        # Allow the user to overwrite the texture.
        yield
      end

      # Copy the modified texture back from the screen buffer to the image.
      to_texture(tex_name, x_offset + left, y_offset + top, 0, 0, width, height)

      # Clear the clipped zone to black again, ready for the regular screen drawing.
      # Quad can be a pixel out, so just make sure with a slightly larger shape.
      draw_quad(left - 2, top - 2, TexPlay::RENDER_CLEAR_COLOR,
                right + 2, top - 2, TexPlay::RENDER_CLEAR_COLOR,
                right + 2, bottom + 2, TexPlay::RENDER_CLEAR_COLOR,
                left - 2, bottom + 2, TexPlay::RENDER_CLEAR_COLOR)
    end
  end

  image
end