-
Notifications
You must be signed in to change notification settings - Fork 1
/
shader.py
75 lines (55 loc) · 2.01 KB
/
shader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from OpenGL.GL import *
import sys
def load_shader(shaderName: str):
code: str = ""
try:
with open(file=shaderName, mode='r') as f:
for line in f:
code += line
except Exception as e:
print(e, file=sys.stderr)
exit(-1)
return code
def create_shader(shaderType, sourceCode: str):
shader = glCreateShader(shaderType)
glShaderSource(shader, sourceCode)
glCompileShader(shader)
if not glGetShaderiv(shader, GL_COMPILE_STATUS):
print(f"{shaderType}:\n{glGetShaderInfoLog(shader)}", file=sys.stderr)
exit(-1)
return shader
def link_program(vertexShader, fragmentShader):
program = glCreateProgram()
glAttachShader(program, vertexShader)
glAttachShader(program, fragmentShader)
glLinkProgram(program)
if not glGetProgramiv(program, GL_LINK_STATUS):
print(f"Link status:\n{glGetProgramInfoLog(program)}", file=sys.stderr)
exit(-1)
glDeleteShader(vertexShader)
glDeleteShader(fragmentShader)
return program
class Shader:
def __init__(self, vertexShaderPath: str,
fragmentShaderPath: str,
shaderName: str = None):
vertexCode = load_shader(vertexShaderPath)
fragmentCode = load_shader(fragmentShaderPath)
vertexShader = create_shader(GL_VERTEX_SHADER, vertexCode)
fragmentShader = create_shader(GL_FRAGMENT_SHADER, fragmentCode)
self.program = link_program(vertexShader, fragmentShader)
self.name = shaderName
if shaderName is None:
self.name = f"Shader[{self.program}]"
def getUniformLocation(self, name: str):
loc = glGetUniformLocation(self.program, name)
if loc == -1:
print(f"{self}: location {name} not found", file=sys.stderr)
return loc
def use(self):
glUseProgram(self.program)
def __str__(self):
return self.name
def __del__(self):
if hasattr(self, 'program'):
glDeleteProgram(self.program)