[1198] | 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 |
---|