Class: SFML::VertexArray

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/sfml/graphics/vertex_array.rb

Overview

Batched geometry: a single CSFML draw call shipping many vertices to the GPU at once. This is how you draw thousands of particles, custom meshes, or tile maps without the per-shape overhead.

va = SFML::VertexArray.new(:triangles)
va << SFML::Vertex.new([100, 100], color: SFML::Color.red)
va << SFML::Vertex.new([200, 100], color: SFML::Color.green)
va << SFML::Vertex.new([150, 200], color: SFML::Color.blue)
window.draw(va)

Primitive types control how vertices form geometry:

:points          one isolated point per vertex
:lines           pairs of vertices form line segments
:line_strip      consecutive vertices form a chain of segments
:triangles       triples form independent triangles
:triangle_strip  each new vertex extends the strip
:triangle_fan    every vertex shares a fan-out with vertex 0

Constant Summary collapse

PRIMITIVE_TYPES =

Order matches sfPrimitiveType in CSFML/Graphics/PrimitiveType.h.

%i[points lines line_strip triangles triangle_strip triangle_fan].freeze
PRIMITIVE_INDEX =

Primitive symbol → integer index Hash.

PRIMITIVE_TYPES.each_with_index.to_h.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(primitive_type = :points, vertices = nil) ⇒ VertexArray

Build an empty VertexArray. primitive_type chooses how vertices form geometry (see class doc). vertices is an optional initial list — same as calling #append after.

Raises:



30
31
32
33
34
35
36
37
# File 'lib/sfml/graphics/vertex_array.rb', line 30

def initialize(primitive_type = :points, vertices = nil)
  ptr = C::Graphics.sfVertexArray_create
  raise GraphicsError, "sfVertexArray_create returned NULL" if ptr.null?
  @handle = FFI::AutoPointer.new(ptr, C::Graphics.method(:sfVertexArray_destroy))

  self.primitive_type = primitive_type
  vertices&.each { |v| append(v) }
end

Instance Attribute Details

#handle ⇒ Object (readonly)

:nodoc:



144
145
146
# File 'lib/sfml/graphics/vertex_array.rb', line 144

def handle
  @handle
end

Instance Method Details

#[](index) ⇒ Object

Read a vertex by index, or nil if out of range. Returns a fresh SFML::Vertex copy — mutate via va[i] = new_vertex to write back, not through the returned object.



86
87
88
89
90
91
# File 'lib/sfml/graphics/vertex_array.rb', line 86

def [](index)
  i = Integer(index)
  return nil if i < 0 || i >= size
  ptr = C::Graphics.sfVertexArray_getVertex(@handle, i)
  Vertex.from_native(C::Graphics::Vertex.new(ptr))
end

#[]=(index, vertex) ⇒ Object

In-place vertex replacement. Bounds-checked on the Ruby side because CSFML's getter aborts the process for out-of-range.

Raises:

  • (IndexError)


95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/sfml/graphics/vertex_array.rb', line 95

def []=(index, vertex)
  i = Integer(index)
  # CSFML's sfVertexArray_getVertex aborts the process on out-of-range
  # access (it asserts), so we have to bounds-check on the Ruby side.
  raise IndexError, "vertex index #{i} out of range (size: #{size})" if i < 0 || i >= size

  ptr = C::Graphics.sfVertexArray_getVertex(@handle, i)
  cv = C::Graphics::Vertex.new(ptr)
  cv[:position][:x]   = vertex.position.x.to_f
  cv[:position][:y]   = vertex.position.y.to_f
  cv[:color][:r]      = vertex.color.r
  cv[:color][:g]      = vertex.color.g
  cv[:color][:b]      = vertex.color.b
  cv[:color][:a]      = vertex.color.a
  cv[:tex_coords][:x] = vertex.tex_coords.x.to_f
  cv[:tex_coords][:y] = vertex.tex_coords.y.to_f
  vertex
end

#append(vertex) ⇒ Object Also known as: <<

Add a vertex at the end. Returns self so calls can chain (va << v1 << v2).



77
78
79
80
# File 'lib/sfml/graphics/vertex_array.rb', line 77

def append(vertex)
  C::Graphics.sfVertexArray_append(@handle, vertex.to_native)
  self
end

#bounds ⇒ Object

Axis-aligned bounding box of all current vertices, as a Rect.



123
124
125
# File 'lib/sfml/graphics/vertex_array.rb', line 123

def bounds
  Rect.from_native(C::Graphics.sfVertexArray_getBounds(@handle))
end

#clear ⇒ Object

Remove all vertices. Chainable.



63
64
65
66
# File 'lib/sfml/graphics/vertex_array.rb', line 63

def clear
  C::Graphics.sfVertexArray_clear(@handle)
  self
end

#draw_on(target, states_ptr = nil) ⇒ Object

Returns the draw on.



128
129
130
# File 'lib/sfml/graphics/vertex_array.rb', line 128

def draw_on(target, states_ptr = nil) # :nodoc:
  target._draw_native(:VertexArray, @handle, states_ptr)
end

#dup ⇒ Object Also known as: clone

Independent copy — vertices duplicated, future appends to one don't affect the other.

Raises:



134
135
136
137
138
139
140
141
# File 'lib/sfml/graphics/vertex_array.rb', line 134

def dup
  ptr = C::Graphics.sfVertexArray_copy(@handle)
  raise GraphicsError, "sfVertexArray_copy returned NULL" if ptr.null?
  copy = self.class.allocate
  copy.instance_variable_set(:@handle,
    FFI::AutoPointer.new(ptr, C::Graphics.method(:sfVertexArray_destroy)))
  copy
end

#each ⇒ Object

Yield every vertex in order. Returns an Enumerator without a block — makes va.map, va.select, etc. work via Enumerable.



116
117
118
119
120
# File 'lib/sfml/graphics/vertex_array.rb', line 116

def each
  return enum_for(:each) unless block_given?
  size.times { |i| yield self[i] }
  self
end

#empty? ⇒ Boolean

true if there are no vertices.

Returns:

  • (Boolean)


60
# File 'lib/sfml/graphics/vertex_array.rb', line 60

def empty? = size.zero?

#primitive_type ⇒ Object

Current primitive type as a Symbol (one of PRIMITIVE_TYPES).



40
41
42
# File 'lib/sfml/graphics/vertex_array.rb', line 40

def primitive_type
  PRIMITIVE_TYPES[C::Graphics.sfVertexArray_getPrimitiveType(@handle)] || :unknown
end

#primitive_type=(type) ⇒ Object

Change the primitive type. Raises ArgumentError for unknown symbols.



46
47
48
49
50
51
52
# File 'lib/sfml/graphics/vertex_array.rb', line 46

def primitive_type=(type)
  code = PRIMITIVE_INDEX.fetch(type) do
    raise ArgumentError,
          "Unknown primitive type: #{type.inspect}. Expected one of: #{PRIMITIVE_TYPES.inspect}"
  end
  C::Graphics.sfVertexArray_setPrimitiveType(@handle, code)
end

#resize(n) ⇒ Object

Resize to exactly n vertices, allocating defaults if growing. Useful when you want to index-assign into the array directly.



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

def resize(n)
  C::Graphics.sfVertexArray_resize(@handle, Integer(n))
  self
end

#size ⇒ Object Also known as: length, count

Number of vertices currently in the array.



55
# File 'lib/sfml/graphics/vertex_array.rb', line 55

def size = C::Graphics.sfVertexArray_getVertexCount(@handle)