Class: SFML::RenderWindow

Inherits:
Object
  • Object
show all
Includes:
Graphics::RenderTarget
Defined in:
lib/sfml/graphics/render_window.rb

Overview

The main drawing surface. Wraps sfRenderWindow.

window = SFML::RenderWindow.new(800, 600, "Hello")

while window.open?
window.each_event do |event|
  case event
  in {type: :closed}                     then window.close
  in {type: :key_pressed, code: :escape} then window.close
  end
end

window.clear(SFML::Color.cornflower_blue)
window.display
end

Constant Summary collapse

CSFML_PREFIX =
:sfRenderWindow
DEFAULT_STYLE =

Default window style bitmask.

C::Window::Style::DEFAULT

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Graphics::RenderTarget

#clear, #default_view, #display, #draw, #draw_primitives, #map_coords_to_pixel, #map_pixel_to_coords, #view, #view=

Constructor Details

#initialize(*args, **opts) ⇒ RenderWindow

The first form takes (width, height, title, **opts). The second form takes (video_mode, title, **opts) for full control.

Options:

style:        bitmask of SFML::C::Window::Style constants
fullscreen:   true to use sfFullscreen state instead of sfWindowed
framerate:    cap to N FPS via sfRenderWindow_setFramerateLimit
vsync:        enable vertical sync
antialiasing: shorthand — MSAA level (2 / 4 / 8). Same as
            passing `context: ContextSettings.new(antialiasing: N)`
context:      a SFML::ContextSettings for full GL-context control

Raises:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/sfml/graphics/render_window.rb', line 35

def initialize(*args, **opts)
  mode, title = parse_args(args)
  style = opts.fetch(:style, DEFAULT_STYLE)
  state = opts[:fullscreen] ? :fullscreen : :windowed

  settings = _resolve_context_settings(opts)
  # Hold a reference for the duration of the C call so the
  # struct's memory survives until CSFML has copied it.
  @ctx_struct = settings ? settings.to_native : nil
  ctx_ptr     = @ctx_struct ? @ctx_struct.to_ptr : nil

  ptr = C::Graphics.sfRenderWindow_create(
    mode.to_native,
    title.to_s,
    style,
    C::Window::State[state],
    ctx_ptr,
  )
  raise WindowError, "sfRenderWindow_create returned NULL" if ptr.null?

  @handle = FFI::AutoPointer.new(ptr, C::Graphics.method(:sfRenderWindow_destroy))
  @event_buffer = C::Window::Event.new
  @requested_context = settings

  self.framerate_limit = opts[:framerate] if opts[:framerate]
  self.vsync = opts[:vsync]               unless opts[:vsync].nil?
end

Instance Attribute Details

#handle ⇒ Object (readonly)

:nodoc:



330
331
332
# File 'lib/sfml/graphics/render_window.rb', line 330

def handle
  @handle
end

#requested_context ⇒ Object (readonly)

What we asked for at creation time, if anything (otherwise nil).



71
72
73
# File 'lib/sfml/graphics/render_window.rb', line 71

def requested_context
  @requested_context
end

Class Method Details

.from_handle(handle) ⇒ Object

Wrap an existing OS-level window. handle is a platform native handle (Integer address or FFI::Pointer). Useful for embedding the renderer inside another framework's window (Qt, Gtk, raw Win32, NSView).

Raises:



298
299
300
301
302
303
304
305
306
307
308
# File 'lib/sfml/graphics/render_window.rb', line 298

def self.from_handle(handle)
  ptr = handle.is_a?(FFI::Pointer) ? handle : FFI::Pointer.new(:void, Integer(handle))
  raw = C::Graphics.sfRenderWindow_createFromHandle(ptr, nil)
  raise WindowError, "sfRenderWindow_createFromHandle returned NULL" if raw.null?

  win = allocate
  win.instance_variable_set(:@handle,
    FFI::AutoPointer.new(raw, C::Graphics.method(:sfRenderWindow_destroy)))
  win.instance_variable_set(:@event_buffer, C::Window::Event.new)
  win
end

Instance Method Details

#active=(value) ⇒ Object

Activate / deactivate the window's GL context on the current thread. Only one context can be active per thread at a time.



255
256
257
# File 'lib/sfml/graphics/render_window.rb', line 255

