0
# Array Operations
1
2
Unified array handling system providing seamless integration between OpenGL and various Python array types including NumPy arrays, Python lists, ctypes arrays, and buffer objects. Includes high-performance Vertex Buffer Object (VBO) support for modern graphics programming.
3
4
## Capabilities
5
6
### Vertex Buffer Objects (VBO)
7
8
High-performance buffer objects for storing vertex data in GPU memory with automatic memory management and context-aware binding.
9
10
```python { .api }
11
class VBO:
12
"""
13
Vertex Buffer Object wrapper providing high-performance vertex data storage.
14
15
Usage:
16
vbo = VBO(data)
17
with vbo:
18
glVertexPointer(3, GL_FLOAT, 0, vbo)
19
glDrawArrays(GL_TRIANGLES, 0, len(data))
20
"""
21
22
def __init__(self, data, usage=GL_STATIC_DRAW, target=GL_ARRAY_BUFFER):
23
"""
24
Create VBO from array data.
25
26
Parameters:
27
- data: Array-like data (NumPy array, list, etc.)
28
- usage: Buffer usage hint (GL_STATIC_DRAW, GL_DYNAMIC_DRAW, GL_STREAM_DRAW)
29
- target: Buffer target (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER)
30
"""
31
32
def bind(self):
33
"""Bind VBO to its target."""
34
35
def unbind(self):
36
"""Unbind VBO from its target."""
37
38
def delete(self):
39
"""Delete VBO and free GPU memory."""
40
41
def copy(self, array):
42
"""
43
Copy data to VBO.
44
45
Parameters:
46
- array: New data to copy to buffer
47
"""
48
49
def __enter__(self):
50
"""Context manager entry - binds VBO."""
51
52
def __exit__(self, exc_type, exc_val, exc_tb):
53
"""Context manager exit - unbinds VBO."""
54
55
def __add__(self, offset: int):
56
"""
57
Create VBO offset for sub-arrays.
58
59
Parameters:
60
- offset: Byte offset into buffer
61
62
Returns:
63
VBOOffset object
64
"""
65
66
@property
67
def data(self):
68
"""Get original array data."""
69
70
@property
71
def size(self) -> int:
72
"""Get buffer size in bytes."""
73
74
@property
75
def target(self) -> int:
76
"""Get buffer target."""
77
78
@property
79
def usage(self) -> int:
80
"""Get buffer usage hint."""
81
82
class VBOOffset:
83
"""
84
Represents an offset into a VBO for rendering sub-arrays.
85
86
Usage:
87
vertices = VBO(vertex_data)
88
normals = vertices + 12 # Offset 12 bytes into buffer
89
with vertices:
90
glVertexPointer(3, GL_FLOAT, 24, vertices)
91
glNormalPointer(GL_FLOAT, 24, normals)
92
"""
93
94
def __init__(self, vbo: VBO, offset: int):
95
"""
96
Create VBO offset.
97
98
Parameters:
99
- vbo: Parent VBO object
100
- offset: Byte offset into buffer
101
"""
102
```
103
104
### Array Format Handling
105
106
Automatic detection and conversion between different array formats with plugin architecture for extensibility.
107
108
```python { .api }
109
class ArrayDatatype:
110
"""
111
Base class for array format handlers providing unified interface
112
to different array types (NumPy, ctypes, Python lists, etc.).
113
"""
114
115
@classmethod
116
def from_param(cls, value):
117
"""
118
Convert value to appropriate array representation.
119
120
Parameters:
121
- value: Input data in any supported format
122
123
Returns:
124
Converted array data
125
"""
126
127
@classmethod
128
def dataPointer(cls, value):
129
"""
130
Get memory pointer to array data.
131
132
Parameters:
133
- value: Array data
134
135
Returns:
136
Memory pointer suitable for OpenGL functions
137
"""
138
139
@classmethod
140
def arraySize(cls, value) -> int:
141
"""
142
Get array size in bytes.
143
144
Parameters:
145
- value: Array data
146
147
Returns:
148
Size in bytes
149
"""
150
151
@classmethod
152
def arrayByteCount(cls, value) -> int:
153
"""Get total byte count of array."""
154
155
@classmethod
156
def unitSize(cls, value) -> int:
157
"""Get size of single array element in bytes."""
158
159
@classmethod
160
def dimensions(cls, value) -> tuple:
161
"""
162
Get array dimensions.
163
164
Returns:
165
Tuple of dimension sizes
166
"""
167
168
def asArray(value, typeCode=None):
169
"""
170
Convert value to array format suitable for OpenGL.
171
172
Parameters:
173
- value: Input data in any supported format
174
- typeCode: Optional type specification
175
176
Returns:
177
Array in appropriate format for OpenGL operations
178
"""
179
```
180
181
### NumPy Integration
182
183
Seamless NumPy array support with automatic type mapping and memory layout handling.
184
185
```python { .api }
186
# NumPy arrays are automatically supported
187
import numpy as np
188
189
# Create vertex data
190
vertices = np.array([
191
[0.0, 1.0, 0.0],
192
[-1.0, -1.0, 0.0],
193
[1.0, -1.0, 0.0]
194
], dtype=np.float32)
195
196
# Use directly with OpenGL functions
197
glVertexPointer(3, GL_FLOAT, 0, vertices)
198
199
# Or with VBO for better performance
200
vbo = VBO(vertices)
201
with vbo:
202
glVertexPointer(3, GL_FLOAT, 0, vbo)
203
glDrawArrays(GL_TRIANGLES, 0, len(vertices))
204
```
205
206
### Python List Support
207
208
Native Python list and tuple support with automatic conversion to appropriate OpenGL formats.
209
210
```python { .api }
211
# Python lists work automatically
212
vertices = [
213
[0.0, 1.0, 0.0],
214
[-1.0, -1.0, 0.0],
215
[1.0, -1.0, 0.0]
216
]
217
218
colors = [
219
[1.0, 0.0, 0.0], # Red
220
[0.0, 1.0, 0.0], # Green
221
[0.0, 0.0, 1.0] # Blue
222
]
223
224
# Use directly with OpenGL
225
glVertexPointer(3, GL_FLOAT, 0, vertices)
226
glColorPointer(3, GL_FLOAT, 0, colors)
227
```
228
229
### ctypes Integration
230
231
Direct ctypes array support for low-level control and C library integration.
232
233
```python { .api }
234
import ctypes
235
236
# ctypes arrays
237
FloatArray = ctypes.c_float * 9
238
vertex_array = FloatArray(
239
0.0, 1.0, 0.0, # Vertex 1
240
-1.0, -1.0, 0.0, # Vertex 2
241
1.0, -1.0, 0.0 # Vertex 3
242
)
243
244
# Use with OpenGL functions
245
glVertexPointer(3, GL_FLOAT, 0, vertex_array)
246
```
247
248
### Buffer Protocol Support
249
250
Support for Python buffer protocol objects including bytes, bytearray, and memoryview.
251
252
```python { .api }
253
# Buffer objects supported
254
data = bytearray(36) # 9 floats * 4 bytes each
255
buffer_view = memoryview(data)
256
257
# Can be used with OpenGL functions
258
glBufferData(GL_ARRAY_BUFFER, len(data), data, GL_STATIC_DRAW)
259
```
260
261
### Memory Management
262
263
Automatic memory management with optional pointer storage for safety and performance control.
264
265
```python { .api }
266
# Configuration flags affecting array handling
267
import OpenGL
268
269
# Prevent data copying (raises CopyError if copy would occur)
270
OpenGL.ERROR_ON_COPY = True
271
272
# Store array pointers to prevent garbage collection issues
273
OpenGL.STORE_POINTERS = True # Default: True
274
275
# Enable/disable size checking
276
OpenGL.ARRAY_SIZE_CHECKING = True # Default: True
277
```
278
279
### VBO Utilities
280
281
Helper functions for VBO management and memory mapping.
282
283
```python { .api }
284
def mapVBO(vbo: VBO, access=GL_READ_WRITE):
285
"""
286
Map VBO memory for direct CPU access.
287
288
Parameters:
289
- vbo: VBO object to map
290
- access: Access mode (GL_READ_ONLY, GL_WRITE_ONLY, GL_READ_WRITE)
291
292
Returns:
293
Memory pointer for direct access
294
295
Usage:
296
with vbo:
297
ptr = mapVBO(vbo, GL_WRITE_ONLY)
298
# Modify data through ptr
299
glUnmapBuffer(vbo.target)
300
"""
301
302
class VBOHandler:
303
"""Format handler for VBO objects in the array system."""
304
```
305
306
### Format Handler System
307
308
Plugin architecture for supporting additional array formats.
309
310
```python { .api }
311
class FormatHandler:
312
"""
313
Base class for array format plugins.
314
Allows registration of handlers for custom array types.
315
"""
316
317
def __init__(self, name: str, module: str, types: list,
318
isOutput: bool = False):
319
"""
320
Register format handler.
321
322
Parameters:
323
- name: Handler name
324
- module: Python module containing handler
325
- types: List of type names this handler supports
326
- isOutput: Whether handler can produce output arrays
327
"""
328
329
# Pre-registered handlers
330
handlers = {
331
'numpy': 'numpy.ndarray, numpy.core.memmap.memmap, numpy scalar types',
332
'lists': 'list, tuple',
333
'ctypes': 'ctypes arrays, parameters, pointers',
334
'strings': 'str, bytes, unicode (Python 2)',
335
'numbers': 'int, float, long (Python 2)',
336
'buffers': 'buffer protocol objects (bytearray, memoryview)',
337
'vbo': 'VBO, VBOOffset objects'
338
}
339
```
340
341
## Usage Examples
342
343
### Basic VBO Usage
344
```python
345
import numpy as np
346
from OpenGL.GL import *
347
from OpenGL.arrays import vbo
348
349
# Create vertex data
350
vertices = np.array([
351
[-1.0, -1.0, 0.0],
352
[ 1.0, -1.0, 0.0],
353
[ 0.0, 1.0, 0.0]
354
], dtype=np.float32)
355
356
# Create VBO
357
vertex_buffer = vbo.VBO(vertices)
358
359
# Use in render loop
360
with vertex_buffer:
361
glEnableClientState(GL_VERTEX_ARRAY)
362
glVertexPointer(3, GL_FLOAT, 0, vertex_buffer)
363
glDrawArrays(GL_TRIANGLES, 0, 3)
364
glDisableClientState(GL_VERTEX_ARRAY)
365
```
366
367
### Interleaved Vertex Data
368
```python
369
# Interleaved vertex and color data
370
# Format: [x, y, z, r, g, b, x, y, z, r, g, b, ...]
371
interleaved_data = np.array([
372
# Vertex 1: position + color
373
-1.0, -1.0, 0.0, 1.0, 0.0, 0.0,
374
# Vertex 2: position + color
375
1.0, -1.0, 0.0, 0.0, 1.0, 0.0,
376
# Vertex 3: position + color
377
0.0, 1.0, 0.0, 0.0, 0.0, 1.0
378
], dtype=np.float32)
379
380
stride = 6 * 4 # 6 floats * 4 bytes per float
381
vertex_buffer = vbo.VBO(interleaved_data)
382
383
with vertex_buffer:
384
glEnableClientState(GL_VERTEX_ARRAY)
385
glEnableClientState(GL_COLOR_ARRAY)
386
387
# Vertices start at offset 0
388
glVertexPointer(3, GL_FLOAT, stride, vertex_buffer)
389
390
# Colors start at offset 12 bytes (3 floats * 4 bytes)
391
color_offset = vertex_buffer + 12
392
glColorPointer(3, GL_FLOAT, stride, color_offset)
393
394
glDrawArrays(GL_TRIANGLES, 0, 3)
395
396
glDisableClientState(GL_COLOR_ARRAY)
397
glDisableClientState(GL_VERTEX_ARRAY)
398
```
399
400
### Dynamic Buffer Updates
401
```python
402
# Create dynamic VBO
403
dynamic_data = np.zeros((100, 3), dtype=np.float32)
404
vertex_buffer = vbo.VBO(dynamic_data, usage=GL_DYNAMIC_DRAW)
405
406
# Update data each frame
407
def update_vertices(time):
408
# Modify vertex positions based on time
409
for i in range(100):
410
dynamic_data[i] = [
411
np.sin(time + i * 0.1),
412
np.cos(time + i * 0.1),
413
0.0
414
]
415
416
# Copy updated data to VBO
417
vertex_buffer.copy(dynamic_data)
418
419
# In render loop
420
update_vertices(current_time)
421
with vertex_buffer:
422
glVertexPointer(3, GL_FLOAT, 0, vertex_buffer)
423
glDrawArrays(GL_POINTS, 0, 100)
424
```
425
426
## Constants
427
428
### VBO Usage Hints
429
```python { .api }
430
GL_STATIC_DRAW: int # Data rarely changes
431
GL_DYNAMIC_DRAW: int # Data changes frequently
432
GL_STREAM_DRAW: int # Data changes every frame
433
```
434
435
### VBO Targets
436
```python { .api }
437
GL_ARRAY_BUFFER: int # Vertex attribute data
438
GL_ELEMENT_ARRAY_BUFFER: int # Index data
439
```
440
441
### Memory Access Modes
442
```python { .api }
443
GL_READ_ONLY: int
444
GL_WRITE_ONLY: int
445
GL_READ_WRITE: int
446
```