ncca-ngl 0.3.4__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ncca/ngl/PrimData/pack_arrays.py +2 -3
- ncca/ngl/__init__.py +3 -4
- ncca/ngl/base_mesh.py +28 -20
- ncca/ngl/image.py +1 -3
- ncca/ngl/mat2.py +79 -53
- ncca/ngl/mat3.py +104 -185
- ncca/ngl/mat4.py +144 -309
- ncca/ngl/prim_data.py +42 -36
- ncca/ngl/primitives.py +2 -2
- ncca/ngl/pyside_event_handling_mixin.py +0 -108
- ncca/ngl/quaternion.py +69 -36
- ncca/ngl/shader.py +0 -116
- ncca/ngl/shader_program.py +94 -117
- ncca/ngl/texture.py +5 -2
- ncca/ngl/util.py +7 -0
- ncca/ngl/vec2.py +58 -292
- ncca/ngl/vec2_array.py +79 -28
- ncca/ngl/vec3.py +59 -340
- ncca/ngl/vec3_array.py +76 -23
- ncca/ngl/vec4.py +90 -190
- ncca/ngl/vec4_array.py +78 -27
- ncca/ngl/vector_base.py +542 -0
- ncca/ngl/webgpu/__init__.py +20 -0
- ncca/ngl/webgpu/__main__.py +640 -0
- ncca/ngl/webgpu/__main__.py.backup +640 -0
- ncca/ngl/webgpu/base_webgpu_pipeline.py +354 -0
- ncca/ngl/webgpu/custom_shader_pipeline.py +288 -0
- ncca/ngl/webgpu/instanced_geometry_pipeline.py +594 -0
- ncca/ngl/webgpu/line_pipeline.py +405 -0
- ncca/ngl/webgpu/pipeline_factory.py +190 -0
- ncca/ngl/webgpu/pipeline_shaders.py +497 -0
- ncca/ngl/webgpu/point_list_pipeline.py +349 -0
- ncca/ngl/webgpu/point_pipeline.py +336 -0
- ncca/ngl/webgpu/triangle_pipeline.py +419 -0
- ncca/ngl/webgpu/webgpu_constants.py +31 -0
- ncca/ngl/webgpu/webgpu_widget.py +322 -0
- ncca/ngl/webgpu/wip/REFACTORING_SUMMARY.md +82 -0
- ncca/ngl/webgpu/wip/UNIFIED_SYSTEM.md +314 -0
- ncca/ngl/webgpu/wip/buffer_manager.py +396 -0
- ncca/ngl/webgpu/wip/pipeline_config.py +463 -0
- ncca/ngl/webgpu/wip/shader_constants.py +328 -0
- ncca/ngl/webgpu/wip/shader_templates.py +563 -0
- ncca/ngl/webgpu/wip/unified_examples.py +390 -0
- ncca/ngl/webgpu/wip/unified_factory.py +449 -0
- ncca/ngl/webgpu/wip/unified_pipeline.py +469 -0
- ncca/ngl/widgets/__init__.py +18 -2
- ncca/ngl/widgets/__main__.py +2 -1
- ncca/ngl/widgets/lookatwidget.py +2 -1
- ncca/ngl/widgets/mat4widget.py +2 -2
- ncca/ngl/widgets/vec2widget.py +1 -1
- ncca/ngl/widgets/vec3widget.py +1 -0
- {ncca_ngl-0.3.4.dist-info → ncca_ngl-0.5.0.dist-info}/METADATA +3 -2
- ncca_ngl-0.5.0.dist-info/RECORD +105 -0
- ncca/ngl/widgets/transformation_widget.py +0 -299
- ncca_ngl-0.3.4.dist-info/RECORD +0 -82
- {ncca_ngl-0.3.4.dist-info → ncca_ngl-0.5.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Generic triangle rendering pipeline for WebGPU.
|
|
3
|
+
Handles triangle rendering with customizable colors, projection, and topology.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Optional, Tuple, Union
|
|
7
|
+
|
|
8
|
+
import numpy as np
|
|
9
|
+
import wgpu
|
|
10
|
+
|
|
11
|
+
from .base_webgpu_pipeline import BaseWebGPUPipeline
|
|
12
|
+
from .pipeline_shaders import (
|
|
13
|
+
TRIANGLE_SHADER_MULTI_COLOURED,
|
|
14
|
+
TRIANGLE_SHADER_SINGLE_COLOUR,
|
|
15
|
+
)
|
|
16
|
+
from .webgpu_constants import NGLToWebGPU
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class BaseTrianglePipeline(BaseWebGPUPipeline):
|
|
20
|
+
"""Base class for triangle rendering pipelines."""
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
device: wgpu.GPUDevice,
|
|
25
|
+
data_type: str = "Vec3",
|
|
26
|
+
texture_format: wgpu.TextureFormat = wgpu.TextureFormat.rgba8unorm,
|
|
27
|
+
depth_format: wgpu.TextureFormat = wgpu.TextureFormat.depth24plus,
|
|
28
|
+
msaa_sample_count: int = 4,
|
|
29
|
+
stride: int = 0,
|
|
30
|
+
topology: wgpu.PrimitiveTopology = wgpu.PrimitiveTopology.triangle_list,
|
|
31
|
+
):
|
|
32
|
+
"""
|
|
33
|
+
Initialize the triangle rendering pipeline.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
device: WebGPU device
|
|
37
|
+
texture_format: Color attachment format
|
|
38
|
+
depth_format: Depth attachment format
|
|
39
|
+
msaa_sample_count: Number of MSAA samples
|
|
40
|
+
stride: The stride of the vertex buffer. If 0, it is inferred from data_type.
|
|
41
|
+
topology: Triangle topology (triangle_list or triangle_strip)
|
|
42
|
+
"""
|
|
43
|
+
self._topology = topology
|
|
44
|
+
super().__init__(
|
|
45
|
+
device=device,
|
|
46
|
+
texture_format=texture_format,
|
|
47
|
+
depth_format=depth_format,
|
|
48
|
+
msaa_sample_count=msaa_sample_count,
|
|
49
|
+
data_type=data_type,
|
|
50
|
+
stride=stride,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def _get_primitive_topology(self) -> wgpu.PrimitiveTopology:
|
|
54
|
+
"""Triangle pipelines use configurable topology."""
|
|
55
|
+
return self._topology
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class TrianglePipelineMultiColour(BaseTrianglePipeline):
|
|
59
|
+
"""
|
|
60
|
+
A reusable pipeline for rendering triangles in WebGPU with per-vertex colors.
|
|
61
|
+
|
|
62
|
+
Features:
|
|
63
|
+
- Triangle lists or triangle strips
|
|
64
|
+
- Per-vertex colors
|
|
65
|
+
- MVP matrix support
|
|
66
|
+
- MSAA support
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
def __init__(
|
|
70
|
+
self,
|
|
71
|
+
device: wgpu.GPUDevice,
|
|
72
|
+
data_type: str = "Vec3",
|
|
73
|
+
texture_format: wgpu.TextureFormat = wgpu.TextureFormat.rgba8unorm,
|
|
74
|
+
depth_format: wgpu.TextureFormat = wgpu.TextureFormat.depth24plus,
|
|
75
|
+
msaa_sample_count: int = 4,
|
|
76
|
+
stride: int = 0,
|
|
77
|
+
topology: wgpu.PrimitiveTopology = wgpu.PrimitiveTopology.triangle_list,
|
|
78
|
+
):
|
|
79
|
+
"""
|
|
80
|
+
Initialize the triangle rendering pipeline.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
device: WebGPU device
|
|
84
|
+
texture_format: Color attachment format
|
|
85
|
+
depth_format: Depth attachment format
|
|
86
|
+
msaa_sample_count: Number of MSAA samples
|
|
87
|
+
stride: The stride of the vertex buffer. If 0, it is inferred from data_type.
|
|
88
|
+
topology: Triangle topology (triangle_list or triangle_strip)
|
|
89
|
+
"""
|
|
90
|
+
# Pipeline-specific buffer tracking
|
|
91
|
+
self.vertex_buffer: Optional[wgpu.GPUBuffer] = None
|
|
92
|
+
self.color_buffer: Optional[wgpu.GPUBuffer] = None
|
|
93
|
+
self.num_vertices: int = 0
|
|
94
|
+
|
|
95
|
+
super().__init__(
|
|
96
|
+
device=device,
|
|
97
|
+
texture_format=texture_format,
|
|
98
|
+
depth_format=depth_format,
|
|
99
|
+
msaa_sample_count=msaa_sample_count,
|
|
100
|
+
data_type=data_type,
|
|
101
|
+
stride=stride,
|
|
102
|
+
topology=topology,
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
def get_dtype(self) -> np.dtype:
|
|
106
|
+
"""Get the data type of the pipeline."""
|
|
107
|
+
return np.dtype(
|
|
108
|
+
[
|
|
109
|
+
("MVP", "float32", (4, 4)),
|
|
110
|
+
("padding", "float32", 4),
|
|
111
|
+
]
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
def _get_shader_code(self) -> str:
|
|
115
|
+
"""Get the WGSL shader code for this pipeline."""
|
|
116
|
+
return TRIANGLE_SHADER_MULTI_COLOURED
|
|
117
|
+
|
|
118
|
+
def _get_vertex_buffer_layouts(self):
|
|
119
|
+
"""Get vertex buffer layout configurations for the pipeline."""
|
|
120
|
+
return [
|
|
121
|
+
{
|
|
122
|
+
"array_stride": self._stride,
|
|
123
|
+
"step_mode": "vertex",
|
|
124
|
+
"attributes": [
|
|
125
|
+
{
|
|
126
|
+
"format": NGLToWebGPU.vertex_format(self._data_type),
|
|
127
|
+
"offset": 0,
|
|
128
|
+
"shader_location": 0,
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"array_stride": NGLToWebGPU.stride_from_type("Vec3"),
|
|
134
|
+
"step_mode": "vertex",
|
|
135
|
+
"attributes": [
|
|
136
|
+
{
|
|
137
|
+
"format": NGLToWebGPU.vertex_format("Vec3"),
|
|
138
|
+
"offset": 0,
|
|
139
|
+
"shader_location": 1,
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
},
|
|
143
|
+
]
|
|
144
|
+
|
|
145
|
+
def _set_default_uniforms(self) -> None:
|
|
146
|
+
"""Set default values for uniform data."""
|
|
147
|
+
pass # No specific defaults for triangle pipeline
|
|
148
|
+
|
|
149
|
+
def _get_pipeline_label(self) -> str:
|
|
150
|
+
"""Get the label for the pipeline."""
|
|
151
|
+
topology_name = (
|
|
152
|
+
"list"
|
|
153
|
+
if self._topology == wgpu.PrimitiveTopology.triangle_list
|
|
154
|
+
else "strip"
|
|
155
|
+
)
|
|
156
|
+
return f"triangle_pipeline_multi_coloured_{topology_name}"
|
|
157
|
+
|
|
158
|
+
def set_data(self, positions=None, colors=None, **kwargs) -> None:
|
|
159
|
+
"""
|
|
160
|
+
Set the triangle data for rendering.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
positions: Nx2/Nx3 array of triangle positions or a pre-existing GPUBuffer.
|
|
164
|
+
colors: Nx3 array of triangle colors (RGB) or a pre-existing GPUBuffer.
|
|
165
|
+
"""
|
|
166
|
+
if positions is not None:
|
|
167
|
+
if isinstance(positions, wgpu.GPUBuffer):
|
|
168
|
+
self.vertex_buffer = positions
|
|
169
|
+
self.num_vertices = positions.size // self._stride
|
|
170
|
+
else: # numpy array
|
|
171
|
+
self.vertex_buffer, buffer_size = self._create_or_update_buffer(
|
|
172
|
+
self.vertex_buffer,
|
|
173
|
+
positions,
|
|
174
|
+
wgpu.BufferUsage.VERTEX | wgpu.BufferUsage.COPY_DST,
|
|
175
|
+
f"triangle_pipeline_multi_coloured_position_buffer_{self._get_pipeline_label()}",
|
|
176
|
+
)
|
|
177
|
+
self.num_vertices = buffer_size // self._stride
|
|
178
|
+
|
|
179
|
+
if colors is not None:
|
|
180
|
+
if isinstance(colors, wgpu.GPUBuffer):
|
|
181
|
+
self.color_buffer = colors
|
|
182
|
+
else:
|
|
183
|
+
color_result = self._process_vertex_data(
|
|
184
|
+
colors,
|
|
185
|
+
None,
|
|
186
|
+
padding_size=4, # Pad to vec4 for alignment
|
|
187
|
+
buffer_label=f"triangle_pipeline_multi_coloured_colour_buffer_{self._get_pipeline_label()}",
|
|
188
|
+
)
|
|
189
|
+
if isinstance(color_result, wgpu.GPUBuffer):
|
|
190
|
+
self.color_buffer = color_result
|
|
191
|
+
elif color_result:
|
|
192
|
+
self.color_buffer = color_result[0]
|
|
193
|
+
else:
|
|
194
|
+
self.color_buffer = None
|
|
195
|
+
|
|
196
|
+
def update_uniforms(self, **kwargs) -> None:
|
|
197
|
+
"""
|
|
198
|
+
Update uniform buffer values.
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
**kwargs: Pipeline-specific uniform parameters
|
|
202
|
+
- mvp: 4x4 projection matrix
|
|
203
|
+
"""
|
|
204
|
+
if "mvp" in kwargs and kwargs["mvp"] is not None:
|
|
205
|
+
self.uniform_data["MVP"] = kwargs["mvp"]
|
|
206
|
+
|
|
207
|
+
self.device.queue.write_buffer(
|
|
208
|
+
self.uniform_buffer, 0, self.uniform_data.tobytes()
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
def render(self, render_pass: wgpu.GPURenderPassEncoder, **kwargs) -> None:
|
|
212
|
+
"""
|
|
213
|
+
Render the triangles.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
render_pass: Active render pass encoder
|
|
217
|
+
**kwargs: Pipeline-specific render parameters
|
|
218
|
+
- num_vertices: Number of vertices to render (defaults to all)
|
|
219
|
+
"""
|
|
220
|
+
num_vertices = kwargs.get("num_vertices", None)
|
|
221
|
+
|
|
222
|
+
if self.vertex_buffer is None or self.color_buffer is None:
|
|
223
|
+
return
|
|
224
|
+
|
|
225
|
+
count = num_vertices if num_vertices is not None else self.num_vertices
|
|
226
|
+
|
|
227
|
+
render_pass.set_pipeline(self.pipeline)
|
|
228
|
+
if self.bind_group:
|
|
229
|
+
render_pass.set_bind_group(0, self.bind_group, [], 0, 999999)
|
|
230
|
+
render_pass.set_vertex_buffer(0, self.vertex_buffer)
|
|
231
|
+
render_pass.set_vertex_buffer(1, self.color_buffer)
|
|
232
|
+
render_pass.draw(count)
|
|
233
|
+
|
|
234
|
+
def cleanup(self) -> None:
|
|
235
|
+
"""Release resources."""
|
|
236
|
+
if self.vertex_buffer:
|
|
237
|
+
self.vertex_buffer.destroy()
|
|
238
|
+
if self.color_buffer:
|
|
239
|
+
self.color_buffer.destroy()
|
|
240
|
+
super().cleanup()
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class TrianglePipelineSingleColour(BaseTrianglePipeline):
|
|
244
|
+
"""
|
|
245
|
+
A reusable pipeline for rendering triangles in WebGPU with single color.
|
|
246
|
+
|
|
247
|
+
Features:
|
|
248
|
+
- Triangle lists or triangle strips
|
|
249
|
+
- Single color for all triangles
|
|
250
|
+
- MVP matrix support
|
|
251
|
+
- MSAA support
|
|
252
|
+
"""
|
|
253
|
+
|
|
254
|
+
def __init__(
|
|
255
|
+
self,
|
|
256
|
+
device: wgpu.GPUDevice,
|
|
257
|
+
data_type: str = "Vec3",
|
|
258
|
+
texture_format: wgpu.TextureFormat = wgpu.TextureFormat.rgba8unorm,
|
|
259
|
+
depth_format: wgpu.TextureFormat = wgpu.TextureFormat.depth24plus,
|
|
260
|
+
msaa_sample_count: int = 4,
|
|
261
|
+
stride: int = 0,
|
|
262
|
+
topology: wgpu.PrimitiveTopology = wgpu.PrimitiveTopology.triangle_list,
|
|
263
|
+
colour: Tuple[float, float, float] = (1.0, 1.0, 1.0),
|
|
264
|
+
):
|
|
265
|
+
"""
|
|
266
|
+
Initialize the triangle rendering pipeline.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
device: WebGPU device
|
|
270
|
+
texture_format: Color attachment format
|
|
271
|
+
depth_format: Depth attachment format
|
|
272
|
+
msaa_sample_count: Number of MSAA samples
|
|
273
|
+
stride: The stride of the vertex buffer. If 0, it is inferred from data_type.
|
|
274
|
+
topology: Triangle topology (triangle_list or triangle_strip)
|
|
275
|
+
colour: RGB color tuple for triangles (default white)
|
|
276
|
+
"""
|
|
277
|
+
# Pipeline-specific buffer tracking
|
|
278
|
+
self.vertex_buffer: Optional[wgpu.GPUBuffer] = None
|
|
279
|
+
self.num_vertices: int = 0
|
|
280
|
+
self._colour = np.array(colour, dtype=np.float32)
|
|
281
|
+
|
|
282
|
+
super().__init__(
|
|
283
|
+
device=device,
|
|
284
|
+
texture_format=texture_format,
|
|
285
|
+
depth_format=depth_format,
|
|
286
|
+
msaa_sample_count=msaa_sample_count,
|
|
287
|
+
data_type=data_type,
|
|
288
|
+
stride=stride,
|
|
289
|
+
topology=topology,
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
def get_dtype(self) -> np.dtype:
|
|
293
|
+
"""Get the data type of the pipeline."""
|
|
294
|
+
return np.dtype(
|
|
295
|
+
[
|
|
296
|
+
("MVP", "float32", (4, 4)),
|
|
297
|
+
("Colour", "float32", 3),
|
|
298
|
+
("padding", "float32", 1),
|
|
299
|
+
]
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
def _get_shader_code(self) -> str:
|
|
303
|
+
"""Get the WGSL shader code for this pipeline."""
|
|
304
|
+
return TRIANGLE_SHADER_SINGLE_COLOUR
|
|
305
|
+
|
|
306
|
+
def _get_vertex_buffer_layouts(self):
|
|
307
|
+
"""Get vertex buffer layout configurations for the pipeline."""
|
|
308
|
+
return [
|
|
309
|
+
{
|
|
310
|
+
"array_stride": self._stride,
|
|
311
|
+
"step_mode": "vertex",
|
|
312
|
+
"attributes": [
|
|
313
|
+
{
|
|
314
|
+
"format": NGLToWebGPU.vertex_format(self._data_type),
|
|
315
|
+
"offset": 0,
|
|
316
|
+
"shader_location": 0,
|
|
317
|
+
},
|
|
318
|
+
],
|
|
319
|
+
},
|
|
320
|
+
]
|
|
321
|
+
|
|
322
|
+
def _set_default_uniforms(self) -> None:
|
|
323
|
+
"""Set default values for uniform data."""
|
|
324
|
+
pass # No specific defaults for triangle pipeline
|
|
325
|
+
|
|
326
|
+
def _get_pipeline_label(self) -> str:
|
|
327
|
+
"""Get the label for the pipeline."""
|
|
328
|
+
topology_name = (
|
|
329
|
+
"list"
|
|
330
|
+
if self._topology == wgpu.PrimitiveTopology.triangle_list
|
|
331
|
+
else "strip"
|
|
332
|
+
)
|
|
333
|
+
return f"triangle_pipeline_single_colour_{topology_name}"
|
|
334
|
+
|
|
335
|
+
def set_data(self, positions=None, colors=None, **kwargs) -> None:
|
|
336
|
+
"""
|
|
337
|
+
Set the triangle data for rendering.
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
positions: Nx2/Nx3 array of triangle positions or a pre-existing GPUBuffer.
|
|
341
|
+
colors: Ignored for single colour pipeline
|
|
342
|
+
"""
|
|
343
|
+
if positions is not None:
|
|
344
|
+
if isinstance(positions, wgpu.GPUBuffer):
|
|
345
|
+
self.vertex_buffer = positions
|
|
346
|
+
self.num_vertices = positions.size // self._stride
|
|
347
|
+
else: # numpy array
|
|
348
|
+
self.vertex_buffer, buffer_size = self._create_or_update_buffer(
|
|
349
|
+
self.vertex_buffer,
|
|
350
|
+
positions,
|
|
351
|
+
wgpu.BufferUsage.VERTEX | wgpu.BufferUsage.COPY_DST,
|
|
352
|
+
f"triangle_pipeline_single_colour_position_buffer_{self._get_pipeline_label()}",
|
|
353
|
+
)
|
|
354
|
+
self.num_vertices = buffer_size // self._stride
|
|
355
|
+
|
|
356
|
+
def update_uniforms(self, **kwargs) -> None:
|
|
357
|
+
"""
|
|
358
|
+
Update uniform buffer values.
|
|
359
|
+
|
|
360
|
+
Args:
|
|
361
|
+
**kwargs: Pipeline-specific uniform parameters
|
|
362
|
+
- mvp: 4x4 projection matrix
|
|
363
|
+
- colour: RGB color tuple
|
|
364
|
+
"""
|
|
365
|
+
if "mvp" in kwargs and kwargs["mvp"] is not None:
|
|
366
|
+
self.uniform_data["MVP"] = kwargs["mvp"]
|
|
367
|
+
|
|
368
|
+
if "colour" in kwargs and kwargs["colour"] is not None:
|
|
369
|
+
colour = np.array(kwargs["colour"], dtype=np.float32)
|
|
370
|
+
if colour.shape == (3,):
|
|
371
|
+
self.uniform_data["Colour"] = colour
|
|
372
|
+
self._colour = colour
|
|
373
|
+
|
|
374
|
+
self.device.queue.write_buffer(
|
|
375
|
+
self.uniform_buffer, 0, self.uniform_data.tobytes()
|
|
376
|
+
)
|
|
377
|
+
|
|
378
|
+
def set_color(self, colour: Tuple[float, float, float]) -> None:
|
|
379
|
+
"""
|
|
380
|
+
Set the color for the triangles.
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
colour: RGB color tuple
|
|
384
|
+
"""
|
|
385
|
+
colour_array = np.array(colour, dtype=np.float32)
|
|
386
|
+
if colour_array.shape == (3,):
|
|
387
|
+
self.uniform_data["Colour"] = colour_array
|
|
388
|
+
self._colour = colour_array
|
|
389
|
+
self.device.queue.write_buffer(
|
|
390
|
+
self.uniform_buffer, 0, self.uniform_data.tobytes()
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
def render(self, render_pass: wgpu.GPURenderPassEncoder, **kwargs) -> None:
|
|
394
|
+
"""
|
|
395
|
+
Render the triangles.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
render_pass: Active render pass encoder
|
|
399
|
+
**kwargs: Pipeline-specific render parameters
|
|
400
|
+
- num_vertices: Number of vertices to render (defaults to all)
|
|
401
|
+
"""
|
|
402
|
+
num_vertices = kwargs.get("num_vertices", None)
|
|
403
|
+
|
|
404
|
+
if self.vertex_buffer is None:
|
|
405
|
+
return
|
|
406
|
+
|
|
407
|
+
count = num_vertices if num_vertices is not None else self.num_vertices
|
|
408
|
+
|
|
409
|
+
render_pass.set_pipeline(self.pipeline)
|
|
410
|
+
if self.bind_group:
|
|
411
|
+
render_pass.set_bind_group(0, self.bind_group, [], 0, 999999)
|
|
412
|
+
render_pass.set_vertex_buffer(0, self.vertex_buffer)
|
|
413
|
+
render_pass.draw(count)
|
|
414
|
+
|
|
415
|
+
def cleanup(self) -> None:
|
|
416
|
+
"""Release resources."""
|
|
417
|
+
if self.vertex_buffer:
|
|
418
|
+
self.vertex_buffer.destroy()
|
|
419
|
+
super().cleanup()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from enum import IntEnum
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from ncca.ngl import Mat2, Mat3, Mat4, Vec2, Vec3, Vec4
|
|
6
|
+
|
|
7
|
+
FLOAT_SIZE = np.dtype(np.float32).itemsize
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class NGLToWebGPU:
|
|
11
|
+
_strides = {
|
|
12
|
+
"vec2": 2 * FLOAT_SIZE,
|
|
13
|
+
"vec3": 3 * FLOAT_SIZE,
|
|
14
|
+
"vec4": 4 * FLOAT_SIZE,
|
|
15
|
+
"mat2": 4 * FLOAT_SIZE,
|
|
16
|
+
"mat3": 12 * FLOAT_SIZE,
|
|
17
|
+
"mat4": 16 * FLOAT_SIZE,
|
|
18
|
+
}
|
|
19
|
+
_vertex_format = {
|
|
20
|
+
"vec2": "float32x2",
|
|
21
|
+
"vec3": "float32x3",
|
|
22
|
+
"vec4": "float32x4",
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def stride_from_type(type: str):
|
|
27
|
+
return NGLToWebGPU._strides[type.lower()]
|
|
28
|
+
|
|
29
|
+
@staticmethod
|
|
30
|
+
def vertex_format(type: str):
|
|
31
|
+
return NGLToWebGPU._vertex_format[type.lower()]
|