def _mark_active_attributes(self): """ Mark which attributes are active and set the location. Called after linking. """ count = gl.glGetProgramiv(self.handle, gl.GL_ACTIVE_ATTRIBUTES) # This match a name of the form "name[size]" (= array) regex = re.compile("""(?P<name>\w+)\s*(\[(?P<size>\d+)\])""") # Find active attributes self._active_attributes = {} for i in range(count): name, size, gtype = gl.glGetActiveAttrib(self.handle, i) loc = gl.glGetAttribLocation(self._handle, name) name = name.decode('utf-8') # This checks if the attribute is an array # Name will be something like xxx[0] instead of xxx m = regex.match(name) # When attribute is an array, size corresponds to the highest used index if m: name = m.group('name') if size >= 1: for i in range(size): name = '%s[%d]' % (m.group('name'),i) self._active_attributes[name] = loc else: self._active_attributes[name] = loc # Mark these as active (loc non-None means active) for attribute in self._attributes.values(): attribute._loc = self._active_attributes.get(attribute.name, None)
def on_initialize(self, event): gl.glClearColor(1,1,1,1) gl.glEnable(gl.GL_DEPTH_TEST) # Create shader program self._prog_handle = gl.glCreateProgram() # Create vertex shader shader = gl.glCreateShader(gl.GL_VERTEX_SHADER) gl.glShaderSource(shader, VERT_CODE) gl.glCompileShader(shader) status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Vertex shader did not compile.') else: gl.glAttachShader(self._prog_handle, shader) # Create fragment shader shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) gl.glShaderSource(shader, FRAG_CODE) gl.glCompileShader(shader) status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Fragment shader did not compile.') else: gl.glAttachShader(self._prog_handle, shader) # Link gl.glLinkProgram(self._prog_handle) status = gl.glGetProgramiv(self._prog_handle, gl.GL_LINK_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Program did not link.') # Create texture im = io.crate() self._tex_handle = gl.glGenTextures(1) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) gl.glBindTexture(gl.GL_TEXTURE_2D, self._tex_handle) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, im.shape[1], im.shape[0], 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, im) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) if use_buffers: # Create vertex buffer self._positions_handle = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._positions_handle) gl.glBufferData(gl.GL_ARRAY_BUFFER, positions.nbytes, positions, gl.GL_DYNAMIC_DRAW) # self._texcoords_handle = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._texcoords_handle) gl.glBufferData(gl.GL_ARRAY_BUFFER, texcoords.nbytes, texcoords, gl.GL_DYNAMIC_DRAW) # Create buffer for faces self._faces_handle = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._faces_handle) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, faces.nbytes, faces, gl.GL_DYNAMIC_DRAW)
def _mark_active_attributes(self): """ Mark which attributes are active and set the location. Called after linking. """ count = gl.glGetProgramiv(self.handle, gl.GL_ACTIVE_ATTRIBUTES) # This match a name of the form "name[size]" (= array) regex = re.compile("""(?P<name>\w+)\s*(\[(?P<size>\d+)\])""") # Find active attributes self._active_attributes = {} for i in range(count): name, size, gtype = gl.glGetActiveAttrib(self.handle, i) loc = gl.glGetAttribLocation(self._handle, name) name = name.decode('utf-8') # This checks if the attribute is an array # Name will be something like xxx[0] instead of xxx m = regex.match(name) # When attribute is an array, size corresponds to the highest used index if m: name = m.group('name') if size >= 1: for i in range(size): name = '%s[%d]' % (m.group('name'), i) self._active_attributes[name] = loc else: self._active_attributes[name] = loc # Mark these as active (loc non-None means active) for attribute in self._attributes.values(): attribute._loc = self._active_attributes.get(attribute.name, None)
def on_initialize(self, event): gl.glClearColor(0, 0, 0, 1) # Enable blending gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE) # Note: normal GL requires these lines, ES 2.0 does not from OpenGL import GL gl.glEnable(GL.GL_VERTEX_PROGRAM_POINT_SIZE) gl.glEnable(GL.GL_POINT_SPRITE) # Create shader program self._prog_handle = gl.glCreateProgram() # Create vertex shader shader = gl.glCreateShader(gl.GL_VERTEX_SHADER) gl.glShaderSource(shader, VERT_CODE) gl.glCompileShader(shader) status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Vertex shader did not compile.') else: gl.glAttachShader(self._prog_handle, shader) # Create fragment shader shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) gl.glShaderSource(shader, FRAG_CODE) gl.glCompileShader(shader) status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Fragment shader did not compile.') else: gl.glAttachShader(self._prog_handle, shader) # Link gl.glLinkProgram(self._prog_handle) status = gl.glGetProgramiv(self._prog_handle, gl.GL_LINK_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Program did not link.') # Create texture self._tex_handle = gl.glGenTextures(1) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) gl.glBindTexture(gl.GL_TEXTURE_2D, self._tex_handle) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_LUMINANCE, im1.shape[1], im1.shape[0], 0, gl.GL_LUMINANCE, gl.GL_FLOAT, im1.astype(np.float32)) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) # Create vertex buffer self._vbo_handle = gl.glGenBuffers(1)
def link_shader_program(vertex_shader, fragment_shader): program = gl.glCreateProgram() gl.glAttachShader(program, vertex_shader) gl.glAttachShader(program, fragment_shader) gl.glLinkProgram(program) result = gl.glGetProgramiv(program, gl.GL_LINK_STATUS) if not (result): raise RuntimeError(gl.glGetProgramInfoLog(program)) return program
def link_shader_program(vertex_shader, fragment_shader): program = gl.glCreateProgram() gl.glAttachShader(program, vertex_shader) gl.glAttachShader(program, fragment_shader) gl.glLinkProgram(program) result = gl.glGetProgramiv(program, gl.GL_LINK_STATUS) if not(result): raise RuntimeError(gl.glGetProgramInfoLog(program)) return program
def on_initialize(self, event): gl.glClearColor(0,0,0,1); # Enable blending gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE) # Note: normal GL requires these lines, ES 2.0 does not from OpenGL import GL gl.glEnable(GL.GL_VERTEX_PROGRAM_POINT_SIZE) gl.glEnable(GL.GL_POINT_SPRITE) # Create shader program self._prog_handle = gl.glCreateProgram() # Create vertex shader shader = gl.glCreateShader(gl.GL_VERTEX_SHADER) gl.glShaderSource(shader, VERT_CODE) gl.glCompileShader(shader) status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Vertex shader did not compile.') else: gl.glAttachShader(self._prog_handle, shader) # Create fragment shader shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) gl.glShaderSource(shader, FRAG_CODE) gl.glCompileShader(shader) status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Fragment shader did not compile.') else: gl.glAttachShader(self._prog_handle, shader) # Link gl.glLinkProgram(self._prog_handle) status = gl.glGetProgramiv(self._prog_handle, gl.GL_LINK_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Program did not link.') # Create texture self._tex_handle = gl.glGenTextures(1) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) gl.glBindTexture(gl.GL_TEXTURE_2D, self._tex_handle) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_LUMINANCE, im1.shape[1], im1.shape[0], 0, gl.GL_LUMINANCE, gl.GL_FLOAT, im1.astype(np.float32)) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) # Create vertex buffer self._vbo_handle = gl.glGenBuffers(1)
def _update(self): """ Called when the object is activated and the _need_update flag is set """ # Check if we have something to link if not self._verts: raise ProgramError("No vertex shader has been given") if not self._frags: raise ProgramError("No fragment shader has been given") # Detach any attached shaders attached = gl.glGetAttachedShaders(self._handle) for handle in attached: gl.glDetachShader(self._handle, handle) # Attach and activate vertex and fragment shaders for shader in self.shaders: shader.activate() gl.glAttachShader(self._handle, shader.handle) # Only proceed if all shaders compiled ok oks = [shader._valid for shader in self.shaders] if not (oks and all(oks)): raise ProgramError('Shaders did not compile.') # Link the program # todo: should there be a try-except around this? gl.glLinkProgram(self._handle) if not gl.glGetProgramiv(self._handle, gl.GL_LINK_STATUS): errors = gl.glGetProgramInfoLog(self._handle) errormsg = self._get_error(errors, 4) #parse_shader_errors(errors) raise ProgramError('Error linking %r:\n'%self + errormsg) # Mark all active attributes and uniforms self._mark_active_attributes() self._mark_active_uniforms() # Invalidate all uniforms and attributes for var in self._uniforms.values(): var.invalidate() for var in self._attributes.values(): var.invalidate()
def _mark_active_uniforms(self): """ Mark which uniforms are actve and set the location, for textures also set texture unit. Called after linking. """ count = gl.glGetProgramiv(self.handle, gl.GL_ACTIVE_UNIFORMS) # This match a name of the form "name[size]" (= array) regex = re.compile("""(?P<name>\w+)\s*(\[(?P<size>\d+)\])\s*""") # Find active uniforms self._active_uniforms = {} for i in range(count): name, size, gtype = gl.glGetActiveUniform(self.handle, i) loc = gl.glGetUniformLocation(self._handle, name) name = name.decode('utf-8') # This checks if the uniform is an array # Name will be something like xxx[0] instead of xxx m = regex.match(name) # When uniform is an array, size corresponds to the highest used index if m: name = m.group('name') if size >= 1: for i in range(size): name = '%s[%d]' % (m.group('name'),i) self._active_uniforms[name] = loc else: self._active_uniforms[name] = loc # Mark these as active (loc non-None means active) texture_count = 0 for uniform in self._uniforms.values(): uniform._loc = self._active_uniforms.get(uniform.name, None) if uniform._loc is not None: if uniform._textureClass: uniform._texture_unit = texture_count texture_count += 1
def _update(self): """ Called when the object is activated and the _need_update flag is set """ # Check if we have something to link if not self._verts: raise ProgramError("No vertex shader has been given") if not self._frags: raise ProgramError("No fragment shader has been given") # Detach any attached shaders attached = gl.glGetAttachedShaders(self._handle) for handle in attached: gl.glDetachShader(self._handle, handle) # Attach and activate vertex and fragment shaders for shader in self.shaders: shader.activate() gl.glAttachShader(self._handle, shader.handle) # Only proceed if all shaders compiled ok oks = [shader._valid for shader in self.shaders] if not (oks and all(oks)): raise ProgramErrorr('Shaders did not compile.') # Link the program # todo: should there be a try-except around this? gl.glLinkProgram(self._handle) if not gl.glGetProgramiv(self._handle, gl.GL_LINK_STATUS): errors = gl.glGetProgramInfoLog(self._handle) print(errors) #parse_shader_errors(errors) raise ProgramError('Linking error') # Mark all active attributes and uniforms self._mark_active_attributes() self._mark_active_uniforms()
def _mark_active_uniforms(self): """ Mark which uniforms are actve and set the location, for textures also set texture unit. Called after linking. """ count = gl.glGetProgramiv(self.handle, gl.GL_ACTIVE_UNIFORMS) # This match a name of the form "name[size]" (= array) regex = re.compile("""(?P<name>\w+)\s*(\[(?P<size>\d+)\])\s*""") # Find active uniforms self._active_uniforms = {} for i in range(count): name, size, gtype = gl.glGetActiveUniform(self.handle, i) loc = gl.glGetUniformLocation(self._handle, name) name = name.decode('utf-8') # This checks if the uniform is an array # Name will be something like xxx[0] instead of xxx m = regex.match(name) # When uniform is an array, size corresponds to the highest used index if m: name = m.group('name') if size >= 1: for i in range(size): name = '%s[%d]' % (m.group('name'), i) self._active_uniforms[name] = loc else: self._active_uniforms[name] = loc # Mark these as active (loc non-None means active) texture_count = 0 for uniform in self._uniforms.values(): uniform._loc = self._active_uniforms.get(uniform.name, None) if uniform._loc is not None: if uniform._textureClass: uniform._texture_unit = texture_count texture_count += 1
def on_initialize(self, event): gl.glClearColor(1, 1, 1, 1) gl.glEnable(gl.GL_DEPTH_TEST) # Create shader program self._prog_handle = gl.glCreateProgram() # Create vertex shader shader = gl.glCreateShader(gl.GL_VERTEX_SHADER) gl.glShaderSource(shader, VERT_CODE) gl.glCompileShader(shader) status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Vertex shader did not compile.') else: gl.glAttachShader(self._prog_handle, shader) # Create fragment shader shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) gl.glShaderSource(shader, FRAG_CODE) gl.glCompileShader(shader) status = gl.glGetShaderiv(shader, gl.GL_COMPILE_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Fragment shader did not compile.') else: gl.glAttachShader(self._prog_handle, shader) # Link gl.glLinkProgram(self._prog_handle) status = gl.glGetProgramiv(self._prog_handle, gl.GL_LINK_STATUS) if not status: # We could show more useful info here, but that takes a few lines raise RuntimeError('Program did not link.') # Create texture im = io.crate() self._tex_handle = gl.glGenTextures(1) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) gl.glBindTexture(gl.GL_TEXTURE_2D, self._tex_handle) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, im.shape[1], im.shape[0], 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, im) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameter(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) if use_buffers: # Create vertex buffer self._positions_handle = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._positions_handle) gl.glBufferData(gl.GL_ARRAY_BUFFER, positions.nbytes, positions, gl.GL_DYNAMIC_DRAW) # self._texcoords_handle = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._texcoords_handle) gl.glBufferData(gl.GL_ARRAY_BUFFER, texcoords.nbytes, texcoords, gl.GL_DYNAMIC_DRAW) # Create buffer for faces self._faces_handle = gl.glGenBuffers(1) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._faces_handle) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, faces.nbytes, faces, gl.GL_DYNAMIC_DRAW)