def active=(value)
  C::Graphics.sfRenderWindow_setActive(@handle, value ? true : false)
end

#capture_image ⇒ Object

Read the current back-buffer into a fresh CPU-side SFML::Image. Useful for processing/encoding the frame yourself (sending it over a socket, encoding as JPEG memory bytes, comparing against a reference, etc.).



162
163
164
165
166
167
# File 'lib/sfml/graphics/render_window.rb', line 162

def capture_image
  w, h = size.x, size.y
  tex  = Texture.create(w, h)
  tex.update_from_render_window(self)
  tex.to_image
end

#close ⇒ Object

Close the window — the next iteration of the main loop will see #open? == false.



81
82
83
84
# File 'lib/sfml/graphics/render_window.rb', line 81

def close
  C::Graphics.sfRenderWindow_close(@handle)
  self
end

#context_settings ⇒ Object

The actual ContextSettings the driver gave us. May differ from what we requested — the driver picks the closest level of MSAA / GL version it supports.



66
67
68
# File 'lib/sfml/graphics/render_window.rb', line 66

def context_settings
  ContextSettings.from_native(C::Graphics.sfRenderWindow_getSettings(@handle))
end

#cursor=(cursor) ⇒ Object

Apply a SFML::Cursor as the visible mouse pointer over this window. Keeps a Ruby reference so the Cursor object's lifetime spans at least until the next assignment.

Raises:

  • (ArgumentError)


110
111
112
113
114
# File 'lib/sfml/graphics/render_window.rb', line 110

def cursor=(cursor)
  raise ArgumentError, "RenderWindow#cursor= requires a SFML::Cursor" unless cursor.is_a?(Cursor)
  C::Graphics.sfRenderWindow_setMouseCursor(@handle, cursor.handle)
  @cursor = cursor
end

#cursor_grabbed=(grabbed) ⇒ Object

Lock the mouse pointer inside the window's client area while focused — useful for FPS-style games or when dragging widgets that need pixel-precise input.



124
125
126
# File 'lib/sfml/graphics/render_window.rb', line 124

def cursor_grabbed=(grabbed)
  C::Graphics.sfRenderWindow_setMouseCursorGrabbed(@handle, grabbed ? true : false)
end

#cursor_visible=(visible) ⇒ Object

Toggle the OS mouse pointer's visibility while it's over the window.



117
118
119
# File 'lib/sfml/graphics/render_window.rb', line 117

def cursor_visible=(visible)
  C::Graphics.sfRenderWindow_setMouseCursorVisible(@handle, visible ? true : false)
end

#each_event ⇒ Object

Yields every pending event for this frame, then returns. Without a block returns an Enumerator.



94
95
96
97
98
99
100
# File 'lib/sfml/graphics/render_window.rb', line 94

def each_event
  return enum_for(:each_event) unless block_given?
  while (event = poll_event)
    yield event
  end
  self
end

#focused? ⇒ Boolean

true if this window currently has OS-level keyboard focus.

Returns:

  • (Boolean)


203
204
205
# File 'lib/sfml/graphics/render_window.rb', line 203

def focused?       = C::Graphics.sfRenderWindow_hasFocus(@handle)
# Ask the OS to give this window focus. Cooperative — most
# window managers won't steal focus unconditionally.

#framerate_limit=(value) ⇒ Object

Cap the render loop to value frames per second. Set 0 to disable the cap.



130
131
132
# File 'lib/sfml/graphics/render_window.rb', line 130

def framerate_limit=(value)
  C::Graphics.sfRenderWindow_setFramerateLimit(@handle, Integer(value))
end

#icon=(image) ⇒ Object

Replace the window's title-bar / taskbar icon with the pixels from the given SFML::Image. The OS scales it as needed; 32×32 RGBA is the typical sweet spot.

Raises:

  • (ArgumentError)


172
173
174
175
176
177
178
179
# File 'lib/sfml/graphics/render_window.rb', line 172

def icon=(image)
  raise ArgumentError, "RenderWindow#icon= requires a SFML::Image" unless image.is_a?(Image)

  size = C::System::Vector2u.new
  size[:x] = image.width
  size[:y] = image.height
  C::Graphics.sfRenderWindow_setIcon(@handle, size, C::Graphics.sfImage_getPixelsPtr(image.handle))
