%PDF- %PDF-
Direktori : /usr/share/doc/python3-freetype/examples/ |
Current File : //usr/share/doc/python3-freetype/examples/shader.py |
#!/usr/bin/env python # -*- coding: utf-8 -*- # ----------------------------------------------------------------------------- # Copyright (C) 2009-2010 Nicolas P. Rougier # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. # ----------------------------------------------------------------------------- # # Copyright Tristam Macdonald 2008. # # Distributed under the Boost Software License, Version 1.0 # (see http://www.boost.org/LICENSE_1_0.txt) # ''' Base shader class. Example: -------- shader = Shader() shader.bind() glActiveTexture(GL_TEXTURE1) glBindTexture(lut.target, lut.id) shader.uniformi('lut', 1) glActiveTexture(GL_TEXTURE0) glBindTexture(texture.target, texture.id) shader.uniformi('texture', 0) shader.uniformf('pixel', 1.0/texture.width, 1.0/texture.height) texture.blit(x,y,w,h) shader.unbind() ''' import os import OpenGL.GL as gl import ctypes class Shader: ''' Base shader class. ''' def __init__(self, vert = None, frag = None, name=''): ''' vert, frag and geom take arrays of source strings the arrays will be concatenated into one string by OpenGL.''' self.uniforms = {} self.name = name # create the program handle self.handle = gl.glCreateProgram() # we are not linked yet self.linked = False # create the vertex shader self._build_shader(vert, gl.GL_VERTEX_SHADER) # create the fragment shader self._build_shader(frag, gl.GL_FRAGMENT_SHADER) # the geometry shader will be the same, once pyglet supports the # extension self.createShader(frag, GL_GEOMETRY_SHADER_EXT) attempt to # link the program self._link() def _build_shader(self, strings, stype): ''' Actual building of the shader ''' count = len(strings) # if we have no source code, ignore this shader if count < 1: return # create the shader handle shader = gl.glCreateShader(stype) # Upload shader code gl.glShaderSource(shader, strings) # compile the shader gl.glCompileShader(shader) # retrieve the compile status status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) # if compilation failed, print the log if not status: # display the log print (gl.glGetShaderInfoLog(shader)) else: # all is well, so attach the shader to the program gl.glAttachShader(self.handle, shader) def _link(self): ''' Link the program ''' gl.glLinkProgram(self.handle) # retrieve the link status temp = ctypes.c_int(0) gl.glGetProgramiv(self.handle, gl.GL_LINK_STATUS, ctypes.byref(temp)) # if linking failed, print the log if not temp: # retrieve the log length gl.glGetProgramiv(self.handle, gl.GL_INFO_LOG_LENGTH, ctypes.byref(temp)) # create a buffer for the log #buffer = ctypes.create_string_buffer(temp.value) # retrieve the log text log = gl.glGetProgramInfoLog(self.handle) #, temp, None, buffer) # print the log to the console print (log) else: # all is well, so we are linked self.linked = True def bind(self): ''' Bind the program, i.e. use it. ''' gl.glUseProgram(self.handle) def unbind(self): ''' Unbind whatever program is currently bound - not necessarily this program, so this should probably be a class method instead. ''' gl.glUseProgram(0) def uniformf(self, name, *vals): ''' Uploads float uniform(s), program must be currently bound. ''' loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name)) self.uniforms[name] = loc # Check there are 1-4 values if len(vals) 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(vals)](loc, *vals) def uniformi(self, name, *vals): ''' Upload integer uniform(s), program must be currently bound. ''' loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name)) self.uniforms[name] = loc # Checks there are 1-4 values if len(vals) in range(1, 5): # Selects the correct function { 1 : gl.glUniform1i, 2 : gl.glUniform2i, 3 : gl.glUniform3i, 4 : gl.glUniform4i # Retrieves uniform location, and set it }[len(vals)](loc, *vals) def uniform_matrixf(self, name, mat): ''' Upload uniform matrix, program must be currently bound. ''' loc = self.uniforms.get(name, gl.glGetUniformLocation(self.handle,name)) self.uniforms[name] = loc # Upload the 4x4 floating point matrix gl.glUniformMatrix4fv(loc, 1, False, (ctypes.c_float * 16)(*mat))