1 | import OpenGL.GL as gl
|
---|
2 | import os
|
---|
3 | import glm
|
---|
4 |
|
---|
5 | class ShaderProgram:
|
---|
6 | def __init__(self, vertexFile: str, fragmentFile: str, geometryFile: str = None) -> None:
|
---|
7 | self.initShaderFromGLSL(vertexFile, fragmentFile, geometryFile)
|
---|
8 | self.programID = gl.glCreateProgram()
|
---|
9 | gl.glAttachShader(self.programID, self.vs)
|
---|
10 | gl.glAttachShader(self.programID, self.fs)
|
---|
11 | if geometryFile:
|
---|
12 | gl.glAttachShader(self.programID, self.gs)
|
---|
13 |
|
---|
14 | def start(self):
|
---|
15 | gl.glUseProgram(self.programID)
|
---|
16 |
|
---|
17 | def stop(self):
|
---|
18 | gl.glUseProgram(0)
|
---|
19 |
|
---|
20 | def cleanUp(self):
|
---|
21 | self.stop()
|
---|
22 | gl.glDetachShader(self.programID, self.vs)
|
---|
23 | gl.glDetachShader(self.programID, self.fs)
|
---|
24 | gl.glDeleteShader(self.vs)
|
---|
25 | gl.glDeleteShader(self.fs)
|
---|
26 | gl.glDeleteProgram(self.programID)
|
---|
27 |
|
---|
28 | def bindAttributes(self):
|
---|
29 | pass
|
---|
30 |
|
---|
31 | def getAllUniformLocations(self):
|
---|
32 | pass
|
---|
33 |
|
---|
34 | def getUniformLocation(self, uniformName):
|
---|
35 | return gl.glGetUniformLocation(self.programID, uniformName)
|
---|
36 |
|
---|
37 | def bindAttribute(self, attribute: int, variableName: str):
|
---|
38 | gl.glBindAttribLocation(self.programID, attribute, variableName)
|
---|
39 |
|
---|
40 | def loadFloat(self, location: int, value: float):
|
---|
41 | gl.glUniform1f(location, value)
|
---|
42 |
|
---|
43 | def loadInt(self, location: int, value: int):
|
---|
44 | gl.glUniform1i(location, value)
|
---|
45 |
|
---|
46 | def loadVector3(self, location: int, value):
|
---|
47 | gl.glUniform3fv(location, 1, glm.value_ptr(value))
|
---|
48 |
|
---|
49 | def loadVector2(self, location: int, value):
|
---|
50 | gl.glUniform2fv(location, 1, glm.value_ptr(value))
|
---|
51 |
|
---|
52 | def loadVector4(self, location: int, value):
|
---|
53 | gl.glUniform4fv(location, 1, glm.value_ptr(value))
|
---|
54 |
|
---|
55 | def loadBool(self, location: int, value: bool):
|
---|
56 | gl.glUniform1f(location, value == 1)
|
---|
57 |
|
---|
58 | def loadMatrix4(self, location: int, value):
|
---|
59 | gl.glUniformMatrix4fv(location, 1, False, glm.value_ptr(value))
|
---|
60 |
|
---|
61 | def initShaderFromGLSL(self, vertex_shader_path, fragment_shader_path, geometry_shader_path = None):
|
---|
62 | vertex_shader_source_list = []
|
---|
63 | fragment_shader_source_list = []
|
---|
64 | geometry_shader_source_list = []
|
---|
65 | if(isinstance(vertex_shader_path, str)):
|
---|
66 | absDIR = os.path.abspath(os.path.join(os.path.join(os.path.dirname(__file__), ".."), vertex_shader_path))
|
---|
67 | f = open(absDIR, 'rb')
|
---|
68 | vertex_shader_source_list.append(f.read())
|
---|
69 | f.close()
|
---|
70 |
|
---|
71 | absDIR = os.path.abspath(os.path.join(os.path.join(os.path.dirname(__file__), ".."), fragment_shader_path))
|
---|
72 | f = open(absDIR, 'rb')
|
---|
73 | fragment_shader_source_list.append(f.read())
|
---|
74 | f.close()
|
---|
75 |
|
---|
76 | if geometry_shader_path:
|
---|
77 | absDIR = os.path.abspath(os.path.join(os.path.join(os.path.dirname(__file__), ".."), geometry_shader_path))
|
---|
78 | f = open(absDIR, 'rb')
|
---|
79 | geometry_shader_source_list.append(f.read())
|
---|
80 | f.close()
|
---|
81 |
|
---|
82 | self.initShader(vertex_shader_source_list, fragment_shader_source_list, geometry_shader_source_list)
|
---|
83 |
|
---|
84 | def initShader(self, vertex_shader_source_list, fragment_shader_source_list, geometry_shader_source_list):
|
---|
85 | # create program
|
---|
86 | self.program = gl.glCreateProgram() # pylint: disable=E1111
|
---|
87 | #print('create program ',self.program)
|
---|
88 | ShaderProgram.printOpenGLError()
|
---|
89 |
|
---|
90 | # vertex shader
|
---|
91 | #print('compile vertex shader...')
|
---|
92 | self.vs = gl.glCreateShader(gl.GL_VERTEX_SHADER) # pylint: disable=E1111
|
---|
93 | gl.glShaderSource(self.vs, vertex_shader_source_list)
|
---|
94 | gl.glCompileShader(self.vs)
|
---|
95 | if gl.GL_TRUE != gl.glGetShaderiv(self.vs, gl.GL_COMPILE_STATUS):
|
---|
96 | err = gl.glGetShaderInfoLog(self.vs)
|
---|
97 | raise Exception(err)
|
---|
98 | #gl.glAttachShader(self.program, self.vs)
|
---|
99 | ShaderProgram.printOpenGLError()
|
---|
100 |
|
---|
101 | # fragment shader
|
---|
102 | #print('compile fragment shader...')
|
---|
103 | self.fs = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) # pylint: disable=E1111
|
---|
104 | gl.glShaderSource(self.fs, fragment_shader_source_list)
|
---|
105 | gl.glCompileShader(self.fs)
|
---|
106 | if gl.GL_TRUE!=gl.glGetShaderiv(self.fs, gl.GL_COMPILE_STATUS):
|
---|
107 | err = gl.glGetShaderInfoLog(self.fs)
|
---|
108 | raise Exception(err)
|
---|
109 | #gl.glAttachShader(self.program, self.fs)
|
---|
110 | ShaderProgram.printOpenGLError()
|
---|
111 |
|
---|
112 | if geometry_shader_source_list:
|
---|
113 | self.gs = gl.glCreateShader(gl.GL_GEOMETRY_SHADER) # pylint: disable=E1111
|
---|
114 | gl.glShaderSource(self.gs, geometry_shader_source_list)
|
---|
115 | gl.glCompileShader(self.gs)
|
---|
116 | if gl.GL_TRUE!=gl.glGetShaderiv(self.gs, gl.GL_COMPILE_STATUS):
|
---|
117 | err = gl.glGetShaderInfoLog(self.gs)
|
---|
118 | print(err.decode("utf-8"))
|
---|
119 | raise Exception(err)
|
---|
120 | #gl.glAttachShader(self.program, self.gs)
|
---|
121 | ShaderProgram.printOpenGLError()
|
---|
122 |
|
---|
123 | #print('link...')
|
---|
124 | #gl.glLinkProgram(self.program)
|
---|
125 | #if(gl.GL_TRUE != gl.glGetProgramiv(self.program, gl.GL_LINK_STATUS)):
|
---|
126 | # err = gl.glGetShaderInfoLog(self.vs)
|
---|
127 | # raise Exception(err)
|
---|
128 | #printOpenGLError()
|
---|
129 |
|
---|
130 | @staticmethod
|
---|
131 | def printOpenGLError():
|
---|
132 | err = gl.glGetError() # pylint: disable=E1111
|
---|
133 | if (err != gl.GL_NO_ERROR):
|
---|
134 | print('GLERROR: ', gl.gluErrorString(err)) # pylint: disable=E1101 |
---|