Skip to content

Commit 91345d9

Browse files
authored
GL module docs and docstrings (#2300)
* Initial work + doc revamp * enums * framebuffer * geometry * glsl * framebuffer and program docstrings * vertex_array * add utils to docs * uniform * types * texture * query * Lingering issues * Various docstring improvements. * Fix Buffer.orphan
1 parent c91f53b commit 91345d9

26 files changed

+1273
-741
lines changed

arcade/gl/__init__.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"""
2-
A wrapper over OpenGL 3.3 core making OpenGL more reasonable to work with and easier to learn.
3-
The API is based on `ModernGL <https://github.com/moderngl/moderngl>`_ implementing
4-
a subset of the features.
5-
We use pyglet's OpenGL bindings based on ctypes.
2+
A wrapper over OpenGL 3.3 core making OpenGL more reasonable to work with and easier
3+
to learn. The API is based on `ModernGL <https://github.com/moderngl/moderngl>`_
4+
implementing a subset of the features. We use pyglet's OpenGL bindings based on ctypes.
65
76
Creating OpenGL resources such as buffers, framebuffers, programs (shaders) and textures
87
should be done through methods in a context.
98
10-
* Arcade users should access :py:attr:`arcade.Window.ctx` exposing an :py:class:`arcade.ArcadeContext`
9+
* Arcade users should access :py:attr:`arcade.Window.ctx` exposing an
10+
:py:class:`arcade.ArcadeContext`
1111
* Pyglet users can instantiate an :py:class:`arcade.gl.Context` for the window or
1212
extend this class with more features if needed.
1313
@@ -17,12 +17,11 @@
1717

1818
from __future__ import annotations
1919

20-
# flake8: noqa
2120
from .context import Context
2221
from .types import BufferDescription
2322
from .compute_shader import ComputeShader
2423
from .exceptions import ShaderException
25-
from .enums import *
24+
from .enums import * # noqa
2625
from .buffer import Buffer
2726
from .vertex_array import Geometry, VertexArray
2827
from .texture import Texture2D

arcade/gl/buffer.py

Lines changed: 72 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from .utils import data_to_ctypes
1212

13-
if TYPE_CHECKING: # handle import cycle caused by type hinting
13+
if TYPE_CHECKING:
1414
from arcade.gl import Context
1515

1616

@@ -30,12 +30,16 @@ class Buffer:
3030
3131
.. warning:: Buffer objects should be created using :py:meth:`arcade.gl.Context.buffer`
3232
33-
:param ctx: The context this buffer belongs to
34-
:param data: The data this buffer should contain.
35-
It can be a ``bytes`` instance or any
36-
object supporting the buffer protocol.
37-
:param reserve: Create a buffer of a specific byte size
38-
:param usage: A hit of this buffer is ``static`` or ``dynamic`` (can mostly be ignored)
33+
Args:
34+
ctx:
35+
The context this buffer belongs to
36+
data:
37+
The data this buffer should contain. It can be a ``bytes`` instance or any
38+
object supporting the buffer protocol.
39+
reserve:
40+
Create a buffer of a specific byte size
41+
usage:
42+
A hit of this buffer is ``static`` or ``dynamic`` (can mostly be ignored)
3943
"""
4044

4145
__slots__ = "_ctx", "_glo", "_size", "_usage", "__weakref__"
@@ -47,7 +51,7 @@ class Buffer:
4751

4852
def __init__(
4953
self,
50-
ctx: "Context",
54+
ctx: Context,
5155
data: BufferProtocol | None = None,
5256
reserve: int = 0,
5357
usage: str = "static",
@@ -93,38 +97,40 @@ def __del__(self):
9397

9498
@property
9599
def size(self) -> int:
96-
"""
97-
The byte size of the buffer.
98-
"""
100+
"""The byte size of the buffer."""
99101
return self._size
100102

101103
@property
102104
def ctx(self) -> "Context":
103-
"""
104-
The context this resource belongs to.
105-
"""
105+
"""The context this resource belongs to."""
106106
return self._ctx
107107

108108
@property
109109
def glo(self) -> gl.GLuint:
110-
"""
111-
The OpenGL resource id
112-
"""
110+
"""The OpenGL resource id."""
113111
return self._glo
114112

115-
def delete(self):
113+
def delete(self) -> None:
116114
"""
117115
Destroy the underlying OpenGL resource.
118-
Don't use this unless you know exactly what you are doing.
116+
117+
.. warning:: Don't use this unless you know exactly what you are doing.
119118
"""
120119
Buffer.delete_glo(self._ctx, self._glo)
121120
self._glo.value = 0
122121

123122
@staticmethod
124-
def delete_glo(ctx: "Context", glo: gl.GLuint):
123+
def delete_glo(ctx: Context, glo: gl.GLuint):
125124
"""
126125
Release/delete open gl buffer.
126+
127127
This is automatically called when the object is garbage collected.
128+
129+
Args:
130+
ctx:
131+
The context the buffer belongs to
132+
glo:
133+
The OpenGL buffer id
128134
"""
129135
# If we have no context, then we are shutting down, so skip this
130136
if gl.current_context is None:
@@ -139,8 +145,11 @@ def delete_glo(ctx: "Context", glo: gl.GLuint):
139145
def read(self, size: int = -1, offset: int = 0) -> bytes:
140146
"""Read data from the buffer.
141147
142-
:param size: The bytes to read. -1 means the entire buffer (default)
143-
:param offset: Byte read offset
148+
Args:
149+
size:
150+
The bytes to read. -1 means the entire buffer (default)
151+
offset:
152+
Byte read offset
144153
"""
145154
if size == -1:
146155
size = self._size - offset
@@ -183,9 +192,12 @@ def write(self, data: BufferProtocol, offset: int = 0):
183192
truncated to fit. If the supplied data is smaller than the
184193
buffer, the remaining bytes will be left unchanged.
185194
186-
:param data: The byte data to write. This can be bytes or any object
187-
supporting the buffer protocol.
188-
:param offset: The byte offset
195+
Args:
196+
data:
197+
The byte data to write. This can be bytes or any object
198+
supporting the buffer protocol.
199+
offset:
200+
The byte offset
189201
"""
190202
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._glo)
191203
size, data = data_to_ctypes(data)
@@ -195,13 +207,18 @@ def write(self, data: BufferProtocol, offset: int = 0):
195207
raise ValueError("Attempting to write negative number bytes to buffer")
196208
gl.glBufferSubData(gl.GL_ARRAY_BUFFER, gl.GLintptr(offset), size, data)
197209

198-
def copy_from_buffer(self, source: "Buffer", size=-1, offset=0, source_offset=0):
199-
"""Copy data into this buffer from another buffer
200-
201-
:param source: The buffer to copy from
202-
:param size: The amount of bytes to copy
203-
:param offset: The byte offset to write the data in this buffer
204-
:param source_offset: The byte offset to read from the source buffer
210+
def copy_from_buffer(self, source: Buffer, size=-1, offset=0, source_offset=0):
211+
"""Copy data into this buffer from another buffer.
212+
213+
Args:
214+
source:
215+
The buffer to copy from
216+
size:
217+
The amount of bytes to copy
218+
offset:
219+
The byte offset to write the data in this buffer
220+
source_offset:
221+
The byte offset to read from the source buffer
205222
"""
206223
# Read the entire source buffer into this buffer
207224
if size == -1:
@@ -232,13 +249,17 @@ def orphan(self, size: int = -1, double: bool = False):
232249
If the current buffer is busy in rendering operations
233250
it will be deallocated by OpenGL when completed.
234251
235-
:param size: New size of buffer. -1 will retain the current size.
236-
:param double: Is passed in with `True` the buffer size will be doubled
252+
Args:
253+
size: (optional)
254+
New size of buffer. -1 will retain the current size.
255+
Takes precedence over ``double`` parameter if specified.
256+
double (optional):
257+
Is passed in with `True` the buffer size will be doubled
258+
from its current size.
237259
"""
238-
if size > -1:
260+
if size > 0:
239261
self._size = size
240-
241-
if double:
262+
elif double is True:
242263
self._size *= 2
243264

244265
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._glo)
@@ -248,9 +269,13 @@ def bind_to_uniform_block(self, binding: int = 0, offset: int = 0, size: int = -
248269
"""Bind this buffer to a uniform block location.
249270
In most cases it will be sufficient to only provide a binding location.
250271
251-
:param binding: The binding location
252-
:param offset: byte offset
253-
:param size: size of the buffer to bind.
272+
Args:
273+
binding:
274+
The binding location
275+
offset:
276+
Byte offset
277+
size:
278+
Size of the buffer to bind.
254279
"""
255280
if size < 0:
256281
size = self.size
@@ -261,9 +286,13 @@ def bind_to_storage_buffer(self, *, binding=0, offset=0, size=-1):
261286
"""
262287
Bind this buffer as a shader storage buffer.
263288
264-
:param binding: The binding location
265-
:param offset: Byte offset in the buffer
266-
:param size: The size in bytes. The entire buffer will be mapped by default.
289+
Args:
290+
binding:
291+
The binding location
292+
offset:
293+
Byte offset in the buffer
294+
size:
295+
The size in bytes. The entire buffer will be mapped by default.
267296
"""
268297
if size < 0:
269298
size = self.size

arcade/gl/compute_shader.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,15 @@
2525
class ComputeShader:
2626
"""
2727
A higher level wrapper for an OpenGL compute shader.
28+
29+
Args:
30+
ctx:
31+
The context this shader belongs to.
32+
glsl_source:
33+
The GLSL source code for the compute shader.
2834
"""
2935

30-
def __init__(self, ctx: "Context", glsl_source: str) -> None:
36+
def __init__(self, ctx: Context, glsl_source: str) -> None:
3137
self._ctx = ctx
3238
self._source = glsl_source
3339
self._uniforms: dict[str, UniformBlock | Uniform] = dict()
@@ -95,7 +101,7 @@ def glo(self) -> int:
95101
"""The name/id of the OpenGL resource"""
96102
return self._glo
97103

98-
def use(self):
104+
def _use(self) -> None:
99105
"""
100106
Use/activate the compute shader.
101107
@@ -105,7 +111,7 @@ def use(self):
105111
since ``run()`` already does this for you.
106112
"""
107113
gl.glUseProgram(self._glo)
108-
# self._ctx.active_program = self
114+
self._ctx.active_program = self
109115

110116
def run(self, group_x=1, group_y=1, group_z=1) -> None:
111117
"""
@@ -128,11 +134,12 @@ def run(self, group_x=1, group_y=1, group_z=1) -> None:
128134
a size for a dimension or uses ``1`` as size you don't have to supply
129135
this parameter.
130136
131-
:param group_x: The number of work groups to be launched in the X dimension.
132-
:param group_y: The number of work groups to be launched in the y dimension.
133-
:param group_z: The number of work groups to be launched in the z dimension.
137+
Args:
138+
group_x: The number of work groups to be launched in the X dimension.
139+
group_y: The number of work groups to be launched in the y dimension.
140+
group_z: The number of work groups to be launched in the z dimension.
134141
"""
135-
self.use()
142+
self._use()
136143
gl.glDispatchCompute(group_x, group_y, group_z)
137144

138145
def __getitem__(self, item) -> Uniform | UniformBlock:
@@ -164,18 +171,25 @@ def __del__(self):
164171
if self._ctx.gc_mode == "context_gc" and self._glo > 0:
165172
self._ctx.objects.append(self)
166173

167-
def delete(self):
174+
def delete(self) -> None:
168175
"""
169176
Destroy the internal compute shader object.
177+
170178
This is normally not necessary, but depends on the
171-
garbage collection more configured in the context.
179+
garbage collection configured in the context.
172180
"""
173181
ComputeShader.delete_glo(self._ctx, self._glo)
174182
self._glo = 0
175183

176184
@staticmethod
177185
def delete_glo(ctx, prog_id):
178-
"""Low level method for destroying a compute shader by id"""
186+
"""
187+
Low level method for destroying a compute shader by id.
188+
189+
Args:
190+
ctx: The context this program belongs to.
191+
prog_id: The OpenGL id of the program.
192+
"""
179193
# Check to see if the context was already cleaned up from program
180194
# shut down. If so, we don't need to delete the shaders.
181195
if gl.current_context is None:

0 commit comments

Comments
 (0)