Class: SFML::VertexBuffer
- Inherits:
-
Object
- Object
- SFML::VertexBuffer
- Defined in:
- lib/sfml/graphics/vertex_buffer.rb
Overview
GPU-resident vertex buffer. Same shape as VertexArray but the vertices live in video memory, so a draw call only ships an index/handle instead of re-uploading the geometry every frame. Useful for static meshes, large tilemaps, particle systems with mostly-static positions.
buf = SFML::VertexBuffer.new(
vertices,
primitive_type: :triangles,
usage: :static,
)
window.draw(buf)
Update later (full or partial):
buf.update(new_vertices) # full replace
buf.update(some_vertices, offset: 32) # patch in place
If the GPU doesn't support OpenGL vertex buffer objects,
SFML::VertexBuffer.available? returns false and you should
fall back to VertexArray.
Constant Summary collapse
- USAGES =
VBO usage hints in CSFML enum order.
C::Graphics::VERTEX_BUFFER_USAGES
- USAGE_INDEX =
Usage symbol → integer Hash.
USAGES.each_with_index.to_h.freeze
- PRIMITIVE_TYPES =
Primitive type symbols in
sfPrimitiveTypeorder. VertexArray::PRIMITIVE_TYPES
- PRIMITIVE_INDEX =
Primitive symbol → integer index Hash.
VertexArray::PRIMITIVE_INDEX
Instance Attribute Summary collapse
-
#handle ⇒ Object
readonly
:nodoc:.
Class Method Summary collapse
-
.available? ⇒ Boolean
Returns the self.
-
.unbind ⇒ Object
Returns the self.
Instance Method Summary collapse
-
#bind ⇒ Object
Bind this VBO as the active vertex buffer for the GL pipeline.
-
#count ⇒ Object
(also: #size, #length)
Returns the count.
-
#draw_on(target, states_ptr = nil) ⇒ Object
Returns the draw on.
-
#draw_range_on(target, first, count, states_ptr = nil) ⇒ Object
Draw a slice of this buffer instead of the whole thing.
-
#initialize(vertices = nil, count: nil, primitive_type: :points, usage: :stream) ⇒ VertexBuffer
constructor
Build a buffer either from an Array of vertices or by giving an explicit
count:to allocate empty (then fill via #update). -
#native_handle ⇒ Object
Returns the native handle.
-
#primitive_type ⇒ Object
Returns the primitive type.
-
#primitive_type=(type) ⇒ Object
Set the primitive type.
-
#update(vertices, offset: 0) ⇒ Object
Replace
vertices.lengthslots starting atoffset. -
#usage ⇒ Object
Returns the usage.
-
#usage=(value) ⇒ Object
Set the usage.
Constructor Details
#initialize(vertices = nil, count: nil, primitive_type: :points, usage: :stream) ⇒ VertexBuffer
Build a buffer either from an Array of vertices or by giving an
explicit count: to allocate empty (then fill via #update).
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 41 def initialize(vertices = nil, count: nil, primitive_type: :points, usage: :stream) n = vertices ? vertices.length : Integer(count || 0) raise ArgumentError, "give either `vertices` or `count:`" if n.zero? && vertices.nil? ptype = PRIMITIVE_INDEX.fetch(primitive_type) do raise ArgumentError, "Unknown primitive type: #{primitive_type.inspect} " \ "(expected one of #{PRIMITIVE_TYPES.inspect})" end uidx = USAGE_INDEX.fetch(usage) do raise ArgumentError, "Unknown VertexBuffer usage: #{usage.inspect} " \ "(expected one of #{USAGES.inspect})" end ptr = C::Graphics.sfVertexBuffer_create(n, ptype, uidx) raise GraphicsError, "sfVertexBuffer_create returned NULL " \ "(VBOs unavailable on this GPU?)" if ptr.null? @handle = FFI::AutoPointer.new(ptr, C::Graphics.method(:sfVertexBuffer_destroy)) update(vertices) if vertices && !vertices.empty? end |
Instance Attribute Details
#handle ⇒ Object (readonly)
:nodoc:
150 151 152 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 150 def handle @handle end |
Class Method Details
.available? ⇒ Boolean
Returns the self.
35 36 37 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 35 def self.available? C::Graphics.sfVertexBuffer_isAvailable end |
.unbind ⇒ Object
Returns the self.
131 132 133 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 131 def self.unbind C::Graphics.sfVertexBuffer_bind(nil) end |
Instance Method Details
#bind ⇒ Object
Bind this VBO as the active vertex buffer for the GL pipeline.
Useful when mixing raw GL with SFML rendering — pair with
SFML::VertexBuffer.unbind (or any other draw) to release.
125 126 127 128 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 125 def bind C::Graphics.sfVertexBuffer_bind(@handle) self end |
#count ⇒ Object Also known as: size, length
Returns the count.
65 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 65 def count = C::Graphics.sfVertexBuffer_getVertexCount(@handle) |
#draw_on(target, states_ptr = nil) ⇒ Object
Returns the draw on.
136 137 138 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 136 def draw_on(target, states_ptr = nil) # :nodoc: target._draw_native(:VertexBuffer, @handle, states_ptr) end |
#draw_range_on(target, first, count, states_ptr = nil) ⇒ Object
Draw a slice of this buffer instead of the whole thing. Useful when you've packed several meshes back-to-back and want to render one at a time.
143 144 145 146 147 148 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 143 def draw_range_on(target, first, count, states_ptr = nil) C::Graphics.public_send( :"#{target.class::CSFML_PREFIX}_drawVertexBufferRange", target.handle, @handle, Integer(first), Integer(count), states_ptr, ) end |
#native_handle ⇒ Object
Returns the native handle.
120 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 120 def native_handle = C::Graphics.sfVertexBuffer_getNativeHandle(@handle) |
#primitive_type ⇒ Object
Returns the primitive type.
70 71 72 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 70 def primitive_type PRIMITIVE_TYPES[C::Graphics.sfVertexBuffer_getPrimitiveType(@handle)] || :unknown end |
#primitive_type=(type) ⇒ Object
Set the primitive type.
75 76 77 78 79 80 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 75 def primitive_type=(type) idx = PRIMITIVE_INDEX.fetch(type) do raise ArgumentError, "Unknown primitive type: #{type.inspect}" end C::Graphics.sfVertexBuffer_setPrimitiveType(@handle, idx) end |
#update(vertices, offset: 0) ⇒ Object
Replace vertices.length slots starting at offset. Pass an
array longer than the buffer to grow it (CSFML expands when
offset==0 and length > current).
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 98 def update(vertices, offset: 0) n = vertices.length buf = FFI::MemoryPointer.new(C::Graphics::Vertex, n) vertices.each_with_index do |v, i| slot = C::Graphics::Vertex.new(buf + i * C::Graphics::Vertex.size) slot[:position][:x] = v.position.x.to_f slot[:position][:y] = v.position.y.to_f slot[:color][:r] = v.color.r slot[:color][:g] = v.color.g slot[:color][:b] = v.color.b slot[:color][:a] = v.color.a slot[:tex_coords][:x] = v.tex_coords.x.to_f slot[:tex_coords][:y] = v.tex_coords.y.to_f end ok = C::Graphics.sfVertexBuffer_update(@handle, buf, n, Integer(offset)) raise GraphicsError, "sfVertexBuffer_update failed " \ "(buffer too small or driver rejected the upload?)" unless ok self end |
#usage ⇒ Object
Returns the usage.
83 84 85 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 83 def usage USAGES[C::Graphics.sfVertexBuffer_getUsage(@handle)] || :unknown end |
#usage=(value) ⇒ Object
Set the usage.
88 89 90 91 92 93 |
# File 'lib/sfml/graphics/vertex_buffer.rb', line 88 def usage=(value) idx = USAGE_INDEX.fetch(value) do raise ArgumentError, "Unknown VertexBuffer usage: #{value.inspect}" end C::Graphics.sfVertexBuffer_setUsage(@handle, idx) end |