ncca-ngl 0.1.0__py3-none-any.whl → 0.1.1__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-0.1.0.dist-info → ncca_ngl-0.1.1.dist-info}/METADATA +9 -9
- ncca_ngl-0.1.1.dist-info/RECORD +4 -0
- {ncca_ngl-0.1.0.dist-info → ncca_ngl-0.1.1.dist-info}/WHEEL +1 -2
- ncca/ngl/PrimData/pack_arrays.py +0 -20
- ncca/ngl/__init__.py +0 -100
- ncca/ngl/abstract_vao.py +0 -89
- ncca/ngl/base_mesh.py +0 -170
- ncca/ngl/base_mesh.pyi +0 -11
- ncca/ngl/bbox.py +0 -224
- ncca/ngl/bezier_curve.py +0 -75
- ncca/ngl/first_person_camera.py +0 -174
- ncca/ngl/image.py +0 -94
- ncca/ngl/log.py +0 -44
- ncca/ngl/mat2.py +0 -128
- ncca/ngl/mat3.py +0 -466
- ncca/ngl/mat4.py +0 -456
- ncca/ngl/multi_buffer_vao.py +0 -49
- ncca/ngl/obj.py +0 -416
- ncca/ngl/plane.py +0 -47
- ncca/ngl/primitives.py +0 -706
- ncca/ngl/pyside_event_handling_mixin.py +0 -318
- ncca/ngl/quaternion.py +0 -112
- ncca/ngl/random.py +0 -167
- ncca/ngl/shader.py +0 -229
- ncca/ngl/shader_lib.py +0 -536
- ncca/ngl/shader_program.py +0 -816
- ncca/ngl/simple_index_vao.py +0 -65
- ncca/ngl/simple_vao.py +0 -42
- ncca/ngl/text.py +0 -346
- ncca/ngl/texture.py +0 -75
- ncca/ngl/transform.py +0 -95
- ncca/ngl/util.py +0 -128
- ncca/ngl/vao_factory.py +0 -34
- ncca/ngl/vec2.py +0 -350
- ncca/ngl/vec2_array.py +0 -106
- ncca/ngl/vec3.py +0 -401
- ncca/ngl/vec3_array.py +0 -110
- ncca/ngl/vec4.py +0 -229
- ncca/ngl/vec4_array.py +0 -106
- ncca_ngl-0.1.0.dist-info/RECORD +0 -41
- ncca_ngl-0.1.0.dist-info/top_level.txt +0 -1
- {ncca_ngl-0.1.0.dist-info → ncca_ngl-0.1.1.dist-info}/licenses/LICENSE.txt +0 -0
ncca/ngl/shader_program.py
DELETED
|
@@ -1,816 +0,0 @@
|
|
|
1
|
-
import ctypes
|
|
2
|
-
from typing import Any, Dict, List, Optional, Union
|
|
3
|
-
|
|
4
|
-
import numpy as np
|
|
5
|
-
import OpenGL.GL as gl
|
|
6
|
-
|
|
7
|
-
from .log import logger
|
|
8
|
-
from .mat2 import Mat2
|
|
9
|
-
from .mat3 import Mat3
|
|
10
|
-
from .mat4 import Mat4
|
|
11
|
-
from .shader import Shader
|
|
12
|
-
from .vec2 import Vec2
|
|
13
|
-
from .vec3 import Vec3
|
|
14
|
-
from .vec4 import Vec4
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class ShaderProgram:
|
|
18
|
-
"""
|
|
19
|
-
A wrapper class for OpenGL shader programs.
|
|
20
|
-
|
|
21
|
-
This class provides functionality to create, link, and manage OpenGL shader programs,
|
|
22
|
-
including automatic uniform and uniform block registration, and convenience methods
|
|
23
|
-
for setting uniform values.
|
|
24
|
-
|
|
25
|
-
Attributes:
|
|
26
|
-
_name: The name of the shader program
|
|
27
|
-
_exit_on_error: Whether to exit the application on errors
|
|
28
|
-
_id: The OpenGL shader program ID
|
|
29
|
-
_shaders: List of attached shaders
|
|
30
|
-
_uniforms: Dictionary of registered uniforms
|
|
31
|
-
_registered_uniform_blocks: Dictionary of registered uniform blocks
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
def __init__(self, name: str, exit_on_error: bool = True) -> None:
|
|
35
|
-
"""
|
|
36
|
-
Initialize a new shader program.
|
|
37
|
-
|
|
38
|
-
Args:
|
|
39
|
-
name: Name of the shader program for identification
|
|
40
|
-
exit_on_error: Whether to exit the application when errors occur
|
|
41
|
-
"""
|
|
42
|
-
self._name: str = name
|
|
43
|
-
self._exit_on_error: bool = exit_on_error
|
|
44
|
-
self._id: int = gl.glCreateProgram()
|
|
45
|
-
self._shaders: list[Shader] = []
|
|
46
|
-
self._uniforms: dict[str, tuple[int, int, int, bool]] = {}
|
|
47
|
-
self._registered_uniform_blocks: dict[str, dict] = {}
|
|
48
|
-
|
|
49
|
-
def attach_shader(self, shader: Shader) -> None:
|
|
50
|
-
"""
|
|
51
|
-
Attach a shader to this program.
|
|
52
|
-
|
|
53
|
-
Args:
|
|
54
|
-
shader: The Shader object to attach
|
|
55
|
-
"""
|
|
56
|
-
gl.glAttachShader(self._id, shader._id)
|
|
57
|
-
self._shaders.append(shader)
|
|
58
|
-
|
|
59
|
-
def link(self) -> bool:
|
|
60
|
-
"""
|
|
61
|
-
Link the attached shaders to create the final shader program.
|
|
62
|
-
|
|
63
|
-
Returns:
|
|
64
|
-
bool: True if linking succeeded, False otherwise.
|
|
65
|
-
"""
|
|
66
|
-
gl.glLinkProgram(self._id)
|
|
67
|
-
if gl.glGetProgramiv(self._id, gl.GL_LINK_STATUS) != gl.GL_TRUE:
|
|
68
|
-
info = gl.glGetProgramInfoLog(self._id)
|
|
69
|
-
logger.error(f"Error linking program {self._name}: {info}")
|
|
70
|
-
if self._exit_on_error:
|
|
71
|
-
exit()
|
|
72
|
-
return False
|
|
73
|
-
# Automatically register uniforms and uniform blocks after linking
|
|
74
|
-
self.auto_register_uniforms()
|
|
75
|
-
self.auto_register_uniform_blocks()
|
|
76
|
-
return True
|
|
77
|
-
|
|
78
|
-
def auto_register_uniforms(self) -> None:
|
|
79
|
-
"""
|
|
80
|
-
Automatically register all active uniforms in the shader program.
|
|
81
|
-
|
|
82
|
-
This method queries OpenGL for all active uniforms and stores their
|
|
83
|
-
information including location, type, size, and array status.
|
|
84
|
-
For array uniforms, it also registers individual array elements.
|
|
85
|
-
"""
|
|
86
|
-
uniform_count = gl.glGetProgramiv(self._id, gl.GL_ACTIVE_UNIFORMS)
|
|
87
|
-
for i in range(uniform_count):
|
|
88
|
-
name, size, shader_type = gl.glGetActiveUniform(self._id, i, 256)
|
|
89
|
-
|
|
90
|
-
# Convert name to string
|
|
91
|
-
name_str = name.decode("utf-8") if isinstance(name, bytes) else name
|
|
92
|
-
|
|
93
|
-
# Handle array uniforms - OpenGL returns name with [0] for arrays
|
|
94
|
-
is_array = size > 1
|
|
95
|
-
base_name = name_str
|
|
96
|
-
if name_str.endswith("[0]"):
|
|
97
|
-
base_name = name_str[:-3]
|
|
98
|
-
|
|
99
|
-
location = gl.glGetUniformLocation(self._id, name)
|
|
100
|
-
|
|
101
|
-
# Store uniform info: (location, shader_type, size, is_array)
|
|
102
|
-
self._uniforms[base_name] = (location, shader_type, size, is_array)
|
|
103
|
-
|
|
104
|
-
# For arrays, also register individual elements
|
|
105
|
-
if is_array:
|
|
106
|
-
for element_idx in range(size):
|
|
107
|
-
element_name = f"{base_name}[{element_idx}]"
|
|
108
|
-
element_location = gl.glGetUniformLocation(
|
|
109
|
-
self._id, element_name.encode("utf-8")
|
|
110
|
-
)
|
|
111
|
-
if element_location != -1:
|
|
112
|
-
# Store individual array element: (location, shader_type, 1, False)
|
|
113
|
-
self._uniforms[element_name] = (
|
|
114
|
-
element_location,
|
|
115
|
-
shader_type,
|
|
116
|
-
1,
|
|
117
|
-
False,
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
# Log array uniforms differently
|
|
121
|
-
if is_array:
|
|
122
|
-
logger.info(
|
|
123
|
-
f"Registered array uniform: {base_name}[{size}] (type: {self.get_gl_type_string(shader_type)}, location: {location})"
|
|
124
|
-
)
|
|
125
|
-
logger.info(
|
|
126
|
-
f" Also registered individual elements: {base_name}[0] to {base_name}[{size - 1}]"
|
|
127
|
-
)
|
|
128
|
-
else:
|
|
129
|
-
logger.info(
|
|
130
|
-
f"Registered uniform: {base_name} (type: {self.get_gl_type_string(shader_type)}, location: {location})"
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
def auto_register_uniform_blocks(self) -> None:
|
|
134
|
-
"""
|
|
135
|
-
Automatically register uniform blocks for this shader program.
|
|
136
|
-
This is the Python equivalent of the C++ ShaderProgram::autoRegisterUniformBlocks method.
|
|
137
|
-
"""
|
|
138
|
-
# Clear existing uniform blocks
|
|
139
|
-
self._registered_uniform_blocks.clear()
|
|
140
|
-
|
|
141
|
-
# Get number of active uniform blocks
|
|
142
|
-
n_uniforms = gl.glGetProgramiv(self._id, gl.GL_ACTIVE_UNIFORM_BLOCKS)
|
|
143
|
-
logger.info(f"FOUND UNIFORM BLOCKS {n_uniforms}")
|
|
144
|
-
|
|
145
|
-
for i in range(n_uniforms):
|
|
146
|
-
# Get uniform block name using ctypes buffer
|
|
147
|
-
name_buffer = (ctypes.c_char * 256)()
|
|
148
|
-
length = ctypes.c_int()
|
|
149
|
-
|
|
150
|
-
gl.glGetActiveUniformBlockName(
|
|
151
|
-
self._id, i, 256, ctypes.byref(length), name_buffer
|
|
152
|
-
)
|
|
153
|
-
name_str = (
|
|
154
|
-
name_buffer.value.decode("utf-8")
|
|
155
|
-
if name_buffer.value
|
|
156
|
-
else f"UniformBlock_{i}"
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
# Create uniform block data structure
|
|
160
|
-
data = {
|
|
161
|
-
"name": name_str,
|
|
162
|
-
"loc": gl.glGetUniformBlockIndex(self._id, name_str.encode("utf-8")),
|
|
163
|
-
"buffer": gl.glGenBuffers(1),
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
# Store the uniform block data
|
|
167
|
-
self._registered_uniform_blocks[name_str] = data
|
|
168
|
-
logger.info(f"Uniform Block {name_str} {data['loc']} {data['buffer']}")
|
|
169
|
-
|
|
170
|
-
def use(self) -> None:
|
|
171
|
-
"""
|
|
172
|
-
Set this shader program as the current active program.
|
|
173
|
-
"""
|
|
174
|
-
gl.glUseProgram(self._id)
|
|
175
|
-
|
|
176
|
-
def get_id(self) -> int:
|
|
177
|
-
"""
|
|
178
|
-
Get the OpenGL shader program ID.
|
|
179
|
-
|
|
180
|
-
Returns:
|
|
181
|
-
int: The OpenGL program ID
|
|
182
|
-
"""
|
|
183
|
-
return self._id
|
|
184
|
-
|
|
185
|
-
def get_uniform_location(self, name: str) -> int:
|
|
186
|
-
"""
|
|
187
|
-
Get the location of a uniform variable.
|
|
188
|
-
|
|
189
|
-
Args:
|
|
190
|
-
name: The name of the uniform variable
|
|
191
|
-
|
|
192
|
-
Returns:
|
|
193
|
-
int: The uniform location, or -1 if not found
|
|
194
|
-
"""
|
|
195
|
-
if name in self._uniforms:
|
|
196
|
-
return self._uniforms[name][0]
|
|
197
|
-
else:
|
|
198
|
-
logger.warning(f"Uniform '{name}' not found in shader '{self._name}'")
|
|
199
|
-
return -1
|
|
200
|
-
|
|
201
|
-
def get_uniform_info(self, name: str) -> tuple[int, int, int, bool]:
|
|
202
|
-
"""
|
|
203
|
-
Get complete uniform info: (location, shader_type, size, is_array).
|
|
204
|
-
|
|
205
|
-
Args:
|
|
206
|
-
name: The name of the uniform variable
|
|
207
|
-
|
|
208
|
-
Returns:
|
|
209
|
-
tuple: (location, shader_type, size, is_array)
|
|
210
|
-
"""
|
|
211
|
-
return self._uniforms.get(name, (-1, 0, 0, False))
|
|
212
|
-
|
|
213
|
-
def is_uniform_array(self, name: str) -> bool:
|
|
214
|
-
"""
|
|
215
|
-
Check if a uniform is an array.
|
|
216
|
-
|
|
217
|
-
Args:
|
|
218
|
-
name: The name of the uniform variable
|
|
219
|
-
|
|
220
|
-
Returns:
|
|
221
|
-
bool: True if the uniform is an array, False otherwise
|
|
222
|
-
"""
|
|
223
|
-
if name in self._uniforms:
|
|
224
|
-
return self._uniforms[name][3]
|
|
225
|
-
return False
|
|
226
|
-
|
|
227
|
-
def get_uniform_array_size(self, name: str) -> int:
|
|
228
|
-
"""
|
|
229
|
-
Get the size of a uniform array, returns 1 for non-arrays.
|
|
230
|
-
|
|
231
|
-
Args:
|
|
232
|
-
name: The name of the uniform variable
|
|
233
|
-
|
|
234
|
-
Returns:
|
|
235
|
-
int: The array size, or 0 if uniform not found
|
|
236
|
-
"""
|
|
237
|
-
if name in self._uniforms:
|
|
238
|
-
return self._uniforms[name][2]
|
|
239
|
-
return 0
|
|
240
|
-
|
|
241
|
-
def set_uniform_buffer(self, uniform_block_name: str, size: int, data) -> bool:
|
|
242
|
-
"""
|
|
243
|
-
Set uniform buffer data for the specified uniform block.
|
|
244
|
-
This is the Python equivalent of the C++ ShaderProgram::setUniformBuffer method.
|
|
245
|
-
|
|
246
|
-
Args:
|
|
247
|
-
uniform_block_name: Name of the uniform block
|
|
248
|
-
size: Size of the data in bytes
|
|
249
|
-
data: Data to upload (can be ctypes array, bytes, or buffer-like object)
|
|
250
|
-
|
|
251
|
-
Returns:
|
|
252
|
-
bool: True if successful, False otherwise
|
|
253
|
-
"""
|
|
254
|
-
if uniform_block_name not in self._registered_uniform_blocks:
|
|
255
|
-
logger.error(
|
|
256
|
-
f"Uniform block '{uniform_block_name}' not found in shader '{self._name}'"
|
|
257
|
-
)
|
|
258
|
-
return False
|
|
259
|
-
|
|
260
|
-
block = self._registered_uniform_blocks[uniform_block_name]
|
|
261
|
-
|
|
262
|
-
try:
|
|
263
|
-
# Bind the uniform buffer
|
|
264
|
-
gl.glBindBuffer(gl.GL_UNIFORM_BUFFER, block["buffer"])
|
|
265
|
-
|
|
266
|
-
# Upload the data
|
|
267
|
-
data = np.frombuffer(data, dtype=np.float32)
|
|
268
|
-
gl.glBufferData(gl.GL_UNIFORM_BUFFER, size, data, gl.GL_DYNAMIC_DRAW)
|
|
269
|
-
|
|
270
|
-
# Bind the buffer to the uniform block binding point
|
|
271
|
-
gl.glBindBufferBase(gl.GL_UNIFORM_BUFFER, block["loc"], block["buffer"])
|
|
272
|
-
|
|
273
|
-
# Unbind the buffer
|
|
274
|
-
gl.glBindBuffer(gl.GL_UNIFORM_BUFFER, 0)
|
|
275
|
-
|
|
276
|
-
return True
|
|
277
|
-
|
|
278
|
-
except Exception as e:
|
|
279
|
-
logger.error(f"Failed to set uniform buffer '{uniform_block_name}': {e}")
|
|
280
|
-
return False
|
|
281
|
-
|
|
282
|
-
def set_uniform(self, name: str, *value: Any) -> None:
|
|
283
|
-
"""
|
|
284
|
-
Set a uniform variable value.
|
|
285
|
-
|
|
286
|
-
This method automatically detects the type of the value and calls the
|
|
287
|
-
appropriate OpenGL uniform function. Supports scalars, vectors, matrices,
|
|
288
|
-
and custom vector/matrix types.
|
|
289
|
-
|
|
290
|
-
Args:
|
|
291
|
-
name: The name of the uniform variable
|
|
292
|
-
*value: The value(s) to set
|
|
293
|
-
"""
|
|
294
|
-
loc = self.get_uniform_location(name)
|
|
295
|
-
if loc == -1:
|
|
296
|
-
logger.warning(f"Uniform location not found for '{name}'")
|
|
297
|
-
return
|
|
298
|
-
|
|
299
|
-
# Get uniform info for better type handling
|
|
300
|
-
uniform_info = self.get_uniform_info(name)
|
|
301
|
-
_, uniform_type, array_size, is_array = uniform_info
|
|
302
|
-
|
|
303
|
-
if len(value) == 1:
|
|
304
|
-
val = value[0]
|
|
305
|
-
if isinstance(val, int):
|
|
306
|
-
gl.glUniform1i(loc, val)
|
|
307
|
-
elif isinstance(val, float):
|
|
308
|
-
gl.glUniform1f(loc, val)
|
|
309
|
-
elif isinstance(val, Mat2):
|
|
310
|
-
gl.glUniformMatrix2fv(
|
|
311
|
-
loc, 1, gl.GL_FALSE, (ctypes.c_float * 4)(*val.get_matrix())
|
|
312
|
-
)
|
|
313
|
-
elif isinstance(val, Mat3):
|
|
314
|
-
gl.glUniformMatrix3fv(
|
|
315
|
-
loc, 1, gl.GL_FALSE, (ctypes.c_float * 9)(*val.get_matrix())
|
|
316
|
-
)
|
|
317
|
-
elif isinstance(val, Mat4):
|
|
318
|
-
gl.glUniformMatrix4fv(
|
|
319
|
-
loc, 1, gl.GL_FALSE, (ctypes.c_float * 16)(*val.get_matrix())
|
|
320
|
-
)
|
|
321
|
-
elif isinstance(val, Vec2):
|
|
322
|
-
gl.glUniform2f(loc, *val)
|
|
323
|
-
elif isinstance(val, Vec3):
|
|
324
|
-
gl.glUniform3f(loc, *val)
|
|
325
|
-
elif isinstance(val, Vec4):
|
|
326
|
-
gl.glUniform4f(loc, *val)
|
|
327
|
-
else:
|
|
328
|
-
try:
|
|
329
|
-
val = list(value[0])
|
|
330
|
-
if len(val) == 4:
|
|
331
|
-
gl.glUniformMatrix2fv(
|
|
332
|
-
loc, 1, gl.GL_FALSE, (ctypes.c_float * 4)(*val)
|
|
333
|
-
)
|
|
334
|
-
elif len(val) == 9:
|
|
335
|
-
gl.glUniformMatrix3fv(
|
|
336
|
-
loc, 1, gl.GL_FALSE, (ctypes.c_float * 9)(*val)
|
|
337
|
-
)
|
|
338
|
-
elif len(val) == 16:
|
|
339
|
-
gl.glUniformMatrix4fv(
|
|
340
|
-
loc, 1, gl.GL_FALSE, (ctypes.c_float * 16)(*val)
|
|
341
|
-
)
|
|
342
|
-
except TypeError:
|
|
343
|
-
logger.warning(
|
|
344
|
-
f"Warning: uniform '{name}' has unknown type: {type(val)}"
|
|
345
|
-
)
|
|
346
|
-
|
|
347
|
-
elif len(value) == 2:
|
|
348
|
-
gl.glUniform2f(loc, *value)
|
|
349
|
-
elif len(value) == 3:
|
|
350
|
-
gl.glUniform3f(loc, *value)
|
|
351
|
-
elif len(value) == 4:
|
|
352
|
-
gl.glUniform4f(loc, *value)
|
|
353
|
-
|
|
354
|
-
def set_uniform_1fv(self, name: str, values: List[float]) -> None:
|
|
355
|
-
"""
|
|
356
|
-
Set a float array uniform.
|
|
357
|
-
|
|
358
|
-
Args:
|
|
359
|
-
name: The name of the uniform variable
|
|
360
|
-
values: List of float values
|
|
361
|
-
"""
|
|
362
|
-
"""Set a float array uniform"""
|
|
363
|
-
loc = self.get_uniform_location(name)
|
|
364
|
-
if loc != -1:
|
|
365
|
-
gl.glUniform1fv(loc, len(values), (ctypes.c_float * len(values))(*values))
|
|
366
|
-
|
|
367
|
-
def set_uniform_2fv(self, name: str, values: List[List[float]]) -> None:
|
|
368
|
-
"""
|
|
369
|
-
Set a vec2 array uniform.
|
|
370
|
-
|
|
371
|
-
Args:
|
|
372
|
-
name: The name of the uniform variable
|
|
373
|
-
values: List of vec2 values (each as a list of 2 floats)
|
|
374
|
-
"""
|
|
375
|
-
"""Set a vec2 array uniform"""
|
|
376
|
-
loc = self.get_uniform_location(name)
|
|
377
|
-
if loc != -1:
|
|
378
|
-
flat_values = [item for vec in values for item in vec]
|
|
379
|
-
gl.glUniform2fv(
|
|
380
|
-
loc, len(values), (ctypes.c_float * len(flat_values))(*flat_values)
|
|
381
|
-
)
|
|
382
|
-
|
|
383
|
-
def set_uniform_3fv(self, name: str, values: List[List[float]]) -> None:
|
|
384
|
-
"""
|
|
385
|
-
Set a vec3 array uniform.
|
|
386
|
-
|
|
387
|
-
Args:
|
|
388
|
-
name: The name of the uniform variable
|
|
389
|
-
values: List of vec3 values (each as a list of 3 floats)
|
|
390
|
-
"""
|
|
391
|
-
"""Set a vec3 array uniform"""
|
|
392
|
-
loc = self.get_uniform_location(name)
|
|
393
|
-
if loc != -1:
|
|
394
|
-
flat_values = [item for vec in values for item in vec]
|
|
395
|
-
gl.glUniform3fv(
|
|
396
|
-
loc, len(values), (ctypes.c_float * len(flat_values))(*flat_values)
|
|
397
|
-
)
|
|
398
|
-
|
|
399
|
-
def set_uniform_4fv(self, name: str, values: List[List[float]]) -> None:
|
|
400
|
-
"""
|
|
401
|
-
Set a vec4 array uniform.
|
|
402
|
-
|
|
403
|
-
Args:
|
|
404
|
-
name: The name of the uniform variable
|
|
405
|
-
values: List of vec4 values (each as a list of 4 floats)
|
|
406
|
-
"""
|
|
407
|
-
"""Set a vec4 array uniform"""
|
|
408
|
-
loc = self.get_uniform_location(name)
|
|
409
|
-
if loc != -1:
|
|
410
|
-
flat_values = [item for vec in values for item in vec]
|
|
411
|
-
gl.glUniform4fv(
|
|
412
|
-
loc, len(values), (ctypes.c_float * len(flat_values))(*flat_values)
|
|
413
|
-
)
|
|
414
|
-
|
|
415
|
-
def set_uniform_1iv(self, name: str, values: List[int]) -> None:
|
|
416
|
-
"""
|
|
417
|
-
Set an int array uniform.
|
|
418
|
-
|
|
419
|
-
Args:
|
|
420
|
-
name: The name of the uniform variable
|
|
421
|
-
values: List of integer values
|
|
422
|
-
"""
|
|
423
|
-
"""Set an int array uniform"""
|
|
424
|
-
loc = self.get_uniform_location(name)
|
|
425
|
-
if loc != -1:
|
|
426
|
-
gl.glUniform1iv(loc, len(values), (ctypes.c_int * len(values))(*values))
|
|
427
|
-
|
|
428
|
-
def set_uniform_matrix2fv(
|
|
429
|
-
self,
|
|
430
|
-
name: str,
|
|
431
|
-
matrices: List[Union[Mat2, List[float]]],
|
|
432
|
-
transpose: bool = False,
|
|
433
|
-
) -> None:
|
|
434
|
-
"""
|
|
435
|
-
Set a mat2 array uniform.
|
|
436
|
-
|
|
437
|
-
Args:
|
|
438
|
-
name: The name of the uniform variable
|
|
439
|
-
matrices: List of 2x2 matrices (Mat2 objects or lists of 4 floats)
|
|
440
|
-
transpose: Whether to transpose the matrices
|
|
441
|
-
"""
|
|
442
|
-
"""Set a mat2 array uniform"""
|
|
443
|
-
loc = self.get_uniform_location(name)
|
|
444
|
-
if loc != -1:
|
|
445
|
-
flat_values = []
|
|
446
|
-
for matrix in matrices:
|
|
447
|
-
if hasattr(matrix, "get_matrix"):
|
|
448
|
-
flat_values.extend(matrix.get_matrix())
|
|
449
|
-
else:
|
|
450
|
-
flat_values.extend(matrix)
|
|
451
|
-
gl.glUniformMatrix2fv(
|
|
452
|
-
loc,
|
|
453
|
-
len(matrices),
|
|
454
|
-
gl.GL_TRUE if transpose else gl.GL_FALSE,
|
|
455
|
-
(ctypes.c_float * len(flat_values))(*flat_values),
|
|
456
|
-
)
|
|
457
|
-
|
|
458
|
-
def set_uniform_matrix3fv(
|
|
459
|
-
self,
|
|
460
|
-
name: str,
|
|
461
|
-
matrices: List[Union[Mat3, List[float]]],
|
|
462
|
-
transpose: bool = False,
|
|
463
|
-
) -> None:
|
|
464
|
-
"""
|
|
465
|
-
Set a mat3 array uniform.
|
|
466
|
-
|
|
467
|
-
Args:
|
|
468
|
-
name: The name of the uniform variable
|
|
469
|
-
matrices: List of 3x3 matrices (Mat3 objects or lists of 9 floats)
|
|
470
|
-
transpose: Whether to transpose the matrices
|
|
471
|
-
"""
|
|
472
|
-
"""Set a mat3 array uniform"""
|
|
473
|
-
loc = self.get_uniform_location(name)
|
|
474
|
-
if loc != -1:
|
|
475
|
-
flat_values = []
|
|
476
|
-
for matrix in matrices:
|
|
477
|
-
if hasattr(matrix, "get_matrix"):
|
|
478
|
-
flat_values.extend(matrix.get_matrix())
|
|
479
|
-
else:
|
|
480
|
-
flat_values.extend(matrix)
|
|
481
|
-
gl.glUniformMatrix3fv(
|
|
482
|
-
loc,
|
|
483
|
-
len(matrices),
|
|
484
|
-
gl.GL_TRUE if transpose else gl.GL_FALSE,
|
|
485
|
-
(ctypes.c_float * len(flat_values))(*flat_values),
|
|
486
|
-
)
|
|
487
|
-
|
|
488
|
-
def set_uniform_matrix4fv(
|
|
489
|
-
self,
|
|
490
|
-
name: str,
|
|
491
|
-
matrices: List[Union[Mat4, List[float]]],
|
|
492
|
-
transpose: bool = False,
|
|
493
|
-
) -> None:
|
|
494
|
-
"""
|
|
495
|
-
Set a mat4 array uniform.
|
|
496
|
-
|
|
497
|
-
Args:
|
|
498
|
-
name: The name of the uniform variable
|
|
499
|
-
matrices: List of 4x4 matrices (Mat4 objects or lists of 16 floats)
|
|
500
|
-
transpose: Whether to transpose the matrices
|
|
501
|
-
"""
|
|
502
|
-
"""Set a mat4 array uniform"""
|
|
503
|
-
loc = self.get_uniform_location(name)
|
|
504
|
-
if loc != -1:
|
|
505
|
-
flat_values = []
|
|
506
|
-
for matrix in matrices:
|
|
507
|
-
if hasattr(matrix, "get_matrix"):
|
|
508
|
-
flat_values.extend(matrix.get_matrix())
|
|
509
|
-
else:
|
|
510
|
-
flat_values.extend(matrix)
|
|
511
|
-
gl.glUniformMatrix4fv(
|
|
512
|
-
loc,
|
|
513
|
-
len(matrices),
|
|
514
|
-
gl.GL_TRUE if transpose else gl.GL_FALSE,
|
|
515
|
-
(ctypes.c_float * len(flat_values))(*flat_values),
|
|
516
|
-
)
|
|
517
|
-
|
|
518
|
-
def get_uniform_1f(self, name: str) -> float:
|
|
519
|
-
"""
|
|
520
|
-
Get a single float uniform value.
|
|
521
|
-
|
|
522
|
-
Args:
|
|
523
|
-
name: The name of the uniform variable
|
|
524
|
-
|
|
525
|
-
Returns:
|
|
526
|
-
The float value, or 0.0 if not found
|
|
527
|
-
"""
|
|
528
|
-
loc = self.get_uniform_location(name)
|
|
529
|
-
if loc != -1:
|
|
530
|
-
result = (ctypes.c_float * 1)()
|
|
531
|
-
gl.glGetUniformfv(self._id, loc, result)
|
|
532
|
-
return result[0]
|
|
533
|
-
return 0.0
|
|
534
|
-
|
|
535
|
-
def get_uniform_2f(self, name: str) -> List[float]:
|
|
536
|
-
"""
|
|
537
|
-
Get a vec2 uniform value.
|
|
538
|
-
|
|
539
|
-
Args:
|
|
540
|
-
name: The name of the uniform variable
|
|
541
|
-
|
|
542
|
-
Returns:
|
|
543
|
-
A list of 2 floats, or [0.0, 0.0] if not found
|
|
544
|
-
"""
|
|
545
|
-
loc = self.get_uniform_location(name)
|
|
546
|
-
if loc != -1:
|
|
547
|
-
result = (ctypes.c_float * 2)()
|
|
548
|
-
gl.glGetUniformfv(self._id, loc, result)
|
|
549
|
-
return list(result)
|
|
550
|
-
return [0.0, 0.0]
|
|
551
|
-
|
|
552
|
-
def get_uniform_3f(self, name: str) -> List[float]:
|
|
553
|
-
"""
|
|
554
|
-
Get a vec3 uniform value.
|
|
555
|
-
|
|
556
|
-
Args:
|
|
557
|
-
name: The name of the uniform variable
|
|
558
|
-
|
|
559
|
-
Returns:
|
|
560
|
-
A list of 3 floats, or [0.0, 0.0, 0.0] if not found
|
|
561
|
-
"""
|
|
562
|
-
loc = self.get_uniform_location(name)
|
|
563
|
-
if loc != -1:
|
|
564
|
-
result = (ctypes.c_float * 3)()
|
|
565
|
-
gl.glGetUniformfv(self._id, loc, result)
|
|
566
|
-
return list(result)
|
|
567
|
-
return [0.0, 0.0, 0.0]
|
|
568
|
-
|
|
569
|
-
def get_uniform_4f(self, name: str) -> List[float]:
|
|
570
|
-
"""
|
|
571
|
-
Get a vec4 uniform value.
|
|
572
|
-
|
|
573
|
-
Args:
|
|
574
|
-
name: The name of the uniform variable
|
|
575
|
-
|
|
576
|
-
Returns:
|
|
577
|
-
A list of 4 floats, or [0.0, 0.0, 0.0, 0.0] if not found
|
|
578
|
-
"""
|
|
579
|
-
loc = self.get_uniform_location(name)
|
|
580
|
-
if loc != -1:
|
|
581
|
-
result = (ctypes.c_float * 4)()
|
|
582
|
-
gl.glGetUniformfv(self._id, loc, result)
|
|
583
|
-
return list(result)
|
|
584
|
-
return [0.0, 0.0, 0.0, 0.0]
|
|
585
|
-
|
|
586
|
-
def get_uniform_mat2(self, name: str) -> List[float]:
|
|
587
|
-
"""
|
|
588
|
-
Get a mat2 uniform value.
|
|
589
|
-
|
|
590
|
-
Args:
|
|
591
|
-
name: The name of the uniform variable
|
|
592
|
-
|
|
593
|
-
Returns:
|
|
594
|
-
A list of 4 floats representing the 2x2 matrix, or zeros if not found
|
|
595
|
-
"""
|
|
596
|
-
loc = self.get_uniform_location(name)
|
|
597
|
-
if loc != -1:
|
|
598
|
-
result = (ctypes.c_float * 4)()
|
|
599
|
-
gl.glGetUniformfv(self._id, loc, result)
|
|
600
|
-
return list(result)
|
|
601
|
-
return [0.0] * 4
|
|
602
|
-
|
|
603
|
-
def get_uniform_mat3(self, name: str) -> List[float]:
|
|
604
|
-
"""
|
|
605
|
-
Get a mat3 uniform value.
|
|
606
|
-
|
|
607
|
-
Args:
|
|
608
|
-
name: The name of the uniform variable
|
|
609
|
-
|
|
610
|
-
Returns:
|
|
611
|
-
A list of 9 floats representing the 3x3 matrix, or zeros if not found
|
|
612
|
-
"""
|
|
613
|
-
loc = self.get_uniform_location(name)
|
|
614
|
-
if loc != -1:
|
|
615
|
-
result = (ctypes.c_float * 9)()
|
|
616
|
-
gl.glGetUniformfv(self._id, loc, result)
|
|
617
|
-
return list(result)
|
|
618
|
-
return [0.0] * 9
|
|
619
|
-
|
|
620
|
-
def get_uniform_mat4(self, name: str) -> List[float]:
|
|
621
|
-
"""
|
|
622
|
-
Get a mat4 uniform value.
|
|
623
|
-
|
|
624
|
-
Args:
|
|
625
|
-
name: The name of the uniform variable
|
|
626
|
-
|
|
627
|
-
Returns:
|
|
628
|
-
A list of 16 floats representing the 4x4 matrix, or zeros if not found
|
|
629
|
-
"""
|
|
630
|
-
loc = self.get_uniform_location(name)
|
|
631
|
-
if loc != -1:
|
|
632
|
-
result = (ctypes.c_float * 16)()
|
|
633
|
-
gl.glGetUniformfv(self._id, loc, result)
|
|
634
|
-
return list(result)
|
|
635
|
-
return [0.0] * 16
|
|
636
|
-
|
|
637
|
-
def get_uniform_mat4x3(self, name: str) -> List[float]:
|
|
638
|
-
"""
|
|
639
|
-
Get a mat4x3 uniform value.
|
|
640
|
-
|
|
641
|
-
Args:
|
|
642
|
-
name: The name of the uniform variable
|
|
643
|
-
|
|
644
|
-
Returns:
|
|
645
|
-
A list of 12 floats representing the 4x3 matrix, or zeros if not found
|
|
646
|
-
"""
|
|
647
|
-
loc = self.get_uniform_location(name)
|
|
648
|
-
if loc != -1:
|
|
649
|
-
result = (ctypes.c_float * 12)()
|
|
650
|
-
gl.glGetUniformfv(self._id, loc, result)
|
|
651
|
-
return list(result)
|
|
652
|
-
return [0.0] * 12
|
|
653
|
-
|
|
654
|
-
def get_uniform_block_data(self, name: str) -> Optional[Dict[str, Any]]:
|
|
655
|
-
"""
|
|
656
|
-
Get uniform block data by name.
|
|
657
|
-
|
|
658
|
-
Args:
|
|
659
|
-
name: The name of the uniform block
|
|
660
|
-
|
|
661
|
-
Returns:
|
|
662
|
-
Dictionary containing uniform block data, or None if not found
|
|
663
|
-
"""
|
|
664
|
-
"""Get uniform block data by name"""
|
|
665
|
-
return self._registered_uniform_blocks.get(name, None)
|
|
666
|
-
|
|
667
|
-
def get_registered_uniform_blocks(self) -> Dict[str, Dict[str, Any]]:
|
|
668
|
-
"""
|
|
669
|
-
Get all registered uniform blocks.
|
|
670
|
-
|
|
671
|
-
Returns:
|
|
672
|
-
A copy of the registered uniform blocks dictionary
|
|
673
|
-
"""
|
|
674
|
-
"""Get all registered uniform blocks"""
|
|
675
|
-
return self._registered_uniform_blocks.copy()
|
|
676
|
-
|
|
677
|
-
def get_uniform_block_location(self, name: str) -> int:
|
|
678
|
-
"""
|
|
679
|
-
Get uniform block location by name.
|
|
680
|
-
|
|
681
|
-
Args:
|
|
682
|
-
name: The name of the uniform block
|
|
683
|
-
|
|
684
|
-
Returns:
|
|
685
|
-
The uniform block index/location, or -1 if not found
|
|
686
|
-
"""
|
|
687
|
-
"""Get uniform block location by name"""
|
|
688
|
-
if name in self._registered_uniform_blocks:
|
|
689
|
-
return self._registered_uniform_blocks[name]["loc"]
|
|
690
|
-
else:
|
|
691
|
-
logger.warning(f"Uniform block '{name}' not found in shader '{self._name}'")
|
|
692
|
-
return -1
|
|
693
|
-
|
|
694
|
-
def get_uniform_block_buffer(self, name: str) -> int:
|
|
695
|
-
"""
|
|
696
|
-
Get uniform block buffer by name.
|
|
697
|
-
|
|
698
|
-
Args:
|
|
699
|
-
name: The name of the uniform block
|
|
700
|
-
|
|
701
|
-
Returns:
|
|
702
|
-
The OpenGL buffer ID, or 0 if not found
|
|
703
|
-
"""
|
|
704
|
-
"""Get uniform block buffer by name"""
|
|
705
|
-
if name in self._registered_uniform_blocks:
|
|
706
|
-
return self._registered_uniform_blocks[name]["buffer"]
|
|
707
|
-
else:
|
|
708
|
-
logger.warning(f"Uniform block '{name}' not found in shader '{self._name}'")
|
|
709
|
-
return 0
|
|
710
|
-
|
|
711
|
-
def get_gl_type_string(self, gl_type: int) -> str:
|
|
712
|
-
"""
|
|
713
|
-
Convert OpenGL type constant to human-readable string.
|
|
714
|
-
|
|
715
|
-
Args:
|
|
716
|
-
gl_type: OpenGL type constant (e.g., GL_FLOAT, GL_FLOAT_VEC3)
|
|
717
|
-
|
|
718
|
-
Returns:
|
|
719
|
-
str: Human-readable type string
|
|
720
|
-
"""
|
|
721
|
-
type_map = {
|
|
722
|
-
gl.GL_FLOAT: "float",
|
|
723
|
-
gl.GL_FLOAT_VEC2: "vec2",
|
|
724
|
-
gl.GL_FLOAT_VEC3: "vec3",
|
|
725
|
-
gl.GL_FLOAT_VEC4: "vec4",
|
|
726
|
-
gl.GL_DOUBLE: "double",
|
|
727
|
-
gl.GL_INT: "int",
|
|
728
|
-
gl.GL_UNSIGNED_INT: "unsigned int",
|
|
729
|
-
gl.GL_BOOL: "bool",
|
|
730
|
-
gl.GL_FLOAT_MAT2: "mat2",
|
|
731
|
-
gl.GL_FLOAT_MAT3: "mat3",
|
|
732
|
-
gl.GL_FLOAT_MAT4: "mat4",
|
|
733
|
-
gl.GL_SAMPLER_2D: "sampler2D",
|
|
734
|
-
gl.GL_SAMPLER_CUBE: "samplerCube",
|
|
735
|
-
}
|
|
736
|
-
return type_map.get(gl_type, f"Unknown type {gl_type}")
|
|
737
|
-
|
|
738
|
-
def print_registered_uniforms(self) -> None:
|
|
739
|
-
"""
|
|
740
|
-
Print information about all registered uniforms to the log.
|
|
741
|
-
"""
|
|
742
|
-
logger.info(f"Registered uniforms for {self._name}:")
|
|
743
|
-
base_uniforms = {}
|
|
744
|
-
array_elements = {}
|
|
745
|
-
|
|
746
|
-
# Separate base uniforms from array elements
|
|
747
|
-
for name, (location, uniform_type, size, is_array) in self._uniforms.items():
|
|
748
|
-
if "[" in name and "]" in name:
|
|
749
|
-
# This is an array element
|
|
750
|
-
base_name = name.split("[")[0]
|
|
751
|
-
if base_name not in array_elements:
|
|
752
|
-
array_elements[base_name] = []
|
|
753
|
-
array_elements[base_name].append(
|
|
754
|
-
(name, location, uniform_type, size, is_array)
|
|
755
|
-
)
|
|
756
|
-
else:
|
|
757
|
-
base_uniforms[name] = (location, uniform_type, size, is_array)
|
|
758
|
-
|
|
759
|
-
# Print base uniforms
|
|
760
|
-
for name, (location, uniform_type, size, is_array) in base_uniforms.items():
|
|
761
|
-
type_str = self.get_gl_type_string(uniform_type)
|
|
762
|
-
if is_array:
|
|
763
|
-
logger.info(
|
|
764
|
-
f" {name}[{size}] (type: {type_str}, location: {location})"
|
|
765
|
-
)
|
|
766
|
-
else:
|
|
767
|
-
logger.info(f" {name} (type: {type_str}, location: {location})")
|
|
768
|
-
|
|
769
|
-
# Print array elements grouped by base name
|
|
770
|
-
for base_name, elements in array_elements.items():
|
|
771
|
-
logger.info(f" Array elements for {base_name}:")
|
|
772
|
-
for element_name, location, uniform_type, size, is_array in elements:
|
|
773
|
-
type_str = self.get_gl_type_string(uniform_type)
|
|
774
|
-
logger.info(
|
|
775
|
-
f" {element_name} (type: {type_str}, location: {location})"
|
|
776
|
-
)
|
|
777
|
-
|
|
778
|
-
def print_registered_uniform_blocks(self) -> None:
|
|
779
|
-
"""
|
|
780
|
-
Print information about all registered uniform blocks to the log.
|
|
781
|
-
"""
|
|
782
|
-
logger.info(f"Registered uniform blocks for {self._name}:")
|
|
783
|
-
for name, data in self._registered_uniform_blocks.items():
|
|
784
|
-
logger.info(f" {name} (index: {data['loc']}, buffer: {data['buffer']})")
|
|
785
|
-
|
|
786
|
-
def print_properties(self) -> None:
|
|
787
|
-
"""
|
|
788
|
-
Print detailed properties and status information about this shader program.
|
|
789
|
-
"""
|
|
790
|
-
logger.info(f"Properties for shader program {self._name}:")
|
|
791
|
-
logger.info(f" ID: {self._id}")
|
|
792
|
-
|
|
793
|
-
link_status = gl.glGetProgramiv(self._id, gl.GL_LINK_STATUS)
|
|
794
|
-
logger.info(f" Link status: {link_status}")
|
|
795
|
-
|
|
796
|
-
validate_status = gl.glGetProgramiv(self._id, gl.GL_VALIDATE_STATUS)
|
|
797
|
-
logger.info(f" Validate status: {validate_status}")
|
|
798
|
-
|
|
799
|
-
attached_shaders = gl.glGetProgramiv(self._id, gl.GL_ATTACHED_SHADERS)
|
|
800
|
-
logger.info(f" Attached shaders: {attached_shaders}")
|
|
801
|
-
|
|
802
|
-
active_attributes = gl.glGetProgramiv(self._id, gl.GL_ACTIVE_ATTRIBUTES)
|
|
803
|
-
logger.info(f" Active attributes: {active_attributes}")
|
|
804
|
-
|
|
805
|
-
active_uniforms = gl.glGetProgramiv(self._id, gl.GL_ACTIVE_UNIFORMS)
|
|
806
|
-
logger.info(f" Active uniforms: {active_uniforms}")
|
|
807
|
-
|
|
808
|
-
active_uniform_blocks = gl.glGetProgramiv(self._id, gl.GL_ACTIVE_UNIFORM_BLOCKS)
|
|
809
|
-
logger.info(f" Active uniform blocks: {active_uniform_blocks}")
|
|
810
|
-
|
|
811
|
-
if self._registered_uniform_blocks:
|
|
812
|
-
logger.info(" Registered uniform blocks:")
|
|
813
|
-
for name, data in self._registered_uniform_blocks.items():
|
|
814
|
-
logger.info(
|
|
815
|
-
f" {name} (index: {data['loc']}, buffer: {data['buffer']})"
|
|
816
|
-
)
|