def set_uniform(self, name, value): name = name.encode() valtype = type(value) if valtype == bool or valtype == int: glUniform1i(glGetUniformLocation(self.shader, name), int(value)) elif valtype == float: glUniform1f(glGetUniformLocation(self.shader, name), value) # elif valtype == VECTOR2_TYPE: # glUniform2fv(glGetUniformLocation(self.shader, name), 1, value) elif valtype == VECTOR3_TYPE: glUniform3fv(glGetUniformLocation(self.shader, name), 1, c_float(value[0]), c_float(value[1]), c_float(value[2])) elif valtype == VECTOR4_TYPE: glUniform4fv(glGetUniformLocation(self.shader, name), 1, c_float(value[0]), c_float(value[1]), c_float(value[2]), c_float(value[3])) elif valtype == MATRIX3_TYPE: glUniformMatrix3fv( glGetUniformLocation(self.shader, name), 1, GL_FALSE, c_float(value[0][0])) # Should this be value[0][0]? elif valtype == MATRIX4_TYPE: glUniformMatrix4fv( glGetUniformLocation(self.shader, name), 1, GL_FALSE, c_float(value[0][0])) # Should this be value[0][0]?
def load_uniform_floats(self, **uniforms): self._assert_bound() for name, data in uniforms.items(): if isinstance(data, (float, int)): glUniform1f(self.uniform[name], data) else: functions = glUniform2f, glUniform3f, glUniform4f functions[len(data) - 2](self.uniform[name], *data)
def draw(self): self.c = 0 daylight_multiplier = self.daylight / 1800 gl.glClearColor(0.5 * (daylight_multiplier - 0.26), 0.8 * (daylight_multiplier - 0.26), (daylight_multiplier - 0.26) * 1.36, 1.0) gl.glUniform1f(self.shader_daylight_location, daylight_multiplier) for render_chunk in self.visible_chunks: render_chunk.draw(gl.GL_TRIANGLES) self.draw_translucent()
def setFloat(self, name, value): if type(name) is not bytes: name = bytes(name, 'utf-8') loc = GL.glGetUniformLocation(self.handle, name) if not hasattr(value, '__len__'): GL.glUniform1f(loc, value) elif len(value) in range(1, 5): # Select the correct function { 1 : GL.glUniform1f, 2 : GL.glUniform2f, 3 : GL.glUniform3f, 4 : GL.glUniform4f # Retrieve uniform location, and set it }[len(value)](loc, *value) else: raise ValueError("Shader.setInt '{}' should be length 1-4 not {}" .format(name, len(value)))
def draw(self, uniforms, entities, models, textures=(), lights=(), *args, **kwargs): glUseProgram(self) # PREPARE SHADER glUniformMatrix4fv( # ctypes.data_as must be here and not at initialization. self.uniforms[b'perspective'], 1, GL_TRUE, uniforms.get(b'perspective').ctypes.data_as(POINTER(GLfloat)) ) glUniformMatrix4fv( self.uniforms[b'view'], 1, GL_TRUE, uniforms.get(b'view').ctypes.data_as(POINTER(GLfloat)) ) for i, entity in enumerate(lights): glUniform3f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].position'], *entity.location) glUniform3f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].color'], *entity.color) glUniform1f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].constant'], entity.attenuation[0]) glUniform1f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].linear'], entity.attenuation[1]) glUniform1f(self.uniforms[b'light[' + bytes(str(i), 'utf-8') + b'].quadratic'], entity.attenuation[1]) # PREPARE MODELS for model_index, texture_mapping in self.entities.items(): model = models[model_index] model.enable() # PREPARE TEXTURES glActiveTexture(GL_TEXTURE0) glActiveTexture(GL_TEXTURE0 + 1) for texture_list, entity_list in texture_mapping.items(): if hasattr(texture_list, '__iter__'): glBindTexture(GL_TEXTURE_2D, textures[0]) glUniform1i(self.uniforms[b'diffuse_texture'], 0) glBindTexture(GL_TEXTURE_2D, textures[1]) glUniform1i(self.uniforms[b'specular_texture'], 1) # textures[0].enable(slot=0) # textures[1].enable(slot=1) else: textures[texture_list].enable(slot=0) glUniform1i(self.uniforms[b'diffuse_texture'], 0) # PREPARE ENTITIES for entity in entity_list: glUniformMatrix4fv( self.uniforms[b'transformation'], 1, GL_TRUE, entity.get_transformation_matrix().ctypes.data_as(POINTER(GLfloat)) ) model.draw() glBindBuffer(GL_ARRAY_BUFFER, 0) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) glBindTexture(GL_TEXTURE_2D, 0) glDisableVertexAttribArray(0) glDisableVertexAttribArray(1) glDisableVertexAttribArray(2)
def render_to_texture(in_size, out_size, view_z=None): z0, z1 = (0, in_size[2]) if view_z == None else view_z vertices = (VERTEX * 6)(((-1, -1), (0, 0)), ((1, -1), (1, 0)), ((1, 1), (1, 1)), ((1, 1), (1, 1)), ((-1, 1), (0, 1)), ((-1, -1), (0, 0))) gl.glBindTexture(gl.GL_TEXTURE_3D, rendered_texture) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) gl.glViewport(0, 0, out_size[0], out_size[1]) gl.glUseProgram(render_program) loc_depth = gl.glGetUniformLocation(render_program, ctypes.create_string_buffer(b'depth')) loc_texelSize = gl.glGetUniformLocation( render_program, ctypes.create_string_buffer(b'texelSize')) gl.glUniform3f(loc_texelSize, 1 / in_size[0], 1 / in_size[1], 1 / in_size[2]) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(vertices), vertices, gl.GL_DYNAMIC_DRAW) gl.glBindVertexArray(render_vao) gl.glClearColor(0.0, 0.0, 0.0, 0.0) for z in range(out_size[2]): gl.glFramebufferTexture3D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_3D, rendered_texture, 0, z) fbs = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) assert fbs == gl.GL_FRAMEBUFFER_COMPLETE, 'FramebufferStatus is {}'.format( fbs) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glUniform1f(loc_depth, (z0 + z * (z1 - z0)) / in_size[2] / out_size[2]) gl.glBindTexture(gl.GL_TEXTURE_3D, input_texture) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) if z % 10 == 0: gl.glFinish() print('\033[K{}/{}'.format(z, out_size[2] - 1), end='\r') gl.glFinish() gl.glBindVertexArray(0)
def __init__(self, frames): #consider bumping opengl version if apple supports it #amdgpu-mesa currently supports up to 4.5 super(ControledRender, self).__init__(512, 512, fullscreen=False, config=gl.Config(major_version=4, minor_version=1), visible=False) print(self.context.get_info().get_version()) self.frames = frames self.vertex_buffer = gl.GLuint(0) self.vao = gl.GLuint(0) #self.prev_program = (gl.GLint * 1)() self.dimx = args["A"].shape[0] self.dimy = args["A"].shape[1] A = args["A"].astype(np.float32) #print("A shape " + str(A.shape)) #print(str(A.dtype)) #print(A) B = args["B"].astype(np.float32) #self.dp = self.tdata.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) self.Ap = A.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) self.Bp = B.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) self.setupFBOandTextures() self.setupShaders() data = [ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ] dataGl = (gl.GLfloat * len(data))(*data) gl.glGenBuffers(1, ctypes.byref(self.vertex_buffer)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, len(dataGl) * 4, dataGl, gl.GL_STATIC_DRAW) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) gl.glUseProgram(self.programA) self.pos_posA = gl.glGetAttribLocation( self.programA, ctypes.create_string_buffer(b"a_position")) assert (self.pos_posA >= 0) gl.glEnableVertexAttribArray(self.pos_posA) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glVertexAttribPointer(self.pos_posA, 2, gl.GL_FLOAT, False, 0, 0) self.tex_pos_A_A = gl.glGetUniformLocation(self.programA, b"A") self.tex_pos_A_B = gl.glGetUniformLocation(self.programA, b"B") self.feed_pos_A = gl.glGetUniformLocation(self.programA, b"f") self.kill_pos_A = gl.glGetUniformLocation(self.programA, b"k") self.dA_pos_A = gl.glGetUniformLocation(self.programA, b"dA") self.dB_pos_A = gl.glGetUniformLocation(self.programA, b"dB") self.dt_pos_A = gl.glGetUniformLocation(self.programA, b"timestep") self.step_pos_A = gl.glGetUniformLocation(self.programA, b"step") gl.glUniform1f(self.feed_pos_A, args["feed"]) gl.glUniform1f(self.kill_pos_A, args["kill"]) gl.glUniform1f(self.dA_pos_A, args["dA"]) gl.glUniform1f(self.dB_pos_A, args["dB"]) gl.glUniform1f(self.dt_pos_A, args["dt"]) #may need changed for nonsquare textures gl.glUniform1f(self.step_pos_A, 1 / self.dimx) gl.glUseProgram(self.programB) self.pos_posB = gl.glGetAttribLocation( self.programB, ctypes.create_string_buffer(b"a_position")) assert (self.pos_posB >= 0) gl.glEnableVertexAttribArray(self.pos_posB) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glVertexAttribPointer(self.pos_posB, 2, gl.GL_FLOAT, False, 0, 0) self.tex_pos_B_A = gl.glGetUniformLocation(self.programB, b"A") self.tex_pos_B_B = gl.glGetUniformLocation(self.programB, b"B") self.feed_pos_B = gl.glGetUniformLocation(self.programB, b"f") self.kill_pos_B = gl.glGetUniformLocation(self.programB, b"k") self.dA_pos_B = gl.glGetUniformLocation(self.programB, b"dA") self.dB_pos_B = gl.glGetUniformLocation(self.programB, b"dB") self.dt_pos_B = gl.glGetUniformLocation(self.programB, b"timestep") self.step_pos_B = gl.glGetUniformLocation(self.programB, b"step") gl.glUniform1f(self.feed_pos_B, args["feed"]) gl.glUniform1f(self.kill_pos_B, args["kill"]) gl.glUniform1f(self.dA_pos_B, args["dA"]) gl.glUniform1f(self.dB_pos_B, args["dB"]) gl.glUniform1f(self.dt_pos_B, args["dt"]) #may need changed for nonsquare textures gl.glUniform1f(self.step_pos_B, 1 / self.dimx) gl.glViewport(0, 0, self.dimx, self.dimy)
def set_uniform_f(self, name, value): location = gl.glGetUniformLocation(self.program, name) gl.glUniform1f(location, value)
def __set_uniforms(self): # projection matrix (proj) proj_loc = gl.glGetUniformLocation(self.__prog.value, "proj") proj_matrix = self.__proj_matrix() proj_matrix_ptr = ct.cast( \ ct.pointer(np.ctypeslib.as_ctypes(proj_matrix)), ct.POINTER(ct.c_float) ) gl.glUniformMatrix4fv(proj_loc, 1, gl.GL_TRUE, proj_matrix_ptr) # voxel spacing voxel_spacing_loc = gl.glGetUniformLocation(self.__prog.value, "voxel_spacing") gl.glUniform3f(voxel_spacing_loc, self.__voxel_spacing[0]*self.__downsample, self.__voxel_spacing[1]*self.__downsample, self.__voxel_spacing[2]*self.__downsample) # voxel size voxel_size_loc = gl.glGetUniformLocation(self.__prog.value, "voxel_size") gl.glUniform3f(voxel_size_loc, self.__voxel_size[0]*self.__downsample, self.__voxel_size[1]*self.__downsample, self.__voxel_size[2]*self.__downsample) # data; not technically a "uniform" but a texture data_loc = gl.glGetUniformLocation(self.__prog.value, "data") gl.glUniform1i(data_loc, 0) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(gl.GL_TEXTURE_BUFFER, self.__data_texture.value) # dims dims_loc = gl.glGetUniformLocation(self.__prog.value, "dims") gl.glUniform3i(dims_loc, self.__data.shape[0]/self.__downsample, self.__data.shape[1]/self.__downsample, self.__data.shape[2]/self.__downsample) # global_opacity global_opacity_loc = gl.glGetUniformLocation(self.__prog.value, "global_opacity") gl.glUniform1f(global_opacity_loc, self.__opacity) # min value min_value_loc = gl.glGetUniformLocation(self.__prog.value, "min_value") gl.glUniform1f(min_value_loc, self.__min_value) # saturation value saturation_value_loc = gl.glGetUniformLocation(self.__prog.value, "saturation_value") gl.glUniform1f(saturation_value_loc, self.__saturation_value) # downsample downsample_loc = gl.glGetUniformLocation(self.__prog.value, "downsample") gl.glUniform1i(downsample_loc, self.__downsample)
def render_view(window): """ Render the current view to a texture. """ drawing = window.drawing view = window.view changed = False # Update the overlay with the current stroke overlay = view.overlay w, h, d = view.shape size = w, h overlay_texture = _get_overlay_texture(size) if overlay.dirty and overlay.lock.acquire(timeout=0.01): rect = overlay.dirty x0, y0, x1, y1 = rect.box() overlay_data = overlay.data[x0:x1, y0:y1].tobytes("F") gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) # Needed for writing 8bit data gl.glTextureSubImage2D(overlay_texture.name, 0, *rect.position, *rect.size, gl.GL_RGBA_INTEGER, gl.GL_UNSIGNED_BYTE, overlay_data) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 4) overlay.dirty = None overlay.lock.release() changed = True # Update the image texture data = drawing.data drawing_texture = _get_3d_texture(data.shape) if drawing.dirty: with drawing.lock: update_data = data[drawing.dirty].tobytes(order="F") sx, sy, sz = drawing.dirty drawing.dirty = None sw = sx.stop - sx.start sh = sy.stop - sy.start sd = sz.stop - sz.start gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) # Needed for writing 8bit data gl.glTextureSubImage3D(drawing_texture.name, 0, sx.start, sy.start, sz.start, sw, sh, sd, gl.GL_RED_INTEGER, gl.GL_UNSIGNED_BYTE, update_data) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 4) changed = True # Render everything to the offscreen buffer # TODO we actually should not have to redraw the offscreen_buffer unless something has changed # (e.g. drawing, overlay, palette or cursor) offscreen_buffer = _get_offscreen_buffer(size) colors = _get_colors(drawing.palette.colors) vao = _get_vao() draw_program = _get_program() empty_texture = _get_empty_texture(size) cursor_pos = d - view.index - 1 # TODO why? other_layer_alpha = 0.3 if view.show_only_current_layer or view.layer_being_switched else 1.0 T = _get_transform(view.rotation) with vao, offscreen_buffer: gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glViewport(0, 0, w, h) gl.glClearBufferfv(gl.GL_COLOR, 0, EMPTY_COLOR) with draw_program, drawing_texture: gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, (gl.GLfloat * 16)(*T)) gl.glUniform3f(1, *view.direction) gl.glUniform4fv(5, 256, colors) # Draw the layers below the current one if cursor_pos < d - 1: with empty_texture: gl.glUniform1f(2, other_layer_alpha) gl.glUniform2i(3, cursor_pos + 1, d) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) # Draw the current layer + overlay with overlay_texture: gl.glUniform1f(2, 1) gl.glUniform2i(3, cursor_pos, cursor_pos + 1) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) # Draw the layers on top if cursor_pos > 0: with empty_texture: gl.glUniform1f(2, other_layer_alpha) gl.glUniform2i(3, 0, cursor_pos) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) return offscreen_buffer
def __init__(self): #consider bumping opengl version if apple supports it #amdgpu-mesa currently supports up to 4.5 super(ControledRender, self).__init__(512, 512, fullscreen=False, config=gl.Config(major_version=4, minor_version=1), visible=False) print(self.context.get_info().get_version()) self.vertex_buffer = gl.GLuint(0) self.vao = gl.GLuint(0) #self.prev_program = (gl.GLint * 1)() self.setupFBOandTextures() self.setupShaders() data = [ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ] dataGl = (gl.GLfloat * len(data))(*data) gl.glGenBuffers(1, ctypes.byref(self.vertex_buffer)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, len(dataGl) * 4, dataGl, gl.GL_STATIC_DRAW) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) gl.glUseProgram(self.programA) self.pos_posA = gl.glGetAttribLocation( self.programA, ctypes.create_string_buffer(b"a_position")) assert (self.pos_posA >= 0) gl.glEnableVertexAttribArray(self.pos_posA) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glVertexAttribPointer(self.pos_posA, 2, gl.GL_FLOAT, False, 0, 0) if args["shape"] == "sphere": self.radius_pos = gl.glGetUniformLocation( self.programA, b"radius") self.center_pos = gl.glGetUniformLocation( self.programA, b"center") self.checkUniformLocation(self.radius_pos) self.checkUniformLocation(self.center_pos) gl.glUniform1f(self.radius_pos, args["radius"]) gl.glUniform3f(self.center_pos, args["center"][0], args["center"][1], args["center"][2]) elif args["shape"] == "cylinder": self.radius_pos = gl.glGetUniformLocation( self.programA, b"radius") self.height_pos = gl.glGetUniformLocation( self.programA, b"height") self.checkUniformLocation(self.radius_pos) self.checkUniformLocation(self.height_pos) gl.glUniform1f(self.radius_pos, args["radius"]) gl.glUniform1f(self.height_pos, args["height"]) self.slice_pos = gl.glGetUniformLocation(self.programA, b"slice") self.step_pos = gl.glGetUniformLocation(self.programA, b"step") self.checkUniformLocation(self.slice_pos) gl.glUniform1f(self.step_pos, 1 / args["resolution"]) #may need changed for nonsquare textures gl.glViewport(0, 0, args["resolution"], args["resolution"])
def render_drawing(drawing, highlighted_layer=None): """ This function has the job of rendering a drawing to a framebuffer. """ offscreen_buffer = _get_offscreen_buffer(drawing.size) colors = _get_colors(drawing.palette.as_tuple()) with vao, offscreen_buffer, draw_program: w, h = offscreen_buffer.size gl.glViewport(0, 0, w, h) gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glClearBufferfv(gl.GL_COLOR, 0, EMPTY_COLOR) overlay = drawing.overlay overlay_texture = _get_overlay_texture(overlay.size) if overlay.dirty.get(0) and overlay.lock.acquire(timeout=0.01): # Since we're drawing in a separate thread, we need to be very careful # when accessing the overlay, otherwise we can get nasty problems. # While we have the lock, the thread won't draw, so we can safely copy data. # The acquire timeout is a compromise; on one hand, we don't wait # so long that the user feels stutter, on the other hand, # if we never wait, and the draw thread is very busy, we might # not get to update for a long time. rect = overlay.dirty[0] subimage = overlay.get_subimage(rect) data = subimage.tobytes("F") # TODO Is this making another copy? # Now update the texture with the changed part of the layer. try: gl.glTextureSubImage2D(overlay_texture.name, 0, *rect.points, gl.GL_RGBA_INTEGER, gl.GL_UNSIGNED_BYTE, data) overlay.dirty.pop(0) overlay.lock.release() # Allow layer to change again. except gl.lib.GLException as e: logging.error(str(e)) frame = drawing.frame for layer in drawing.layers: if highlighted_layer and highlighted_layer != layer: continue # TODO might be a good optimization to draw the layers above and # above into two separate textures, so we don't have # to iterate over them all every frame. Also cuts down on the # number of textures in GPU memory. # Assumes the non-current textures don't change though. layer_texture = _get_layer_texture(layer, frame) if layer.dirty.get(frame) and layer.lock.acquire(timeout=0.03): rect = layer.dirty[frame] subimage = layer.get_subimage(rect, frame) data = subimage.tobytes("F") gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) # Needed for writing 8bit data gl.glTextureSubImage2D(layer_texture.name, 0, *rect.points, gl.GL_RED_INTEGER, gl.GL_UNSIGNED_BYTE, data) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 4) layer.dirty.pop(frame) layer.lock.release() if not layer.visible and highlighted_layer != layer: continue with layer_texture: if layer == drawing.current: # The overlay is combined with the layer with overlay_texture: # TODO is it possible to send the palette without converting # to float first? gl.glUniform1f(1, 1) gl.glUniform4fv(2, 256, colors) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) else: with _get_empty_texture(drawing.size): gl.glUniform1f(1, 1) gl.glUniform4fv(2, 256, colors) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) gl.glDisable(gl.GL_BLEND) return offscreen_buffer
def __init__(self): #consider bumping opengl version if apple supports it #amdgpu-mesa currently supports up to 4.5 super(ControledRender, self).__init__(512, 512, fullscreen=False, config=gl.Config(major_version=4, minor_version=1), visible=False) print(self.context.get_info().get_version()) self.vertex_buffer = gl.GLuint(0) self.vao = gl.GLuint(0) #self.prev_program = (gl.GLint * 1)() self.dimx = args["A"].shape[0] self.dimy = args["A"].shape[1] self.dimz = args["A"].shape[2] A = args["A"].astype(np.float32) #print("A shape " + str(A.shape)) #print(str(A.dtype)) #print(A) #self.dp = self.tdata.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) self.Ap = A.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) T = args["transform"].astype(np.float32) self.Tp = T.ctypes.data_as(ctypes.POINTER(ctypes.c_float)) self.setupFBOandTextures() self.setupShaders() data = [ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ] dataGl = (gl.GLfloat * len(data))(*data) gl.glGenBuffers(1, ctypes.byref(self.vertex_buffer)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, len(dataGl) * 4, dataGl, gl.GL_STATIC_DRAW) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) gl.glUseProgram(self.programA) self.pos_posA = gl.glGetAttribLocation( self.programA, ctypes.create_string_buffer(b"a_position")) assert (self.pos_posA >= 0) gl.glEnableVertexAttribArray(self.pos_posA) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glVertexAttribPointer(self.pos_posA, 2, gl.GL_FLOAT, False, 0, 0) self.tex_pos_A = gl.glGetUniformLocation(self.programA, b"A") self.transform_pos = gl.glGetUniformLocation( self.programA, b"transform") self.step_pos_A = gl.glGetUniformLocation(self.programA, b"step") self.slice_pos_A = gl.glGetUniformLocation(self.programA, b"slice") self.checkUniformLocation(self.tex_pos_A) self.checkUniformLocation(self.transform_pos) self.checkUniformLocation(self.step_pos_A) self.checkUniformLocation(self.slice_pos_A) gl.glUniformMatrix4fv(self.transform_pos, 1, True, self.Tp) #gl.glUniformMatrix4fv(self.transform_pos, 1, False, self.Tp) #may need changed for nonsquare textures gl.glUniform1f(self.step_pos_A, 1 / self.dimx) gl.glViewport(0, 0, self.dimx, self.dimy)