end

#joystick_threshold=(value) ⇒ Object

Dead-zone for joystick axis events in [0, 100]. Axes whose absolute value is below this are reported as 0.



221
222
223
# File 'lib/sfml/graphics/render_window.rb', line 221

def joystick_threshold=(value)
  C::Graphics.sfRenderWindow_setJoystickThreshold(@handle, Float(value))
end

#key_repeat_enabled=(value) ⇒ Object

Toggle key repeat. With true, holding a key fires repeated :key_pressed events; with false only one fires per press.



215
216
217
# File 'lib/sfml/graphics/render_window.rb', line 215

def key_repeat_enabled=(value)
  C::Graphics.sfRenderWindow_setKeyRepeatEnabled(@handle, value ? true : false)
end

#maximum_size=(value) ⇒ Object

Upper bound on user-driven resizes — see #minimum_size=.



190
191
192
# File 'lib/sfml/graphics/render_window.rb', line 190

def maximum_size=(value)
  C::Graphics.sfRenderWindow_setMaximumSize(@handle, _vec2u_or_nil(value))
end

#minimum_size=(value) ⇒ Object

Constrain user-driven resizes. Accepts a [w, h] Array, a Vector2, or nil to clear the limit. When set, the OS won't let the user drag the window smaller (or larger) than this — programmatic size= is not affected.



185
186
187
# File 'lib/sfml/graphics/render_window.rb', line 185

def minimum_size=(value)
  C::Graphics.sfRenderWindow_setMinimumSize(@handle, _vec2u_or_nil(value))
end

#native_handle ⇒ Object

OS-specific native handle for the underlying window — HWND on Windows, NSView* on macOS, X11 Window xid on Linux.



196
197
198
# File 'lib/sfml/graphics/render_window.rb', line 196

def native_handle
  C::Graphics.sfRenderWindow_getNativeHandle(@handle)
end

#open? ⇒ Boolean

