| import ctypes |
| import pyglet.gl as gl |
|
|
| class Shader_error(Exception): |
| def __init__(self, message): |
| self.message = message |
|
|
| def create_shader(target, source_path): |
| |
|
|
| source_file = open(source_path, "rb") |
| source = source_file.read() |
| source_file.close() |
|
|
| source_length = ctypes.c_int(len(source) + 1) |
| source_buffer = ctypes.create_string_buffer(source) |
|
|
| buffer_pointer = ctypes.cast( |
| ctypes.pointer(ctypes.pointer(source_buffer)), |
| ctypes.POINTER(ctypes.POINTER(ctypes.c_char))) |
| |
| |
|
|
| gl.glShaderSource(target, 1, buffer_pointer, ctypes.byref(source_length)) |
| gl.glCompileShader(target) |
|
|
| |
|
|
| log_length = gl.GLint(0) |
| gl.glGetShaderiv(target, gl.GL_INFO_LOG_LENGTH, ctypes.byref(log_length)) |
|
|
| log_buffer = ctypes.create_string_buffer(log_length.value) |
| gl.glGetShaderInfoLog(target, log_length, None, log_buffer) |
|
|
| if log_length.value > 1: |
| raise Shader_error(str(log_buffer.value)) |
|
|
| class Shader: |
| def __init__(self, vert_path, frag_path): |
| self.program = gl.glCreateProgram() |
|
|
| |
|
|
| self.vert_shader = gl.glCreateShader(gl.GL_VERTEX_SHADER) |
| create_shader(self.vert_shader, vert_path) |
| gl.glAttachShader(self.program, self.vert_shader) |
|
|
| |
|
|
| self.frag_shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) |
| create_shader(self.frag_shader, frag_path) |
| gl.glAttachShader(self.program, self.frag_shader) |
|
|
| |
|
|
| gl.glLinkProgram(self.program) |
|
|
| gl.glDeleteShader(self.vert_shader) |
| gl.glDeleteShader(self.frag_shader) |
| |
| def __del__(self): |
| gl.glDeleteProgram(self.program) |
|
|
| def find_uniform(self, name): |
| return gl.glGetUniformLocation(self.program, ctypes.create_string_buffer(name)) |
| |
| def uniform_matrix(self, location, matrix): |
| gl.glUniformMatrix4fv(location, 1, gl.GL_FALSE, (gl.GLfloat * 16) (*sum(matrix.data, []))) |
|
|
| def use(self): |
| gl.glUseProgram(self.program) |
|
|