0
# Shaders
1
2
Modern OpenGL shader support providing utilities for compiling, linking, and managing vertex and fragment shaders. Includes error handling, uniform management, and integration with PyOpenGL's array system for high-performance graphics programming.
3
4
## Capabilities
5
6
### Shader Compilation
7
8
High-level utilities for compiling GLSL shader source code with comprehensive error reporting.
9
10
```python { .api }
11
def compileShader(source: str, shaderType) -> int:
12
"""
13
Compile GLSL shader source code.
14
15
Parameters:
16
- source: GLSL shader source code string
17
- shaderType: Shader type (GL_VERTEX_SHADER, GL_FRAGMENT_SHADER, etc.)
18
19
Returns:
20
Compiled shader object identifier
21
22
Raises:
23
ShaderCompilationError: If compilation fails with error details
24
"""
25
26
def compileProgram(*shaders) -> int:
27
"""
28
Link compiled shaders into a shader program.
29
30
Parameters:
31
- shaders: Variable number of compiled shader objects
32
33
Returns:
34
Linked shader program identifier
35
36
Raises:
37
ShaderLinkError: If linking fails with error details
38
"""
39
40
class ShaderCompilationError(Exception):
41
"""
42
Exception raised when shader compilation fails.
43
Contains detailed error information from GLSL compiler.
44
"""
45
46
def __init__(self, message: str, shader_type: int, source: str):
47
"""
48
Parameters:
49
- message: Compiler error message
50
- shader_type: Type of shader that failed
51
- source: Original shader source code
52
"""
53
54
class ShaderLinkError(Exception):
55
"""
56
Exception raised when shader program linking fails.
57
Contains detailed error information from GLSL linker.
58
"""
59
```
60
61
### Shader Program Management
62
63
Functions for using and managing shader programs with uniform variable support.
64
65
```python { .api }
66
def glUseProgram(program: int):
67
"""
68
Install shader program as part of rendering state.
69
70
Parameters:
71
- program: Shader program identifier, or 0 to use fixed-function pipeline
72
"""
73
74
def glDeleteShader(shader: int):
75
"""
76
Delete shader object.
77
78
Parameters:
79
- shader: Shader object identifier
80
"""
81
82
def glDeleteProgram(program: int):
83
"""
84
Delete shader program.
85
86
Parameters:
87
- program: Shader program identifier
88
"""
89
90
def glGetProgramiv(program: int, pname: int) -> int:
91
"""
92
Get shader program parameter.
93
94
Parameters:
95
- program: Shader program identifier
96
- pname: Parameter name (GL_LINK_STATUS, GL_ACTIVE_UNIFORMS, etc.)
97
98
Returns:
99
Parameter value
100
"""
101
102
def glGetShaderiv(shader: int, pname: int) -> int:
103
"""
104
Get shader object parameter.
105
106
Parameters:
107
- shader: Shader object identifier
108
- pname: Parameter name (GL_COMPILE_STATUS, GL_SHADER_TYPE, etc.)
109
110
Returns:
111
Parameter value
112
"""
113
114
def glGetProgramInfoLog(program: int) -> str:
115
"""
116
Get shader program information log.
117
118
Parameters:
119
- program: Shader program identifier
120
121
Returns:
122
Information log string (linking errors, warnings, etc.)
123
"""
124
125
def glGetShaderInfoLog(shader: int) -> str:
126
"""
127
Get shader object information log.
128
129
Parameters:
130
- shader: Shader object identifier
131
132
Returns:
133
Information log string (compilation errors, warnings, etc.)
134
"""
135
```
136
137
### Uniform Variables
138
139
Uniform variable location and value management for passing data to shaders.
140
141
```python { .api }
142
def glGetUniformLocation(program: int, name: str) -> int:
143
"""
144
Get uniform variable location.
145
146
Parameters:
147
- program: Shader program identifier
148
- name: Uniform variable name in shader
149
150
Returns:
151
Uniform location identifier, or -1 if not found
152
"""
153
154
# Scalar uniform functions
155
def glUniform1f(location: int, v0: float):
156
"""Set single float uniform value."""
157
158
def glUniform2f(location: int, v0: float, v1: float):
159
"""Set 2-component float uniform value."""
160
161
def glUniform3f(location: int, v0: float, v1: float, v2: float):
162
"""Set 3-component float uniform value."""
163
164
def glUniform4f(location: int, v0: float, v1: float, v2: float, v3: float):
165
"""Set 4-component float uniform value."""
166
167
def glUniform1i(location: int, v0: int):
168
"""Set single integer uniform value."""
169
170
def glUniform2i(location: int, v0: int, v1: int):
171
"""Set 2-component integer uniform value."""
172
173
def glUniform3i(location: int, v0: int, v1: int, v2: int):
174
"""Set 3-component integer uniform value."""
175
176
def glUniform4i(location: int, v0: int, v1: int, v2: int, v3: int):
177
"""Set 4-component integer uniform value."""
178
179
# Array uniform functions
180
def glUniform1fv(location: int, count: int, value: list):
181
"""
182
Set array of float uniform values.
183
184
Parameters:
185
- location: Uniform location
186
- count: Number of elements to modify
187
- value: Array of float values
188
"""
189
190
def glUniform2fv(location: int, count: int, value: list):
191
"""Set array of 2-component float uniform values."""
192
193
def glUniform3fv(location: int, count: int, value: list):
194
"""Set array of 3-component float uniform values."""
195
196
def glUniform4fv(location: int, count: int, value: list):
197
"""Set array of 4-component float uniform values."""
198
199
def glUniform1iv(location: int, count: int, value: list):
200
"""Set array of integer uniform values."""
201
202
def glUniform2iv(location: int, count: int, value: list):
203
"""Set array of 2-component integer uniform values."""
204
205
def glUniform3iv(location: int, count: int, value: list):
206
"""Set array of 3-component integer uniform values."""
207
208
def glUniform4iv(location: int, count: int, value: list):
209
"""Set array of 4-component integer uniform values."""
210
211
# Matrix uniform functions
212
def glUniformMatrix2fv(location: int, count: int, transpose: bool, value: list):
213
"""
214
Set 2x2 matrix uniform values.
215
216
Parameters:
217
- location: Uniform location
218
- count: Number of matrices to modify
219
- transpose: Whether to transpose matrices
220
- value: Matrix values in column-major order
221
"""
222
223
def glUniformMatrix3fv(location: int, count: int, transpose: bool, value: list):
224
"""Set 3x3 matrix uniform values."""
225
226
def glUniformMatrix4fv(location: int, count: int, transpose: bool, value: list):
227
"""Set 4x4 matrix uniform values."""
228
```
229
230
### Vertex Attributes
231
232
Vertex attribute management for modern shader-based rendering.
233
234
```python { .api }
235
def glGetAttribLocation(program: int, name: str) -> int:
236
"""
237
Get vertex attribute location.
238
239
Parameters:
240
- program: Shader program identifier
241
- name: Attribute variable name in shader
242
243
Returns:
244
Attribute location identifier, or -1 if not found
245
"""
246
247
def glVertexAttribPointer(index: int, size: int, type: int, normalized: bool,
248
stride: int, pointer):
249
"""
250
Define vertex attribute array.
251
252
Parameters:
253
- index: Attribute location
254
- size: Components per attribute (1, 2, 3, or 4)
255
- type: Data type (GL_FLOAT, GL_INT, etc.)
256
- normalized: Whether to normalize integer values
257
- stride: Byte offset between attributes
258
- pointer: Array data or buffer offset
259
"""
260
261
def glEnableVertexAttribArray(index: int):
262
"""
263
Enable vertex attribute array.
264
265
Parameters:
266
- index: Attribute location to enable
267
"""
268
269
def glDisableVertexAttribArray(index: int):
270
"""
271
Disable vertex attribute array.
272
273
Parameters:
274
- index: Attribute location to disable
275
"""
276
277
def glVertexAttrib1f(index: int, x: float):
278
"""Set single-component vertex attribute value."""
279
280
def glVertexAttrib2f(index: int, x: float, y: float):
281
"""Set 2-component vertex attribute value."""
282
283
def glVertexAttrib3f(index: int, x: float, y: float, z: float):
284
"""Set 3-component vertex attribute value."""
285
286
def glVertexAttrib4f(index: int, x: float, y: float, z: float, w: float):
287
"""Set 4-component vertex attribute value."""
288
```
289
290
### Shader Information Query
291
292
Functions for querying shader and program properties.
293
294
```python { .api }
295
def glGetActiveUniform(program: int, index: int) -> tuple:
296
"""
297
Get information about active uniform variable.
298
299
Parameters:
300
- program: Shader program identifier
301
- index: Uniform index (0 to GL_ACTIVE_UNIFORMS-1)
302
303
Returns:
304
Tuple of (size, type, name) where:
305
- size: Array size (1 for non-arrays)
306
- type: Variable type (GL_FLOAT, GL_FLOAT_VEC3, etc.)
307
- name: Variable name string
308
"""
309
310
def glGetActiveAttrib(program: int, index: int) -> tuple:
311
"""
312
Get information about active vertex attribute.
313
314
Parameters:
315
- program: Shader program identifier
316
- index: Attribute index (0 to GL_ACTIVE_ATTRIBUTES-1)
317
318
Returns:
319
Tuple of (size, type, name)
320
"""
321
322
def glGetShaderSource(shader: int) -> str:
323
"""
324
Get shader source code.
325
326
Parameters:
327
- shader: Shader object identifier
328
329
Returns:
330
Shader source code string
331
"""
332
```
333
334
## Usage Examples
335
336
### Basic Vertex and Fragment Shader
337
```python
338
from OpenGL.GL import *
339
from OpenGL.GL import shaders
340
import numpy as np
341
342
# Vertex shader source
343
vertex_shader_source = """
344
#version 330 core
345
layout (location = 0) in vec3 aPos;
346
layout (location = 1) in vec3 aColor;
347
348
out vec3 vertexColor;
349
uniform mat4 transform;
350
351
void main() {
352
gl_Position = transform * vec4(aPos, 1.0);
353
vertexColor = aColor;
354
}
355
"""
356
357
# Fragment shader source
358
fragment_shader_source = """
359
#version 330 core
360
in vec3 vertexColor;
361
out vec4 FragColor;
362
363
uniform float alpha;
364
365
void main() {
366
FragColor = vec4(vertexColor, alpha);
367
}
368
"""
369
370
try:
371
# Compile shaders
372
vertex_shader = shaders.compileShader(vertex_shader_source, GL_VERTEX_SHADER)
373
fragment_shader = shaders.compileShader(fragment_shader_source, GL_FRAGMENT_SHADER)
374
375
# Link program
376
shader_program = shaders.compileProgram(vertex_shader, fragment_shader)
377
378
# Clean up shader objects (no longer needed after linking)
379
glDeleteShader(vertex_shader)
380
glDeleteShader(fragment_shader)
381
382
except shaders.ShaderCompilationError as e:
383
print(f"Shader compilation failed: {e}")
384
except shaders.ShaderLinkError as e:
385
print(f"Shader linking failed: {e}")
386
387
# Get uniform locations
388
transform_loc = glGetUniformLocation(shader_program, "transform")
389
alpha_loc = glGetUniformLocation(shader_program, "alpha")
390
391
# Use shader program
392
glUseProgram(shader_program)
393
394
# Set uniform values
395
transform_matrix = np.eye(4, dtype=np.float32)
396
glUniformMatrix4fv(transform_loc, 1, GL_FALSE, transform_matrix)
397
glUniform1f(alpha_loc, 1.0)
398
```
399
400
### Vertex Attribute Setup
401
```python
402
# Vertex data with positions and colors
403
vertices = np.array([
404
# Positions # Colors
405
-0.5, -0.5, 0.0, 1.0, 0.0, 0.0, # Bottom left, red
406
0.5, -0.5, 0.0, 0.0, 1.0, 0.0, # Bottom right, green
407
0.0, 0.5, 0.0, 0.0, 0.0, 1.0 # Top center, blue
408
], dtype=np.float32)
409
410
from OpenGL.arrays import vbo
411
412
# Create VBO
413
vertex_buffer = vbo.VBO(vertices)
414
415
# Setup vertex attributes
416
with vertex_buffer:
417
# Position attribute (location 0)
418
glEnableVertexAttribArray(0)
419
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * 4, vertex_buffer)
420
421
# Color attribute (location 1)
422
glEnableVertexAttribArray(1)
423
color_offset = vertex_buffer + 12 # Offset 3 floats * 4 bytes
424
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * 4, color_offset)
425
426
# Draw triangle
427
glDrawArrays(GL_TRIANGLES, 0, 3)
428
429
# Cleanup
430
glDisableVertexAttribArray(0)
431
glDisableVertexAttribArray(1)
432
```
433
434
### Animated Uniforms
435
```python
436
import math
437
import time
438
439
# Animation loop
440
start_time = time.time()
441
442
def render_frame():
443
current_time = time.time() - start_time
444
445
# Animated rotation matrix
446
angle = current_time * 2.0 # 2 radians per second
447
cos_a = math.cos(angle)
448
sin_a = math.sin(angle)
449
450
rotation_matrix = np.array([
451
[cos_a, -sin_a, 0.0, 0.0],
452
[sin_a, cos_a, 0.0, 0.0],
453
[0.0, 0.0, 1.0, 0.0],
454
[0.0, 0.0, 0.0, 1.0]
455
], dtype=np.float32)
456
457
# Update uniform
458
glUseProgram(shader_program)
459
glUniformMatrix4fv(transform_loc, 1, GL_FALSE, rotation_matrix)
460
461
# Animated alpha
462
alpha = (math.sin(current_time * 3.0) + 1.0) * 0.5 # 0.0 to 1.0
463
glUniform1f(alpha_loc, alpha)
464
465
# Render geometry
466
render_triangle()
467
```
468
469
### Error Handling
470
```python
471
def safe_compile_shader(source, shader_type):
472
try:
473
return shaders.compileShader(source, shader_type)
474
except shaders.ShaderCompilationError as e:
475
print(f"Compilation Error in {shader_type}:")
476
print(f"Error: {e}")
477
print("Source code:")
478
for i, line in enumerate(source.split('\n'), 1):
479
print(f"{i:3}: {line}")
480
return None
481
482
def safe_link_program(*shader_objects):
483
try:
484
return shaders.compileProgram(*shader_objects)
485
except shaders.ShaderLinkError as e:
486
print(f"Linking Error: {e}")
487
return None
488
```
489
490
## Constants
491
492
### Shader Types
493
```python { .api }
494
GL_VERTEX_SHADER: int
495
GL_FRAGMENT_SHADER: int
496
GL_GEOMETRY_SHADER: int # OpenGL 3.2+
497
GL_TESS_CONTROL_SHADER: int # OpenGL 4.0+
498
GL_TESS_EVALUATION_SHADER: int # OpenGL 4.0+
499
GL_COMPUTE_SHADER: int # OpenGL 4.3+
500
```
501
502
### Shader Parameters
503
```python { .api }
504
GL_COMPILE_STATUS: int
505
GL_DELETE_STATUS: int
506
GL_INFO_LOG_LENGTH: int
507
GL_SHADER_SOURCE_LENGTH: int
508
GL_SHADER_TYPE: int
509
```
510
511
### Program Parameters
512
```python { .api }
513
GL_LINK_STATUS: int
514
GL_VALIDATE_STATUS: int
515
GL_ACTIVE_UNIFORMS: int
516
GL_ACTIVE_ATTRIBUTES: int
517
GL_ACTIVE_UNIFORM_MAX_LENGTH: int
518
GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: int
519
```
520
521
### Uniform Types
522
```python { .api }
523
GL_FLOAT: int
524
GL_FLOAT_VEC2: int
525
GL_FLOAT_VEC3: int
526
GL_FLOAT_VEC4: int
527
GL_INT: int
528
GL_INT_VEC2: int
529
GL_INT_VEC3: int
530
GL_INT_VEC4: int
531
GL_BOOL: int
532
GL_BOOL_VEC2: int
533
GL_BOOL_VEC3: int
534
GL_BOOL_VEC4: int
535
GL_FLOAT_MAT2: int
536
GL_FLOAT_MAT3: int
537
GL_FLOAT_MAT4: int
538
GL_SAMPLER_2D: int
539
GL_SAMPLER_CUBE: int
540
```