true while the window is still alive (hasn't been closed by #close or the user).

Returns:

  • (Boolean)


75
76
77
# File 'lib/sfml/graphics/render_window.rb', line 75

def open?
  C::Graphics.sfRenderWindow_isOpen(@handle)
end

#poll_event ⇒ Object

Returns the next pending Event or nil if the queue is empty.



87
88
89
90
# File 'lib/sfml/graphics/render_window.rb', line 87

def poll_event
  return nil unless C::Graphics.sfRenderWindow_pollEvent(@handle, @event_buffer)
  Event.from_native(@event_buffer)
end

#pop_gl_states ⇒ Object

Restore SFML's GL state after raw GL calls (paired with #push_gl_states).



262
263
264
# File 'lib/sfml/graphics/render_window.rb', line 262

def pop_gl_states   = C::Graphics.sfRenderWindow_popGLStates(@handle)
# Re-initialise SFML's GL state from scratch — heavier hammer
# than push/pop.

#position ⇒ Object

Top-left corner in desktop coordinates.



226
227
228
# File 'lib/sfml/graphics/render_window.rb', line 226

def position
  Vector2.from_native(C::Graphics.sfRenderWindow_getPosition(@handle))
end

#position=(value) ⇒ Object

Move the window's top-left corner in desktop coordinates.



231
232
233
234
235
236
# File 'lib/sfml/graphics/render_window.rb', line 231

def position=(value)
  vec = value.is_a?(Vector2) ? value : Vector2.new(*value)
  v = C::System::Vector2i.new
  v[:x] = Integer(vec.x); v[:y] = Integer(vec.y)
  C::Graphics.sfRenderWindow_setPosition(@handle, v)
end

#push_gl_states ⇒ Object

Save SFML's GL state before raw GL calls.



259
260
261
# File 'lib/sfml/graphics/render_window.rb', line 259

def push_gl_states  = C::Graphics.sfRenderWindow_pushGLStates(@handle)
# Restore SFML's GL state after raw GL calls (paired with
# `#push_gl_states`).

#request_focus ⇒ Object

Ask the OS to give this window focus. Cooperative — most window managers won't steal focus unconditionally.



206
# File 'lib/sfml/graphics/render_window.rb', line 206

def request_focus  = C::Graphics.sfRenderWindow_requestFocus(@handle)

#reset_gl_states ⇒ Object

Re-initialise SFML's GL state from scratch — heavier hammer than push/pop.



265
# File 'lib/sfml/graphics/render_window.rb', line 265

def reset_gl_states = C::Graphics.sfRenderWindow_resetGLStates(@handle)

#run ⇒ Object

Convenience driver loop. Yields the per-frame delta (SFML::Time) and auto-pumps events + display. The block is responsible for #clear and any drawing.

window.run do |dt, events|
events.each { |e| ... }
window.clear(...)
window.draw(...)
end


319
320
321
322
323
324
325
326
327
328
# File 'lib/sfml/graphics/render_window.rb', line 319

def run
  clock = Clock.new
  while open?
    dt = clock.restart
    events = each_event.to_a
    yield dt, events
    display
  end
  self
end

#scissor(view = self.view) ⇒ Object

The pixel-space scissor rect — same idea as viewport but for the view's scissor property. Pixels outside this rect are clipped before rendering.

Raises:

  • (ArgumentError)


289
290
291
292
# File 'lib/sfml/graphics/render_window.rb', line 289

def scissor(view = self.view)
  raise ArgumentError, "expected a SFML::View" unless view.is_a?(View)
  Rect.from_native(C::Graphics.sfRenderWindow_getScissor(@handle, view.handle))
end

#screenshot(path, format: nil) ⇒ Object

Capture the current back-buffer to disk. The format is inferred from the file extension (png / jpg / bmp / tga supported by CSFML's stb_image-based saver). Returns the path.

window.screenshot("screenshot.png")

format: lets you save under a different name than the extension. For an in-memory copy, use #capture_image instead.



153
154
155
156
# File 'lib/sfml/graphics/render_window.rb', line 153

def screenshot(path, format: nil)
  capture_image.save(path.to_s)
  path
end

#size ⇒ Object

Current window size in pixels as a Vector2.



140
141
142
143
# File 'lib/sfml/graphics/render_window.rb', line 140

def size
  v = C::Graphics.sfRenderWindow_getSize(@handle)
  Vector2.new(v[:x], v[:y])
end

#srgb? ⇒ Boolean

true if the framebuffer is sRGB-capable (i.e. the GL context was created with the sRGB attribute and the driver honoured it).

Returns:

  • (Boolean)


241
# File 'lib/sfml/graphics/render_window.rb', line 241

def srgb? = C::Graphics.sfRenderWindow_isSrgb(@handle)

#title=(value) ⇒ Object

Change the window's title bar text.



103
104
105
# File 'lib/sfml/graphics/render_window.rb', line 103

def title=(value)
  C::Graphics.sfRenderWindow_setTitle(@handle, value.to_s)
end

#viewport(view = self.view) ⇒ Object

The pixel-space rect a view projects onto inside this window. Combines the view's normalised viewport with the window's pixel size.

Raises:

  • (ArgumentError)


281
282
283
284
# File 'lib/sfml/graphics/render_window.rb', line 281

def viewport(view = self.view)
  raise ArgumentError, "expected a SFML::View" unless view.is_a?(View)
  Rect.from_native(C::Graphics.sfRenderWindow_getViewport(@handle, view.handle))
end

#visible=(value) ⇒ Object

---- OS-window state ----



209
210
211
# File 'lib/sfml/graphics/render_window.rb', line 209

def visible=(value)
  C::Graphics.sfRenderWindow_setVisible(@handle, value ? true : false)
end

#vsync=(enabled) ⇒ Object

Enable / disable vertical sync.



135
136
137
# File 'lib/sfml/graphics/render_window.rb', line 135

def vsync=(enabled)
  C::Graphics.sfRenderWindow_setVerticalSyncEnabled(@handle, enabled ? true : false)
end

#wait_event(timeout: nil) ⇒ Object

Block until an event arrives or timeout (a SFML::Time) elapses. Returns the next pending Event or nil on timeout. Useful for low-power apps that don't need to redraw at 60fps — wake on input.



271
272
273
274
275
276
# File 'lib/sfml/graphics/render_window.rb', line 271

def wait_event(timeout: nil)
  t = timeout || Time.zero
  ok = C::Graphics.sfRenderWindow_waitEvent(@handle, t.to_native, @event_buffer)
  return nil unless ok
  Event.from_native(@event_buffer)
end