def from_atlas(cls, name, firstgid, file, tile_width, tile_height): image = pyglet.image.load(file) rows = image.height // tile_height columns = image.width // tile_width image_grid = pyglet.image.ImageGrid(image, rows, columns) atlas = pyglet.image.TextureGrid(image_grid) id = firstgid ts = cls(name, {}) ts.firstgid = firstgid for j in range(rows-1, -1, -1): for i in range(columns): tile_image = image.get_region(atlas[j, i].x, atlas[j, i].y, atlas[j, i].width, atlas[j, i].height) # Set texture clamping to avoid mis-rendering subpixel edges gl.glBindTexture(tile_image.texture.target, id) gl.glTexParameteri(tile_image.texture.target, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(tile_image.texture.target, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE) ts[id] = Tile(id, {}, tile_image) id += 1 return ts
def update_display(verts,tex_coords,texture=bird_texture): gl.glClearColor(0.2, 0.4, 0.5, 1.0) gl.glEnable(texture.target) gl.glBindTexture(texture.target, texture.id) gl.glPushAttrib(gl.GL_COLOR_BUFFER_BIT) gl.glEnable(gl.GL_ALPHA_TEST) gl.glAlphaFunc (gl.GL_GREATER, .1) #gl.glEnable(gl.GL_BLEND) #gl.glBlendFunc (gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glEnable(gl.GL_DEPTH_TEST) gl.glEnableClientState(gl.GL_VERTEX_ARRAY) gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY) n=len(verts[:]) #TODO verts._buffer.ctypes.data is awkward gl.glVertexPointer(3, vert_dtype.gl, 0, verts[:].ctypes.data) gl.glTexCoordPointer(3, tex_dtype.gl, 0, tex_coords[:].ctypes.data) gl.glDrawArrays(gl.GL_TRIANGLE_STRIP, 0, n) #unset state gl.glPopAttrib() gl.glDisable(texture.target)
def blit_buffer(self, framebuffer, parent_width, parent_height, **kwargs): """Draw the texture into the parent scene .. warning: This method's arguments are not part of the API yet and may change at any time. """ gl.glViewport(0, 0, parent_width, parent_height) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glBindTexture(gl.GL_TEXTURE_2D, framebuffer.texture_id) gl.glEnable(gl.GL_TEXTURE_2D) gl.glColor4fv((gl.GLfloat * 4)(*self.color + (self.opacity, ))) gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA) # premultipl. gl.glBegin(gl.GL_TRIANGLE_STRIP) gl.glTexCoord2f(0, 0) gl.glVertex2i(0, 0) gl.glTexCoord2f(0, parent_height) gl.glVertex2i(0, parent_height) gl.glTexCoord2f(parent_width, 0) gl.glVertex2i(parent_width, 0) gl.glTexCoord2f(parent_width, parent_height) gl.glVertex2i(parent_width, parent_height) gl.glEnd() gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glDisable(gl.GL_TEXTURE_2D) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glViewport(0, 0, parent_width, parent_height)
def after_draw(self, camera): """Called by CocosNode when the texture is already grabbed. The FrameBuffer will be unbound and the texture will be drawn :Parameters: `camera` : `Camera` The target's camera object. """ # capture after drawing self.grabber.after_render(self.texture) # after unbinding # set a 3d projection self._set_3d_projection() # and center the camera camera.locate(force=True) # blit gl.glEnable(self.texture.target) gl.glBindTexture(self.texture.target, self.texture.id) gl.glPushAttrib(gl.GL_COLOR_BUFFER_BIT) self._blit() gl.glPopAttrib() gl.glDisable(self.texture.target)
def data(self, buffer_type, data, offset): if buffer_type != "texture": gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffers[buffer_type]) if buffer_type == "color": offset *= 16 else: offset *= 12 gl_data = to_gl_float(data) length = len(data) * 4 gl.glBufferSubData(gl.GL_ARRAY_BUFFER, offset, length, gl_data) if buffer_type == "vertex": self.vertex_count += int(len(data) / 3) else: self.buffers["texture"] = gl.GLuint(0) gl.glGenTextures(1, self.buffers["texture"]) gl.glBindTexture(data.target, data.id) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, texture.width, texture.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, texture_data)
def set_state(self): gl.glPushMatrix() gl.glMultMatrixf(rendering.matrix_to_gl(self.transform)) if self.texture: gl.glEnable(self.texture.target) gl.glBindTexture(self.texture.target, self.texture.id)
def set_data(self, arr): arr = np.asarray(arr) self.src_format, self.dst_format = fmts_from_shape(arr.shape, self._texture_dim) # Float is default type if arr.dtype == np.uint8: arr = np.ascontiguousarray(arr) self.src_type = gl.GL_UNSIGNED_BYTE elif arr.dtype == np.float32: arr = np.ascontiguousarray(arr) self.src_type = gl.GL_FLOAT else: arr = np.astype(np.float32) self.src_type = gl.GL_FLOAT self._arr = arr if self._id: gl.glDeleteTextures(1, gl.byref(self._id)) id = gl.GLuint() gl.glGenTextures(1, gl.byref(id)) self._id = id gl.glPixelStorei (gl.GL_UNPACK_ALIGNMENT, 1) gl.glPixelStorei (gl.GL_PACK_ALIGNMENT, 1) gl.glBindTexture (self.target, self._id) gl.glTexParameterf (self.target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) gl.glTexParameterf (self.target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glTexParameterf (self.target, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP) gl.glTexParameterf (self.target, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP) self._setup_tex() self.update()
def set_state(self): gl.glBindTexture( gl.GL_TEXTURE_CUBE_MAP, self.tex_object ) gl.glTexGeni( gl.GL_S, gl.GL_TEXTURE_GEN_MODE, gl.GL_REFLECTION_MAP ) gl.glTexGeni( gl.GL_T, gl.GL_TEXTURE_GEN_MODE, gl.GL_REFLECTION_MAP ) gl.glTexGeni( gl.GL_R, gl.GL_TEXTURE_GEN_MODE, gl.GL_REFLECTION_MAP ) gl.glEnable( gl.GL_TEXTURE_CUBE_MAP ) gl.glTexEnvi( gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_DECAL )
def texture_from_data(internalformat, size, data_format, data_type, data): '''Create texture from a data buffer (whatever can be passed as pointer to ctypes) internalformat - GL_RGBA8 or GL_RGB8 recommended size - a 1-, 2- or 3-tuple describing the image sizes data_format - see 'format' parameter of glDrawPixels data_type - see 'type' parameter of glDrawPixels data - pointer to memory''' size = list(size) dimensions = len(size) binding = getattr(gl, 'GL_TEXTURE_BINDING_{0:d}D'.format(dimensions)) target = getattr(gl,'GL_TEXTURE_{0:d}D'.format(dimensions)) texImage = getattr(gl,'glTexImage{0:d}D'.format(dimensions)) oldbind = ctypes.c_uint(0) gl.glGetIntegerv(binding, ctypes.cast(ctypes.byref(oldbind), ctypes.POINTER(ctypes.c_int))) texid = ctypes.c_uint(0) gl.glEnable(target) gl.glGenTextures(1, ctypes.byref(texid)) gl.glBindTexture(target, texid) gl.glTexParameteri(target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameteri(target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) args = [target, 0, internalformat] + size + [0, data_format, data_type, data] texImage(*args) gl.glBindTexture(target, oldbind) return texid
def upload(self): ''' Upload atlas data into video memory. ''' glEnable( GL_TEXTURE_2D ) if self.texid is None: self.texid = GLuint(0) glGenTextures(1,ctypes.byref(self.texid)) glBindTexture( GL_TEXTURE_2D, self.texid ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ) glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ) if self.depth == 1: glTexImage2D( GL_TEXTURE_2D, 0, GL_ALPHA, self.width, self.height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, self.data.ctypes ) elif self.depth == 3: glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, self.width, self.height, 0, GL_RGB, GL_UNSIGNED_BYTE, self.data.ctypes ) else: glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, self.width, self.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, self.data.ctypes ) glBindTexture( GL_TEXTURE_2D, 0 )
def poll(dt): out = next(itr, False) if out is False: if args.pause: label.text = "Done. ('q' to quit)" else: pyglet.app.exit() elif out is not None: name, buf = out real_dt = time.time() - last_time[0] last_time[0] = time.time() if buf.dtype == np.uint8: fmt = gl.GL_UNSIGNED_BYTE elif buf.dtype == np.uint16: fmt = gl.GL_UNSIGNED_SHORT else: label.text = 'Unsupported format: ' + buf.dtype return h, w, ch = buf.shape gl.glEnable(tex.target) gl.glBindTexture(tex.target, tex.id) gl.glTexImage2D(tex.target, 0, gl.GL_RGB8, w, h, 0, gl.GL_RGBA, fmt, buf.tostring()) gl.glDisable(tex.target) label.text = '%s (%g fps)' % (name, 1./real_dt) else: label.text += '.'
def __init__(self, width, height, background=[255,255,255]): self.width = width self.height = height self.triangles = [] self.batch = Batch() self.bg_colour = background has_fbo = gl.gl_info.have_extension('GL_EXT_framebuffer_object') #setup a framebuffer self.fb = gl.GLuint() gl.glGenFramebuffersEXT(1, ctypes.byref(self.fb)) gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, self.fb) #allocate a texture for the fb to render to tex = image.Texture.create_for_size(gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA) gl.glBindTexture(gl.GL_TEXTURE_2D, tex.id) gl.glFramebufferTexture2DEXT(gl.GL_FRAMEBUFFER_EXT, gl.GL_COLOR_ATTACHMENT0_EXT, gl.GL_TEXTURE_2D, tex.id, 0) status = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) assert status == gl.GL_FRAMEBUFFER_COMPLETE_EXT gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, 0) self.bg = self.batch.add( 6, gl.GL_TRIANGLES,None, ("v2i/static", (0,0,0,height,width,height,width,height,width,0,0,0)), ("c3B/static",background*6) )
def _drawLUTtoScreen(self): """(private) Used to set the LUT in Bits++ mode. Should not be needed by user if attached to a ``psychopy.visual.Window()`` since this will automatically draw the LUT as part of the screen refresh. """ #push the projection matrix and set to orthorgaphic GL.glMatrixMode(GL.GL_PROJECTION) GL.glPushMatrix() GL.glLoadIdentity() GL.glOrtho( 0, self.win.size[0],self.win.size[1], 0, 0, 1 ) #this also sets the 0,0 to be top-left #but return to modelview for rendering GL.glMatrixMode(GL.GL_MODELVIEW) GL.glLoadIdentity() #draw the pixels GL.glActiveTextureARB(GL.GL_TEXTURE0_ARB) GL.glEnable(GL.GL_TEXTURE_2D) GL.glBindTexture(GL.GL_TEXTURE_2D, 0) GL.glActiveTextureARB(GL.GL_TEXTURE1_ARB) GL.glEnable(GL.GL_TEXTURE_2D) GL.glBindTexture(GL.GL_TEXTURE_2D, 0) GL.glRasterPos2i(0,1) GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1) GL.glDrawPixels(len(self._HEADandLUT),1, GL.GL_RGB,GL.GL_UNSIGNED_BYTE, self._HEADandLUTstr) #GL.glDrawPixels(524,1, GL.GL_RGB,GL.GL_UNSIGNED_BYTE, self._HEADandLUTstr) #return to 3D mode (go and pop the projection matrix) GL.glMatrixMode( GL.GL_PROJECTION ) GL.glPopMatrix() GL.glMatrixMode( GL.GL_MODELVIEW )
def buffer_texture(width, height): id_ = gl.GLuint() gl.glGenTextures(1, byref(id_)) gl.glPushAttrib(gl.GL_ENABLE_BIT | gl.GL_TEXTURE_BIT) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glEnable(gl.GL_TEXTURE_2D) gl.glBindTexture(gl.GL_TEXTURE_2D, id_) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, (gl.GLubyte * (width*height * 4))(), ) gl.glFlush() gl.glBindTexture(gl.GL_TEXTURE_2D, 0) gl.glPopAttrib() return id_
def draw(self): if self._dirty: self._context = Context() self._parts = [] self.free() self.render() self.build_vbo() self._dirty = False # set gl.glEnable(self._texture.target) gl.glBindTexture(self._texture.target, self._texture.id) gl.glPushAttrib(gl.GL_COLOR_BUFFER_BIT) gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glPushMatrix() self.transform() # cuadric.begin() self._vertex_list.draw(gl.GL_TRIANGLES) # cuadric.end() # unset gl.glPopMatrix() gl.glPopAttrib() gl.glDisable(self._texture.target)
def create_texture(self, cls, rectangle=False, force_rectangle=False): '''Create a texture containing this image. If the image's dimensions are not powers of 2, a TextureRegion of a larger Texture will be returned that matches the dimensions of this image. :Parameters: `cls` : class (subclass of Texture) Class to construct. `rectangle` : bool ``True`` if a rectangle can be created; see `AbstractImage.get_texture`. :rtype: cls or cls.region_class ''' _is_pow2 = lambda v: (v & (v - 1)) == 0 target = gl.GL_TEXTURE_2D if rectangle and not (_is_pow2(self.width) and _is_pow2(self.height)): if gl.gl_info.have_extension('GL_ARB_texture_rectangle'): target = gl.GL_TEXTURE_RECTANGLE_ARB elif gl.gl_info.have_extension('GL_NV_texture_rectangle'): target = gl.GL_TEXTURE_RECTANGLE_NV texture = cls.create_for_size(target, self.width, self.height) subimage = False if texture.width != self.width or texture.height != self.height: texture = texture.get_region(0, 0, self.width, self.height) subimage = True internalformat = self._get_internalformat(self.format) gl.glBindTexture(texture.target, texture.id) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) if subimage: width = texture.owner.width height = texture.owner.height blank = (ctypes.c_ubyte * (width * height * 4))() gl.glTexImage2D(texture.target, texture.level, internalformat, width, height, 1, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, blank) internalformat = None self.blit_to_texture(texture.target, texture.level, 0, 0, 0, internalformat) return texture
def on_draw(self): self.window.clear() gl.glMatrixMode(gl.GL_PROJECTION) gl.glPushMatrix() gl.glLoadIdentity() self.camera() gl.glEnable(self.grass.target) gl.glEnable(gl.GL_BLEND) gl.glBindTexture(self.grass.target, self.grass.id) W = 10000. graphics.draw(4, gl.GL_QUADS, ('v2f', (-W, -W, W, -W, W, W, -W, W)), ('t2f', (0., 0., W*5., 0., W*5., W*5., 0., W*5.)) ) gl.glDisable(self.grass.target) for lane in self.lanes: self.draw_lane_surface(lane) for lane in self.lanes: self.draw_lane_lines(lane) for obj in self.objects: self.draw_object(obj) for car in self.cars: if car!=self.main_car and car not in self.visible_cars: self.draw_car(self.anim_x[car], car.color) if self.heat is not None: self.draw_heatmap() for car in self.cars: if car==self.main_car or car in self.visible_cars: self.draw_car(self.anim_x[car], car.color) gl.glPopMatrix() if isinstance(self.main_car, Car): self.label.text = 'Speed: %.2f'%self.anim_x[self.main_car][3] self.label.draw() if self.output is not None: pyglet.image.get_buffer_manager().get_color_buffer().save(self.output.format(self.frame))
def __init__(self, width, height, scale=2): """ width, height: size of the window in pixels. scale: the size of the texture is (width//scale) x (height//scale). """ pyglet.window.Window.__init__(self, width, height, caption='GrayScott Simulation', visible=False, vsync=False) self.reaction_shader = Shader('./glsl/default.vert', './glsl/reaction.frag') self.render_shader = Shader('./glsl/default.vert', './glsl/render.frag') self.pattern = DEFAULT_PATTERN self.palette = DEFAULT_PALETTE self.tex_width = width // scale self.tex_height = height // scale self.uv_texture = create_uv_texture(width//scale, height//scale) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.uv_texture.target, self.uv_texture.id) # use an invisible buffer to do the computation. with FrameBuffer() as self.fbo: self.fbo.attach_texture(self.uv_texture) # why do we need this? the reason is in the 'on_mouse_drag' function. self.mouse_down = False # put all patterns in a list for iterating over them. self._species = list(SPECIES.keys()) # set the uniforms and attributes in the two shaders. self.init_reaction_shader() self.init_render_shader()
def draw(self): ''' Draw the windows. ''' self.program.use() data = list(self.root.get_data(0, 0)) data = (gl.GLfloat * len(data))(*data) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_DYNAMIC_DRAW) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(gl.GL_TEXTURE_2D, self.texture) if self.textmanager.dirty: # only upload the texture to the GPU if it has actually changed gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, # level gl.GL_R8, self.textmanager.width, self.textmanager.height, 0, gl.GL_RED, gl.GL_UNSIGNED_BYTE, ctypes.create_string_buffer(self.textmanager.img.tobytes())) self.textmanager.dirty = False self.program.uniform1i(b"tex", 0) # set to 0 because the texture is bound to GL_TEXTURE0 self.program.vertex_attrib_pointer(self.buffer, b"position", 4) # self.program.vertex_attrib_pointer(self.buffer, b"texcoord", 2, stride=4 * sizeof(gl.GLfloat), offset=2 * sizeof(gl.GLfloat)) gl.glDrawArrays(gl.GL_QUADS, 0, len(data) // 4)
def on_draw(): gl.glClearColor(1.0,1.0,1.0,1.0) window.clear() # Compute gl.glViewport(0, 0, width, height) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() gl.glOrtho(0, 1, 0, 1, -1, 1) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glActiveTexture( gl.GL_TEXTURE1 ) gl.glBindTexture(texture_s.target, texture_s.id) gl.glActiveTexture( gl.GL_TEXTURE0 ) gl.glBindTexture(texture_uv.target, texture_uv.id) gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, framebuffer) reaction_shader.bind() texture_uv.blit(x=0.0, y=0.0, width=1.0, height=1.0) reaction_shader.unbind() gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, 0) # Render gl.glViewport(0, 0, window.width, window.height) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() gl.glOrtho(0, 1, 0, 1, -1, 1) gl.glMatrixMode(gl.GL_MODELVIEW) color_shader.bind() texture_uv.blit(x=0.0, y=0.0, width=1.0, height=1.0) color_shader.bind()
def get_blocky_image(name): import pyglet.gl as gl image = pyglet.resource.image(name) gl.glBindTexture(image.target, image.id) gl.glTexParameteri(image.target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glTexParameteri(image.target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) return image
def draw(self, win=None): #set the window to draw to if win==None: win=self.win if win.winType=='pyglet': win.winHandle.switch_to() #work out next default depth if self.depth==0: thisDepth = self.win._defDepth self.win._defDepth += _depthIncrements[self.win.winType] else: thisDepth=self.depth GL.glPushMatrix() #scale and rotate prevScale = self.win.setScale(self._winScale) GL.glTranslatef(self._posRendered[0],self._posRendered[1],thisDepth)#NB depth is set already GL.glRotatef(self.ori,0.0,0.0,1.0) self.win.setScale('pix',None, prevScale) if self._useShaders: #then rgb needs to be set as glColor #setup color desiredRGB = (self.rgb*self.contrast+1)/2.0#RGB in range 0:1 and scaled for contrast if numpy.any(desiredRGB**2.0>1.0): desiredRGB=[0.6,0.6,0.4] GL.glColor4f(desiredRGB[0],desiredRGB[1],desiredRGB[2], self.opacity) else: #color is set in texture, so set glColor to white GL.glColor4f(1,1,1,1) GL.glDisable(GL.GL_DEPTH_TEST) #should text have a depth or just on top? #update list if necss and then call it if self.win.winType=='pyglet': #and align based on x anchor if self.alignHoriz=='right': GL.glTranslatef(-self.width,0,0)#NB depth is set already if self.alignHoriz in ['center', 'centre']: GL.glTranslatef(-self.width/2,0,0)#NB depth is set already #unbind the mask texture regardless GL.glActiveTexture(GL.GL_TEXTURE1) GL.glEnable(GL.GL_TEXTURE_2D) GL.glBindTexture(GL.GL_TEXTURE_2D, 0) #unbind the main texture GL.glActiveTexture(GL.GL_TEXTURE0) GL.glEnable(GL.GL_TEXTURE_2D) #then allow pyglet to bind and use texture during drawing self.glyphStr.draw() GL.glDisable(GL.GL_TEXTURE_2D) else: #for pygame we should (and can) use a drawing list if self.needUpdate: self._updateList() GL.glCallList(self._listID) GL.glEnable(GL.GL_DEPTH_TEST) # Enables Depth Testing GL.glPopMatrix()
def _updateFrameTexture(self): if self._nextFrameT is None: # movie has no current position, need to reset the clock # to zero in order to have the timing logic work # otherwise the video stream would skip frames until the # time since creating the movie object has passed self._videoClock.reset() self._nextFrameT = 0 #only advance if next frame (half of next retrace rate) if self._nextFrameT > self.duration: self._onEos() elif (self._numpyFrame is not None) and \ (self._nextFrameT > (self._videoClock.getTime()-self._retraceInterval/2.0)): return None self._numpyFrame = self._mov.get_frame(self._nextFrameT) useSubTex=self.useTexSubImage2D if self._texID is None: self._texID = GL.GLuint() GL.glGenTextures(1, ctypes.byref(self._texID)) useSubTex=False #bind the texture in openGL GL.glEnable(GL.GL_TEXTURE_2D) GL.glBindTexture(GL.GL_TEXTURE_2D, self._texID)#bind that name to the target GL.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S,GL.GL_REPEAT) #makes the texture map wrap (this is actually default anyway) GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1) # data from PIL/numpy is packed, but default for GL is 4 bytes #important if using bits++ because GL_LINEAR #sometimes extrapolates to pixel vals outside range if self.interpolate: GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR) if useSubTex is False: GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, self._numpyFrame.shape[1],self._numpyFrame.shape[0], 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, self._numpyFrame.shape[1], self._numpyFrame.shape[0], GL.GL_RGB, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_NEAREST) GL.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_NEAREST) if useSubTex is False: GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, self._numpyFrame.shape[1],self._numpyFrame.shape[0], 0, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, self._numpyFrame.shape[1], self._numpyFrame.shape[0], GL.GL_BGR, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) GL.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE)#?? do we need this - think not! if not self.status==PAUSED: self._nextFrameT += self._frameInterval
def usetTex(self, var, unit, target, tx): """ var : name of variable to write unit : texture unit target : target for glBindTexture tx : texture ID """ gl.glUniform1iARB(self.uniformLoc(var), unit) gl.glActiveTexture(gl.GL_TEXTURE0 + unit) gl.glBindTexture(target, tx)
def copy(self): ''' copy the contents of the texture to full window ''' gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0) self.program.use() gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(gl.GL_TEXTURE_2D, self.rendered_texture) self.program.uniform1i(b"tex", 0) self.program.vertex_attrib_pointer(self.vertex_buffer, b"position", 4, stride=4 * sizeof(gl.GLfloat)) gl.glDrawArrays(gl.GL_QUADS, 0, 4)
def create_uv_texture(width, height): """Create a pyglet texture instance from a numpy ndarray.""" uv_grid = np.zeros((height, width, 4), dtype=np.float32) uv_grid[:, :, 0] = 1.0 uv_grid[height//2, width//2, 1] = 1.0 texture = pyglet.image.Texture.create_for_size(gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA32F_ARB) gl.glBindTexture(texture.target, texture.id) gl.glTexImage2D(texture.target, texture.level, gl.GL_RGBA32F_ARB, width, height, 0, gl.GL_RGBA, gl.GL_FLOAT, uv_grid.ctypes.data) gl.glBindTexture(texture.target, 0) return texture
def addTexture(self, imgPath): dir, file = path.split(imgPath) if dir not in resource.path: resource.path.append(dir) resource.reindex() texture = resource.texture(file) self.textures.append(texture) gl.glBindTexture(texture.target, texture.id) gl.glGenerateMipmap(gl.GL_TEXTURE_2D) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST_MIPMAP_LINEAR)
def blit(self, x, y, w, h, z=0, s=(0,1), **kwargs): ''' Draw texture to active framebuffer. ''' gl.glEnable (gl.GL_TEXTURE_2D) gl.glDisable (gl.GL_TEXTURE_1D) gl.glBindTexture(self.target, self._id) gl.glBegin(gl.GL_QUADS) gl.glTexCoord2f(s[0], 1), gl.glVertex2f(x, y) gl.glTexCoord2f(s[0], 0), gl.glVertex2f(x, y+h) gl.glTexCoord2f(s[1], 0), gl.glVertex2f(x+w, y+h) gl.glTexCoord2f(s[1], 1), gl.glVertex2f(x+w, y) gl.glEnd()
def bind(self): """Bind the FBO. Anything drawn afterward will be stored in the FBO's texture.""" # This is called simply to deal with anything that might be currently bound (for example, Pyglet objects), gl.glBindTexture(gl.GL_TEXTURE_2D, 0) # Store current viewport size for later gl.glGetIntegerv(gl.GL_VIEWPORT, self._old_viewport_size) # Bind the FBO, and change the viewport to fit its texture. gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, self.id) # Rendering off-screen gl.glViewport(0, 0, self.texture.width, self.texture.height)
def solid_pattern(): if 'solid' in _bg_textures: return _bg_textures['solid'] data = '%c%c%c%c' % (255, 255, 255, 255) im = pyglet.image.ImageData(1, 1, 'RGBA', data) # have this image repeat gl.glBindTexture(im.texture.target, im.texture.id) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) return im
def draw(self, win=None): """Draw the current frame to a particular visual.Window (or to the default win for this object if not specified). The current position in the movie will be determined automatically. This method should be called on every frame that the movie is meant to appear. Parameters ---------- win : :class:`~psychopy.visual.Window` or None Window the video is being drawn to. If `None`, the window specified by property `win` will be used. Default is `None`. """ if (self.status == NOT_STARTED or (self.status == FINISHED and self.loop)): self.play() elif self.status == FINISHED and not self.loop: return if win is None: win = self.win self._selectWindow(win) self._updateFrameTexture() # will check if it's needed # scale the drawing frame and get to centre of field GL.glPushMatrix() # push before drawing, pop after # push the data for client attributes GL.glPushClientAttrib(GL.GL_CLIENT_ALL_ATTRIB_BITS) self.win.setScale('pix') # move to centre of stimulus and rotate vertsPix = self.verticesPix # bind textures GL.glActiveTexture(GL.GL_TEXTURE1) GL.glBindTexture(GL.GL_TEXTURE_2D, 0) GL.glEnable(GL.GL_TEXTURE_2D) GL.glActiveTexture(GL.GL_TEXTURE0) GL.glBindTexture(GL.GL_TEXTURE_2D, self._texID) GL.glEnable(GL.GL_TEXTURE_2D) # sets opacity (1,1,1 = RGB placeholder) GL.glColor4f(1, 1, 1, self.opacity) array = (GL.GLfloat * 32)( 1, 1, # texture coords vertsPix[0, 0], vertsPix[0, 1], 0., # vertex 0, 1, vertsPix[1, 0], vertsPix[1, 1], 0., 0, 0, vertsPix[2, 0], vertsPix[2, 1], 0., 1, 0, vertsPix[3, 0], vertsPix[3, 1], 0., ) # 2D texture array, 3D vertex array GL.glInterleavedArrays(GL.GL_T2F_V3F, 0, array) GL.glDrawArrays(GL.GL_QUADS, 0, 4) GL.glPopClientAttrib() GL.glPopMatrix() # unbind the textures GL.glActiveTexture(GL.GL_TEXTURE0) GL.glBindTexture(GL.GL_TEXTURE_2D, 0) GL.glEnable(GL.GL_TEXTURE_2D) # implicitly disables 1D
def create_texture(self, cls, rectangle=False, force_rectangle=False): """ Create a texture containing this image. If the image's dimensions are not powers of 2, a TextureRegion of a larger Texture will be returned that matches the dimensions of this image. :Parameters: `cls` : class (subclass of Texture) Class to construct. `rectangle` : bool ``True`` if a rectangle can be created; see `AbstractImage.get_texture`. :rtype: cls or cls.region_class """ _is_pow2 = (lambda v: (v & (v - 1)) == 0) target = gl.GL_TEXTURE_2D if (rectangle and not (_is_pow2(self.width) and _is_pow2(self.height))): if gl.gl_info.have_extension("GL_ARB_texture_rectangle"): target = gl.GL_TEXTURE_RECTANGLE_ARB elif gl.gl_info.have_extension("GL_NV_texture_rectangle"): target = gl.GL_TEXTURE_RECTANGLE_NV texture = cls.create_for_size(target, self.width, self.height) subimage = False if texture.width != self.width or texture.height != self.height: texture = texture.get_region(0, 0, self.width, self.height) subimage = True internalformat = self._get_internalformat(self.format) gl.glBindTexture(texture.target, texture.id) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR) if subimage: width = texture.owner.width height = texture.owner.height blank = (ctypes.c_ubyte * (width * height * 4))() gl.glTexImage2D( texture.target, texture.level, internalformat, width, height, 1, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, blank, ) internalformat = None self.blit_to_texture(texture.target, texture.level, 0, 0, 0, internalformat) return texture
def use(self, texture_unit: int = 0): gl.glActiveTexture(gl.GL_TEXTURE0 + texture_unit) gl.glBindTexture(gl.GL_TEXTURE_2D, self.texture_id)
def create_frame_buffers(width: int, height: int, num_samples: int) -> Tuple[int, int]: """Create the frame buffer objects""" # Create a frame buffer (rendering target) multi_fbo = gl.GLuint(0) gl.glGenFramebuffers(1, byref(multi_fbo)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, multi_fbo) # The try block here is because some OpenGL drivers # (Intel GPU drivers on macbooks in particular) do not # support multisampling on frame buffer objects # noinspection PyBroadException try: # Create a multisampled texture to render into fbTex = gl.GLuint(0) gl.glGenTextures(1, byref(fbTex)) gl.glBindTexture(gl.GL_TEXTURE_2D_MULTISAMPLE, fbTex) gl.glTexImage2DMultisample(gl.GL_TEXTURE_2D_MULTISAMPLE, num_samples, gl.GL_RGBA32F, width, height, True) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D_MULTISAMPLE, fbTex, 0) # Attach a multisampled depth buffer to the FBO depth_rb = gl.GLuint(0) gl.glGenRenderbuffers(1, byref(depth_rb)) gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, depth_rb) gl.glRenderbufferStorageMultisample(gl.GL_RENDERBUFFER, num_samples, gl.GL_DEPTH_COMPONENT, width, height) gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_RENDERBUFFER, depth_rb) except BaseException as e: # logger.warning(e=traceback.format_exc()) logger.debug("Falling back to non-multisampled frame buffer") # Create a plain texture texture to render into fbTex = gl.GLuint(0) gl.glGenTextures(1, byref(fbTex)) gl.glBindTexture(gl.GL_TEXTURE_2D, fbTex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_RGBA, gl.GL_FLOAT, None) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, fbTex, 0) # Attach depth buffer to FBO depth_rb = gl.GLuint(0) gl.glGenRenderbuffers(1, byref(depth_rb)) gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, depth_rb) gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT, width, height) gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_RENDERBUFFER, depth_rb) # Sanity check if pyglet.options["debug_gl"]: res = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) assert res == gl.GL_FRAMEBUFFER_COMPLETE # Create the frame buffer used to resolve the final render final_fbo = gl.GLuint(0) gl.glGenFramebuffers(1, byref(final_fbo)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, final_fbo) # Create the texture used to resolve the final render fbTex = gl.GLuint(0) gl.glGenTextures(1, byref(fbTex)) gl.glBindTexture(gl.GL_TEXTURE_2D, fbTex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_RGBA, gl.GL_FLOAT, None) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, fbTex, 0) if pyglet.options["debug_gl"]: res = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) assert res == gl.GL_FRAMEBUFFER_COMPLETE # Enable depth testing gl.glEnable(gl.GL_DEPTH_TEST) # Unbind the frame buffer gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0) return multi_fbo, final_fbo
def bind(self): from pyglet import gl gl.glBindTexture(self.tex.target, self.tex.id)
self.bottom_right.draw() self.left.draw() self.right.draw() self.top_right.draw() self.top_left.draw() self.top.draw() self.white_pixel.draw() self.label.draw() if __name__ == "__main__": window = pyglet.window.Window() guy_image = pyglet.image.load("./data/images/guymouthshapes/AHH.png") glEnable(guy_image.texture.target) glBindTexture(guy_image.texture.target, guy_image.texture.id) glPushAttrib(GL_COLOR_BUFFER_BIT) glEnable(GL_BLEND) glTexParameteri(guy_image.texture.target, GL_TEXTURE_MAG_FILTER, GL_NEAREST) guy = pyglet.sprite.Sprite(img=guy_image, x=15, y=10) guy.update(scale_x=4, scale_y=4) bubbles = [ # SpeechBubble(30, 350, "Hello, World!"), # SpeechBubble(30, 260, "Wow this is a longer one!"), # SpeechBubble(30, 170, "short!"), SpeechBubble(80, 40, "Bananas") ]
def draw(self, shader, models, textures): """ Dependencies are location, rotation, scale, and model (optionally texture). Args: shader: models: textures: Returns: """ attribute_location = shader.attribute_location location_location = attribute_location['position'] texture_location = attribute_location['texture_coordinate'] normal_location = attribute_location['normal'] transformation = self.transformation diffuse = self.diffuse specular = self.specular emission = self.emission for entity in numpy.where( (self.mask & World.COMPONENT_SPRITE) == World.COMPONENT_SPRITE)[0]: model = models[self.model[entity]] shader.load_uniform_matrix(transformation[entity], name='transform') glActiveTexture(GL_TEXTURE0) texture = textures[diffuse[entity]] glBindTexture(GL_TEXTURE_2D, texture.id) glActiveTexture(GL_TEXTURE0 + 1) texture = textures[specular[entity]] glBindTexture(GL_TEXTURE_2D, texture.id) glActiveTexture(GL_TEXTURE0 + 2) texture = textures[emission[entity]] glBindTexture(GL_TEXTURE_2D, texture.id) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.indexed_vbo) glBindBuffer(GL_ARRAY_BUFFER, model.vbo_array['location']) glEnableVertexAttribArray(location_location) glVertexAttribPointer(location_location, 3, GL_FLOAT, GL_FALSE, 0, 0) glBindBuffer(GL_ARRAY_BUFFER, model.vbo_array['texture_coordinate']) glEnableVertexAttribArray(texture_location) glVertexAttribPointer(texture_location, 2, GL_FLOAT, GL_FALSE, 0, 0) glBindBuffer(GL_ARRAY_BUFFER, model.vbo_array['normal']) glEnableVertexAttribArray(normal_location) glVertexAttribPointer(normal_location, 3, GL_FLOAT, GL_FALSE, 0, 0) glDrawElements(GL_TRIANGLES, model.indexed_vbo.count, GL_UNSIGNED_INT, 0) glDisableVertexAttribArray(location_location) glDisableVertexAttribArray(texture_location) glDisableVertexAttribArray(normal_location) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0)
def set_state(self): glPushAttrib(GL_ENABLE_BIT) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) glEnable(self.texture.target) glBindTexture(self.texture.target, self.texture.id)
def draw_vertex_list(vertex_list, texture): gl.glEnable(gl.GL_TEXTURE_2D) gl.glBindTexture(gl.GL_TEXTURE_2D, texture.id) vertex_list.draw(gl.GL_TRIANGLES)
def on_draw(self): """ Run the actual draw calls. """ self._update_meshes() gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glLoadIdentity() # pull the new camera transform from the scene transform_camera = self.scene.graph.get( frame_to='world', frame_from=self.scene.camera.name)[0] # apply the camera transform to the matrix stack gl.glMultMatrixf(rendering.matrix_to_gl(transform_camera)) # dragging the mouse moves the view # but doesn't alter the scene view = view_to_transform(self.view) # add the view transform to the stack gl.glMultMatrixf(rendering.matrix_to_gl(view)) # we want to render fully opaque objects first, # followed by objects which have transparency node_names = collections.deque(self.scene.graph.nodes_geometry) # how many nodes did we start with count_original = len(node_names) count = -1 # if we are rendering an axis marker at the world if self._axis: # we stored it as a vertex list self._axis.draw(mode=gl.GL_TRIANGLES) while len(node_names) > 0: count += 1 current_node = node_names.popleft() # get the transform from world to geometry and mesh name transform, geometry_name = self.scene.graph[current_node] # if no geometry at this frame continue without rendering if geometry_name is None: continue # if a geometry is marked as fixed apply the inverse view transform if self.fixed is not None and geometry_name in self.fixed: transform = np.dot(np.linalg.inv(view), transform) # get a reference to the mesh so we can check transparency mesh = self.scene.geometry[geometry_name] if mesh.is_empty: continue # add a new matrix to the model stack gl.glPushMatrix() # transform by the nodes transform gl.glMultMatrixf(rendering.matrix_to_gl(transform)) # draw an axis marker for each mesh frame if self.view['axis'] == 'all': self._axis.draw(mode=gl.GL_TRIANGLES) # transparent things must be drawn last if (hasattr(mesh, 'visual') and hasattr(mesh.visual, 'transparency') and mesh.visual.transparency): # put the current item onto the back of the queue if count < count_original: # add the node to be drawn last node_names.append(current_node) # pop the matrix stack for now gl.glPopMatrix() # come back to this mesh later continue # if we have texture enable the target texture texture = None if geometry_name in self.textures: texture = self.textures[geometry_name] gl.glEnable(texture.target) gl.glBindTexture(texture.target, texture.id) # get the mode of the current geometry mode = self.vertex_list_mode[geometry_name] # draw the mesh with its transform applied self.vertex_list[geometry_name].draw(mode=mode) # pop the matrix stack as we drew what we needed to draw gl.glPopMatrix() # disable texture after using if texture is not None: gl.glDisable(texture.target)
def load_texture(file_name: str, x: float=0, y: float=0, width: float=0, height: float=0, mirrored: bool=False, flipped: bool=False, scale: float=1) -> Texture: """ Load image from disk and create a texture. Note, if the code is to load only part of the image, the given x, y coordinates will start with the origin (0, 0) in the upper left of the image. When drawing, Arcade uses (0, 0) in the lower left corner when drawing. Be careful about this reversal. For a longer explanation of why computers sometimes start in the upper left, see: http://programarcadegames.com/index.php?chapter=introduction_to_graphics&lang=en#section_5 Args: :filename (str): Name of the file to that holds the texture. :x (float): X position of the crop area of the texture. :y (float): Y position of the crop area of the texture. :width (float): Width of the crop area of the texture. :height (float): Height of the crop area of the texture. :scale (float): Scale factor to apply on the new texture. Returns: The new texture. Raises: None >>> import arcade >>> arcade.open_window(800,600,"Drawing Example") >>> name = "arcade/examples/images/meteorGrey_big1.png" >>> texture1 = load_texture(name, 1, 1, 50, 50) >>> texture2 = load_texture(name, 1, 1, 50, 50) >>> texture = load_texture(name, 200, 1, 50, 50) Traceback (most recent call last): ... ValueError: Can't load texture starting at an x of 200 when the image is only 101 across. >>> texture = load_texture(name, 1, 50, 50, 50) Traceback (most recent call last): ... ValueError: Can't load texture ending at an y of 100 when the image is only 84 high. >>> texture = load_texture(name, 1, 150, 50, 50) Traceback (most recent call last): ... ValueError: Can't load texture starting at an y of 150 when the image is only 84 high. >>> texture = load_texture(name, 0, 0, 400, 50) Traceback (most recent call last): ... ValueError: Can't load texture ending at an x of 400 when the image is only 101 wide. >>> arcade.close_window() """ # See if we already loaded this file, and we can just use a cached version. cache_name = "{}{}{}{}{}{}{}{}".format(file_name, x, y, width, height, scale, flipped, mirrored) if cache_name in load_texture.texture_cache: return load_texture.texture_cache[cache_name] source_image = PIL.Image.open(file_name) source_image_width, source_image_height = source_image.size if x != 0 or y != 0 or width != 0 or height != 0: if x > source_image_width: raise ValueError("Can't load texture starting at an x of {} " "when the image is only {} across." .format(x, source_image_width)) if y > source_image_height: raise ValueError("Can't load texture starting at an y of {} " "when the image is only {} high." .format(y, source_image_height)) if x + width > source_image_width: raise ValueError("Can't load texture ending at an x of {} " "when the image is only {} wide." .format(x + width, source_image_width)) if y + height > source_image_height: raise ValueError("Can't load texture ending at an y of {} " "when the image is only {} high." .format(y + height, source_image_height)) image = source_image.crop((x, y, x + width, y + height)) else: image = source_image # image = _trim_image(image) if mirrored: image = PIL.ImageOps.mirror(image) if flipped: image = PIL.ImageOps.flip(image) image_width, image_height = image.size # image_bytes = image.convert("RGBA").tobytes("raw", "RGBA", 0, -1) texture = gl.GLuint(0) gl.glGenTextures(1, ctypes.byref(texture)) gl.glBindTexture(gl.GL_TEXTURE_2D, texture) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR_MIPMAP_LINEAR) # glu.gluBuild2DMipmaps(gl.GL_TEXTURE_2D, gl.GL_RGBA, # image_width, image_height, # gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, image_bytes) image_width *= scale image_height *= scale result = Texture(texture, image_width, image_height, file_name) load_texture.texture_cache[cache_name] = result return result
def __init__(self, env, sync=True, tps=60, aspect_ratio=None): obs = env.reset() self._image = self.get_image(obs, env) assert len(self._image.shape ) == 3 and self._image.shape[2] == 3, 'must be an RGB image' image_height, image_width = self._image.shape[:2] if aspect_ratio is None: aspect_ratio = image_width / image_height # guess a screen size that doesn't distort the image too much but also is not tiny or huge platform = pyglet.window.get_platform() display = platform.get_default_display() screen = display.get_default_screen() max_win_width = screen.width * 0.9 max_win_height = screen.height * 0.9 win_width = image_width win_height = int(win_width / aspect_ratio) while win_width > max_win_width or win_height > max_win_height: win_width //= 2 win_height //= 2 while win_width < max_win_width / 2 and win_height < max_win_height / 2: win_width *= 2 win_height *= 2 win = pyglet.window.Window(width=win_width, height=win_height) self._key_handler = pyglet.window.key.KeyStateHandler() win.push_handlers(self._key_handler) win.on_close = self._on_close gl.glEnable(gl.GL_TEXTURE_2D) self._texture_id = gl.GLuint(0) gl.glGenTextures(1, ctypes.byref(self._texture_id)) gl.glBindTexture(gl.GL_TEXTURE_2D, self._texture_id) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA8, image_width, image_height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, None) self._env = env self._win = win # self._render_human = render_human self._key_previous_states = {} self._steps = 0 self._episode_steps = 0 self._episode_returns = 0 self._prev_episode_returns = 0 self._tps = tps self._sync = sync self._current_time = 0 self._sim_time = 0 self._max_sim_frames_per_update = 4
def load_textures(file_name: str, image_location_list: PointList, mirrored: bool=False, flipped: bool=False, scale: float=1) -> List['Texture']: """ Load a set of textures off of a single image file. Note, if the code is to load only part of the image, the given x, y coordinates will start with the origin (0, 0) in the upper left of the image. When drawing, Arcade uses (0, 0) in the lower left corner when drawing. Be careful about this reversal. For a longer explanation of why computers sometimes start in the upper left, see: http://programarcadegames.com/index.php?chapter=introduction_to_graphics&lang=en#section_5 Args: :file_name: Name of the file. :image_location_list: List of image locations. Each location should be a list of four floats. ``[x, y, width, height]``. :mirrored=False: If set to true, the image is mirrored left to right. :flipped=False: If set to true, the image is flipped upside down. Returns: :list: List of textures loaded. Raises: :SystemError: """ source_image = PIL.Image.open(file_name) source_image_width, source_image_height = source_image.size texture_info_list = [] for image_location in image_location_list: x, y, width, height = image_location if width <= 0: raise ValueError("Texture has a width of {}, must be > 0." .format(width)) if x > source_image_width: raise ValueError("Can't load texture starting at an x of {} " "when the image is only {} across." .format(x, source_image_width)) if y > source_image_height: raise ValueError("Can't load texture starting at an y of {} " "when the image is only {} high." .format(y, source_image_height)) if x + width > source_image_width: raise ValueError("Can't load texture ending at an x of {} " "when the image is only {} wide." .format(x + width, source_image_width)) if y + height > source_image_height: raise ValueError("Can't load texture ending at an y of {} " "when the image is only {} high." .format(y + height, source_image_height)) image = source_image.crop((x, y, x + width, y + height)) # image = _trim_image(image) if mirrored: image = PIL.ImageOps.mirror(image) if flipped: image = PIL.ImageOps.flip(image) image_width, image_height = image.size texture = gl.GLuint(0) gl.glGenTextures(1, ctypes.byref(texture)) gl.glBindTexture(gl.GL_TEXTURE_2D, texture) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT) gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR_MIPMAP_LINEAR) image_width *= scale image_height *= scale texture_info_list.append(Texture(texture, width, height, image_location)) return texture_info_list
def __enter__(self): gl.glPushAttrib(gl.GL_ENABLE_BIT | gl.GL_TEXTURE_BIT) gl.glEnable(self.target) gl.glBindTexture(self.target, self.id)
def create_frame_buffers(width, height, num_samples): """Create the frame buffer objects""" from pyglet import gl # Create a frame buffer (rendering target) multi_fbo = gl.GLuint(0) gl.glGenFramebuffers(1, byref(multi_fbo)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, multi_fbo) # The try block here is because some OpenGL drivers # (Intel GPU drivers on macbooks in particular) do not # support multisampling on frame buffer objects try: if not gl.gl_info.have_version(major=3, minor=2): raise Exception('OpenGL version 3.2+ required for \ GL_TEXTURE_2D_MULTISAMPLE') # Create a multisampled texture to render into fbTex = gl.GLuint(0) gl.glGenTextures(1, byref(fbTex)) gl.glBindTexture(gl.GL_TEXTURE_2D_MULTISAMPLE, fbTex) gl.glTexImage2DMultisample(gl.GL_TEXTURE_2D_MULTISAMPLE, num_samples, gl.GL_RGBA32F, width, height, True) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D_MULTISAMPLE, fbTex, 0) # Attach a multisampled depth buffer to the FBO depth_rb = gl.GLuint(0) gl.glGenRenderbuffers(1, byref(depth_rb)) gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, depth_rb) gl.glRenderbufferStorageMultisample(gl.GL_RENDERBUFFER, num_samples, gl.GL_DEPTH_COMPONENT, width, height) gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_RENDERBUFFER, depth_rb) except: logger.debug('Falling back to non-multisampled frame buffer') # Create a plain texture texture to render into fbTex = gl.GLuint(0) gl.glGenTextures(1, byref(fbTex)) gl.glBindTexture(gl.GL_TEXTURE_2D, fbTex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_RGBA, gl.GL_FLOAT, None) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, fbTex, 0) # Attach depth buffer to FBO depth_rb = gl.GLuint(0) gl.glGenRenderbuffers(1, byref(depth_rb)) gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, depth_rb) gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT, width, height) gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_RENDERBUFFER, depth_rb) # Sanity check import pyglet if pyglet.options['debug_gl']: res = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) assert res == gl.GL_FRAMEBUFFER_COMPLETE # Create the frame buffer used to resolve the final render final_fbo = gl.GLuint(0) gl.glGenFramebuffers(1, byref(final_fbo)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, final_fbo) # Create the texture used to resolve the final render fbTex = gl.GLuint(0) gl.glGenTextures(1, byref(fbTex)) gl.glBindTexture(gl.GL_TEXTURE_2D, fbTex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, width, height, 0, gl.GL_RGBA, gl.GL_FLOAT, None) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, fbTex, 0) import pyglet if pyglet.options['debug_gl']: res = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) assert res == gl.GL_FRAMEBUFFER_COMPLETE # Enable depth testing gl.glEnable(gl.GL_DEPTH_TEST) # Unbind the frame buffer gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0) return multi_fbo, final_fbo
def _updateFrameTexture(self): if self._nextFrameT is None: # movie has no current position, need to reset the clock # to zero in order to have the timing logic work # otherwise the video stream would skip frames until the # time since creating the movie object has passed self._videoClock.reset() self._nextFrameT = 0 # only advance if next frame (half of next retrace rate) if self._nextFrameT > self.duration: self._onEos() elif self._numpyFrame is not None: if self._nextFrameT > (self._videoClock.getTime() - old_div(self._retraceInterval, 2.0)): return None self._numpyFrame = self._mov.get_frame(self._nextFrameT) useSubTex = self.useTexSubImage2D if self._texID is None: self._texID = GL.GLuint() GL.glGenTextures(1, ctypes.byref(self._texID)) useSubTex = False # bind the texture in openGL GL.glEnable(GL.GL_TEXTURE_2D) # bind that name to the target GL.glBindTexture(GL.GL_TEXTURE_2D, self._texID) # makes the texture map wrap (this is actually default anyway) GL.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT) # data from PIL/numpy is packed, but default for GL is 4 bytes GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1) # important if using bits++ because GL_LINEAR # sometimes extrapolates to pixel vals outside range if self.interpolate: GL.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR) GL.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR) if useSubTex is False: GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, self._numpyFrame.shape[1], self._numpyFrame.shape[0], 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, self._numpyFrame.shape[1], self._numpyFrame.shape[0], GL.GL_RGB, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST) GL.glTexParameteri( GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST) if useSubTex is False: GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, self._numpyFrame.shape[1], self._numpyFrame.shape[0], 0, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, self._numpyFrame.shape[1], self._numpyFrame.shape[0], GL.GL_BGR, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) GL.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE) # ?? do we need this - think not! if not self.status == PAUSED: self._nextFrameT += self._frameInterval
def load_texture(tex_path: str, segment: bool = False, segment_into_color=None): """ segment_into_black controls what type of segmentation we apply: for tiles and all ground textures, replacing unimportant stuff with black is a good idea. For other things, replacing it with transparency is good too (for example, we don't want black traffic lights, because they go over the roads, and they'd cut our view of things). """ if segment_into_color is None: segment_into_color = [0, 0, 0] logger.debug(f"loading texture: {tex_path}") img = pyglet.image.load(tex_path) # img_format = 'RGBA' # pitch = img.width * len(img_format) # pixels = img.get_data(img_format, pitch) # # # for i in range(x, width): # for j in range(y, height): # pixels[i, j] = (0, 0, 0, 0) if segment: if should_segment_out(tex_path): # replace all by 'segment_into_color' # https://gamedev.stackexchange.com/questions/55945/how-to-draw-image-in-memory-manually-in-pyglet to_fill = np.ones((img.height, img.width), dtype=int) to_fill = np.kron(to_fill, np.array(segment_into_color, dtype=int)) to_fill = list(to_fill.flatten()) rawData = (GLubyte * len(to_fill))(*to_fill) img = pyglet.image.ImageData(img.width, img.height, "RGB", rawData) else: # replace asphalt by black # https://gist.github.com/nkymut/1cb40ea6ae4de0cf9ded7332f1ca0d55 im = cv2.imread(tex_path, cv2.IMREAD_UNCHANGED) hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) # Threshold of blue in HSV space lower = np.array([0, 0, 0], dtype="uint8") upper = np.array([179, 100, 160], dtype="uint8") mask = cv2.inRange(hsv, lower, upper) mask = cv2.bitwise_not(mask) kernel1 = np.array([[0, 0, 0], [0, 1, 0], [0, 0, 0]], np.uint8) kernel2 = np.array([[1, 1, 1], [1, 0, 1], [1, 1, 1]], np.uint8) hitormiss1 = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel1) hitormiss2 = cv2.morphologyEx(hitormiss1, cv2.MORPH_ERODE, kernel2) mask = cv2.bitwise_and(hitormiss1, hitormiss2) result = cv2.bitwise_and(hsv, hsv, mask=mask) im = cv2.cvtColor(result, cv2.COLOR_HSV2BGR) rows, cols, channels = im.shape raw_img = Image.fromarray(im).tobytes() top_to_bottom_flag = -1 bytes_per_row = channels * cols img = pyglet.image.ImageData(width=cols, height=rows, format="BGR", data=raw_img, pitch=top_to_bottom_flag * bytes_per_row) tex = img.get_texture() # if img.width == img.height: # tex = tex.get_mipmapped_texture() gl.glEnable(tex.target) gl.glBindTexture(tex.target, tex.id) rawimage = img.get_image_data() if tex_path.endswith("jpg"): image_data = rawimage.get_data("RGB", img.width * 3) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, img.width, img.height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, image_data, ) else: image_data = rawimage.get_data("RGBA", img.width * 4) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, img.width, img.height, 0, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, image_data, ) return tex
def on_draw(self): """ Run the actual draw calls. """ self._update_meshes() gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glLoadIdentity() # pull the new camera transform from the scene transform_camera = np.linalg.inv(self.scene.camera_transform) # apply the camera transform to the matrix stack gl.glMultMatrixf(rendering.matrix_to_gl(transform_camera)) # we want to render fully opaque objects first, # followed by objects which have transparency node_names = collections.deque(self.scene.graph.nodes_geometry) # how many nodes did we start with count_original = len(node_names) count = -1 # if we are rendering an axis marker at the world if self._axis: # we stored it as a vertex list self._axis.draw(mode=gl.GL_TRIANGLES) if self._grid: self._grid.draw(mode=gl.GL_LINES) while len(node_names) > 0: count += 1 current_node = node_names.popleft() # get the transform from world to geometry and mesh name transform, geometry_name = self.scene.graph.get(current_node) # if no geometry at this frame continue without rendering if geometry_name is None: continue # if a geometry is marked as fixed apply the inverse view transform if self.fixed is not None and geometry_name in self.fixed: # remove altered camera transform from fixed geometry transform_fix = np.linalg.inv( np.dot(self._initial_camera_transform, transform_camera)) # apply the transform so the fixed geometry doesn't move transform = np.dot(transform, transform_fix) # get a reference to the mesh so we can check transparency mesh = self.scene.geometry[geometry_name] if mesh.is_empty: continue # get the GL mode of the current geometry mode = self.vertex_list_mode[geometry_name] # if you draw a coplanar line with a triangle it will z-fight # the best way to do this is probably a shader but this works fine if mode == gl.GL_LINES: # apply the offset in camera space transform = util.multi_dot([ transform, np.linalg.inv(transform_camera), self._line_offset, transform_camera]) # add a new matrix to the model stack gl.glPushMatrix() # transform by the nodes transform gl.glMultMatrixf(rendering.matrix_to_gl(transform)) # draw an axis marker for each mesh frame if self.view['axis'] == 'all': self._axis.draw(mode=gl.GL_TRIANGLES) # transparent things must be drawn last if (hasattr(mesh, 'visual') and hasattr(mesh.visual, 'transparency') and mesh.visual.transparency): # put the current item onto the back of the queue if count < count_original: # add the node to be drawn last node_names.append(current_node) # pop the matrix stack for now gl.glPopMatrix() # come back to this mesh later continue # if we have texture enable the target texture texture = None if geometry_name in self.textures: texture = self.textures[geometry_name] gl.glEnable(texture.target) gl.glBindTexture(texture.target, texture.id) # draw the mesh with its transform applied self.vertex_list[geometry_name].draw(mode=mode) # pop the matrix stack as we drew what we needed to draw gl.glPopMatrix() # disable texture after using if texture is not None: gl.glDisable(texture.target)
def bind(self, segment=False): if segment: self = get_texture(self.tex_name, self.rng, True) gl.glBindTexture(self.tex.target, self.tex.id)
def _draw_heatmap(self): """Draw reward defined by self.heat as a heatmap.""" if not self.heatmap_show or not self.heat: return center_x = 0.0 # TODO make this more general? center_vis = self._get_center() # center of visualization # heatmap center is (center of road, y coordinate of main car) center_heatmap = [center_x, center_vis[1]] # proportion of width and height to draw heatmap around the center if False: # if config.FULL_HEATMAP: # TODO initialization option for this w_h = [1.0, 1.0] else: w_h = [0.15, 1.0] # Min and max coordinates of the heatmap that define the largest area # that could be visible. visible_heatmap_min_coord = center_heatmap - np.asarray(w_h) / self.magnify visible_heatmap_max_coord = center_heatmap + np.asarray(w_h) / self.magnify # Set the min and max coordinates of the heatmap self.heatmap_min_coord = visible_heatmap_min_coord self.heatmap_max_coord = visible_heatmap_max_coord size = self.heatmap_size min_coord = self.heatmap_min_coord max_coord = self.heatmap_max_coord vals = np.zeros(size) for i, x in enumerate(np.linspace(min_coord[0] + 1e-6, max_coord[0] - 1e-6, size[0])): for j, y in enumerate(np.linspace(min_coord[1] + 1e-6, max_coord[1] - 1e-6, size[1])): vals[j, i] = self.heat(np.asarray([x, y])) # Set min and max values if showing the strategic value heatmap # using either fixed values or dynamic values based on the visible heatmap if self.min_heatmap_val is None or not self.fixed_heatmap_scale: min_val = np.nanmin(vals) else: min_val = self.min_heatmap_val if self.max_heatmap_val is None or not self.fixed_heatmap_scale: max_val = np.nanmax(vals) else: max_val = self.max_heatmap_val # scale and translate the values to make the heatmap most useful # 1 - vals to reverse the heatmap colors to make red==bad and blue==good vals = (vals - min_val) / (max_val - min_val) vals *= 0.75 # vals = 1 - vals vals = self.colormap(vals) vals[:, :, 3] = 0.7 # opacity vals = (vals * 255.0).astype("uint8").flatten() # convert to RGBA vals = (gl.GLubyte * vals.size)(*vals) img = pyglet.image.ImageData(size[0], size[1], "RGBA", vals, pitch=size[1] * 4) self.heatmap = img.get_texture() self.heatmap_valid = True gl.glClearColor(1.0, 1.0, 1.0, 1.0) gl.glEnable(self.heatmap.target) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glBindTexture(self.heatmap.target, self.heatmap.id) gl.glEnable(gl.GL_BLEND) min_coord = self.heatmap_min_coord max_coord = self.heatmap_max_coord graphics.draw( 4, gl.GL_QUADS, ( "v2f", ( min_coord[0], min_coord[1], max_coord[0], min_coord[1], max_coord[0], max_coord[1], min_coord[0], max_coord[1], ), ), ("t2f", (0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0)), # ('t2f', (0., 0., size[0], 0., size[0], size[1], 0., size[1])) ) gl.glDisable(self.heatmap.target)
def __init__(self, width, height, scale=1.5, conf=1, mask=None, flip=False, video=False, sample_rate=None, video_rate=None): """ Parameters ---------- :width & height: size of the window in pixels. :scale: scaling factor of the texture. :conf: line number of the config in the file (`config.txt`). :mask: a user-specified image that is used to control the growth of the pattern. :flip: flip the white/black pixels in the mask image, only meaningful if there is a mask image. :video: whether the video is turned on or off. :sample_rate: sample a frame from the animation every these frames. :video_rate: frames per second of the video. """ pyglet.window.Window.__init__(self, width, height, caption="GrayScott Simulation", resizable=True, visible=False, vsync=False) # use two shaders, one for doing the computations and one for rendering to the screen. self.reaction_shader = Shader(["./glsl/reaction.vert"], ["./glsl/reaction.frag"]) self.render_shader = Shader(["./glsl/render.vert"], ["./glsl/render.frag"]) self.tex_width, self.tex_height = int(width / scale), int(height / scale) try: self.species, self.palette = self.load_config(conf) print("> Current species: " + self.species + "\n") except: conf = "unstable: #00000000 #00FF0033 #FFFF0035 #FF000066 #FFFFFF99" self.species, self.palette = parse(conf) print("> Failed to load the config, using the default one.\n") self.species_list = list(ALL_SPECIES.keys()) # create the uv_texture uv_grid = np.zeros((self.tex_height, self.tex_width, 4), dtype=np.float32) uv_grid[:, :, 0] = 1.0 rand_rows = np.random.choice(range(self.tex_height), 5) rand_cols = np.random.choice(range(self.tex_width), 5) uv_grid[rand_rows, rand_cols, 1] = 1.0 self.uv_texture = create_texture_from_ndarray(uv_grid) # create the mask_texture mask_grid = np.ones_like(uv_grid) if mask is not None: img = Image.open(mask).convert("L").resize( (self.tex_width, self.tex_height)) img = (np.asarray(img) / 255.0).astype(np.float32) if flip: img = 1.0 - img mask_grid[:, :, 0] = img[::-1] self.mask_texture = create_texture_from_ndarray(mask_grid) # bind the two textures gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.uv_texture.target, self.uv_texture.id) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(self.mask_texture.target, self.mask_texture.id) # use an invisible buffer to do the computations. with FrameBuffer() as self.fbo: self.fbo.attach_texture(self.uv_texture) # we need this because the program samples the position of the mouse in discrete times. self.mouse_down = False # initialize the two shaders with self.reaction_shader: self.reaction_shader.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.reaction_shader.vertex_attrib("texcoord", [0, 0, 1, 0, 0, 1, 1, 1]) self.reaction_shader.uniformi("uv_texture", 0) self.reaction_shader.uniformi("mask_texture", 1) self.reaction_shader.uniformf("iResolution", self.tex_width, self.tex_height, 0) self.reaction_shader.uniformf("iMouse", -1, -1) self.reaction_shader.uniformf("params", *ALL_SPECIES[self.species]) with self.render_shader: self.render_shader.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.render_shader.vertex_attrib("texcoord", [0, 0, 1, 0, 0, 1, 1, 1]) self.render_shader.uniformi("uv_texture", 0) self.render_shader.uniformfv("palette", 5, self.palette) self.video_on = video self.buffer = pyglet.image.get_buffer_manager().get_color_buffer() self.sample_rate = sample_rate self.video_rate = video_rate self.frame_count = 0 if video: self.ffmpeg_pipe = self.create_new_pipe() self.start_time = time.time()
def on_draw(self): self.window.clear() gl.glEnable(gl.GL_DEPTH_TEST) gl.glEnable(gl.GL_LINE_SMOOTH) width, height = self.get_size() gl.glViewport(0, 0, width, height) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() gl.gluPerspective(60, width / float(height), 0.01, 20) gl.glMatrixMode(gl.GL_TEXTURE) gl.glLoadIdentity() # texcoords are [0..1] and relative to top-left pixel corner, add 0.5 to center gl.glTranslatef(0.5 / image_data.width, 0.5 / image_data.height, 0) image_texture = image_data.get_texture() # texture size may be increased by pyglet to a power of 2 tw, th = image_texture.owner.width, image_texture.owner.height gl.glScalef(image_data.width / float(tw), image_data.height / float(th), 1) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() gl.gluLookAt(0, 0, 0, 0, 0, 1, 0, -1, 0) gl.glTranslatef(0, 0, state.distance) gl.glRotated(state.pitch, 1, 0, 0) gl.glRotated(state.yaw, 0, 1, 0) if any(state.mouse_btns): axes(0.1, 4) gl.glTranslatef(0, 0, -state.distance) gl.glTranslatef(*state.translation) gl.glColor3f(0.5, 0.5, 0.5) gl.glPushMatrix() gl.glTranslatef(0, 0.5, 0.5) grid() gl.glPopMatrix() psz = max(window.get_size()) / float(max(w, h)) if state.scale else 1 gl.glPointSize(psz) distance = (0, 0, 1) if state.attenuation else (1, 0, 0) gl.glPointParameterfv(gl.GL_POINT_DISTANCE_ATTENUATION, (gl.GLfloat * 3)(*distance)) if state.lighting: ldir = [0.5, 0.5, 0.5] # world-space lighting ldir = np.dot(state.rotation, (0, 0, 1)) # MeshLab style lighting ldir = list(ldir) + [0] # w=0, directional light gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, (gl.GLfloat * 4)(*ldir)) gl.glLightfv(gl.GL_LIGHT0, gl.GL_DIFFUSE, (gl.GLfloat * 3)(1.0, 1.0, 1.0)) gl.glLightfv(gl.GL_LIGHT0, gl.GL_AMBIENT, (gl.GLfloat * 3)(0.75, 0.75, 0.75)) gl.glEnable(gl.GL_LIGHT0) gl.glEnable(gl.GL_NORMALIZE) gl.glEnable(gl.GL_LIGHTING) gl.glColor3f(1, 1, 1) texture = image_data.get_texture() gl.glEnable(texture.target) gl.glBindTexture(texture.target, texture.id) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) # comment this to get round points with MSAA on gl.glEnable(gl.GL_POINT_SPRITE) if not state.scale and not state.attenuation: gl.glDisable(gl.GL_MULTISAMPLE) # for true 1px points with MSAA on vertex_list.draw(gl.GL_POINTS) gl.glDisable(texture.target) if not state.scale and not state.attenuation: gl.glEnable(gl.GL_MULTISAMPLE) gl.glDisable(gl.GL_LIGHTING) gl.glColor3f(0.25, 0.25, 0.25) frustum(depth_intrinsics) axes() gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() gl.glOrtho(0, width, 0, height, -1, 1) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glLoadIdentity() gl.glMatrixMode(gl.GL_TEXTURE) gl.glLoadIdentity() gl.glDisable(gl.GL_DEPTH_TEST) fps_display.draw()
def draw_image(self, img, rect=None, force_copy=False): """ Renders a GraphicsContextArray into this GC """ xform = self.get_ctm() image = image_as_array(img) shape = image.shape if shape[2] == 4: fmt = "RGBA" else: fmt = "RGB" aii = ArrayImage(image, format=fmt) texture = aii.texture # The texture coords consists of (u,v,r) for each corner of the # texture rectangle. The coordinates are stored in the order # bottom left, bottom right, top right, top left. x, y, w, h = rect texture.width = w texture.height = h t = texture.tex_coords points = array([[x, y + h], [x + w, y + h], [x + w, y], [x, y]]) p = transform_points(affine_from_values(*xform), points) a = (gl.GLfloat * 32)( t[0], t[1], t[2], 1., p[0, 0], p[0, 1], 0, 1., t[3], t[4], t[5], 1., p[1, 0], p[1, 1], 0, 1., t[6], t[7], t[8], 1., p[2, 0], p[2, 1], 0, 1., t[9], t[10], t[11], 1., p[3, 0], p[3, 1], 0, 1., ) gl.glPushAttrib(gl.GL_ENABLE_BIT) gl.glEnable(texture.target) gl.glBindTexture(texture.target, texture.id) gl.glPushClientAttrib(gl.GL_CLIENT_VERTEX_ARRAY_BIT) gl.glInterleavedArrays(gl.GL_T4F_V4F, 0, a) gl.glDrawArrays(gl.GL_QUADS, 0, 4) gl.glPopClientAttrib() gl.glPopAttrib()
def __init__(self, env, sync=True, tps=60, aspect_ratio=None, display_info=False): self._record_dir = None self._movie_writer = None self._episode = 0 self._display_info = display_info self._seconds_to_display_done_info = 0 obs = env.reset() self._image = self.get_image(obs, env) assert (len(self._image.shape) == 3 and self._image.shape[2] == 3), "must be an RGB image" image_height, image_width = self._image.shape[:2] if aspect_ratio is None: aspect_ratio = image_width / image_height # guess a screen size that doesn't distort the image too much but also is not tiny or huge display = pyglet.canvas.get_display() screen = display.get_default_screen() max_win_width = screen.width * 0.9 max_win_height = screen.height * 0.9 win_width = image_width win_height = int(win_width / aspect_ratio) while win_width > max_win_width or win_height > max_win_height: win_width //= 2 win_height //= 2 while win_width < max_win_width / 2 and win_height < max_win_height / 2: win_width *= 2 win_height *= 2 self._info_width = win_width // 2 if display_info: win_width += self._info_width win = pyglet.window.Window(width=win_width, height=win_height) self._key_handler = pyglet.window.key.KeyStateHandler() win.push_handlers(self._key_handler) win.on_close = self._on_close gl.glEnable(gl.GL_TEXTURE_2D) self._texture_id = gl.GLuint(0) gl.glGenTextures(1, ctypes.byref(self._texture_id)) gl.glBindTexture(gl.GL_TEXTURE_2D, self._texture_id) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) gl.glTexImage2D( gl.GL_TEXTURE_2D, 0, gl.GL_RGBA8, image_width, image_height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, None, ) self._env = env self._win = win self._key_previous_states = {} self._steps = 0 self._episode_steps = 0 self._episode_return = 0 self._prev_episode_return = 0 self._last_info = {} self._tps = tps self._sync = sync self._current_time = 0 self._sim_time = 0 self._max_sim_frames_per_update = 4 self._info_label = pyglet.text.Label( "<label>", font_name="Courier New", font_size=self._win.height // 42, multiline=True, x=self._win.width - self._info_width + 10, y=self._win.height // 2, width=self._info_width, anchor_x="left", anchor_y="center", ) self._done_info_label = pyglet.text.Label( "<label>", font_name="Courier New", font_size=self._win.height // 42, multiline=True, x=self._win.width // 2, y=self._win.height // 2, width=self._info_width, anchor_x="center", anchor_y="center", ) self._skip_info_out = [] self._step_cbs = []
def __exit__(self, exc_type, exc_val, exc_tb): gl.glBindTexture(gl.GL_TEXTURE_2D, 0) gl.glActiveTexture(gl.GL_TEXTURE0)
def __enter__(self): gl.glActiveTexture(gl.GL_TEXTURE0 + self.unit) gl.glBindTexture(gl.GL_TEXTURE_2D, self.name)
def _updateFrameTexture(self): """Update texture pixel store to contain the present frame. Decoded frame image samples are streamed to the texture buffer. """ if self._nextFrameT is None or self._nextFrameT < 0: # movie has no current position (or invalid position -JK), # need to reset the clock to zero in order to have the # timing logic work otherwise the video stream would skip # frames until the time since creating the movie object has passed self._videoClock.reset() self._nextFrameT = 0.0 # only advance if next frame (half of next retrace rate) if self._nextFrameT > self.duration: self._onEos() elif self._numpyFrame is not None: if self._nextFrameT > (self._videoClock.getTime() - self._retraceInterval / 2.0): return None while self._nextFrameT <= (self._videoClock.getTime() - self._frameInterval * 2): self.nDroppedFrames += 1 if self.nDroppedFrames <= reportNDroppedFrames: logging.warning( "{}: Video catchup needed, advancing self._nextFrameT from" " {} to {}".format(self._videoClock.getTime(), self._nextFrameT, self._nextFrameT + self._frameInterval)) if self.nDroppedFrames == reportNDroppedFrames: logging.warning( "Max reportNDroppedFrames reached, will not log any more dropped frames" ) self._nextFrameT += self._frameInterval try: self._numpyFrame = self._mov.get_frame(self._nextFrameT) except OSError: if self.autoLog: logging.warning( "Frame {} not found, moving one frame and trying again". format(self._nextFrameT), obj=self) self._nextFrameT += self._frameInterval self._updateFrameTexture() useSubTex = self.useTexSubImage2D if self._texID is None: self._texID = GL.GLuint() GL.glGenTextures(1, ctypes.byref(self._texID)) useSubTex = False # bind the texture in openGL GL.glEnable(GL.GL_TEXTURE_2D) # bind that name to the target GL.glBindTexture(GL.GL_TEXTURE_2D, self._texID) # makes the texture map wrap (this is actually default anyway) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP) # data from PIL/numpy is packed, but default for GL is 4 bytes GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1) # important if using bits++ because GL_LINEAR # sometimes extrapolates to pixel vals outside range if self.interpolate: GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR) if useSubTex is False: GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, self._numpyFrame.shape[1], self._numpyFrame.shape[0], 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, self._numpyFrame.shape[1], self._numpyFrame.shape[0], GL.GL_RGB, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST) GL.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST) if useSubTex is False: GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB8, self._numpyFrame.shape[1], self._numpyFrame.shape[0], 0, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) else: GL.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, self._numpyFrame.shape[1], self._numpyFrame.shape[0], GL.GL_BGR, GL.GL_UNSIGNED_BYTE, self._numpyFrame.ctypes) GL.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE) # ?? do we need this - think not! if self.status == PLAYING: self._nextFrameT += self._frameInterval
def __init__(self, game_class, x, y, w, h, sprite_sheet=None, sprite_width=32, sprite_height=32): """ To add an object to a map: map.objects['object name'] = object Object states: Each state has a name (consider using integers if you want to advance through them sequentially) Each state is a dict of properties that the object will update to when state_index is changed to that state name Ensure that these properties are spelt correctly! To change state elsewhere, just set object.state_index = <state_name_here>, properties will automatically update Flair: Flair is a dict of 'name': (surface, position (relative to object centre)) to additionally render attached to sprite E.g. Hats, speech bubbles. Collision: Each object has a collision_weight. Objects can only push objects with equal or less weight. Objects can only push a chain of objects up to their own weight. If an objects' collision weight is 0, it does not collide with objects. Collision rectangle updates automatically if you change obj dimensions (or coord). """ self.game_class = game_class self.states = {'state1': {'max_speed': 1, 'fear_radius': 50}, 'state2': {'max_speed': 5, 'fear_radius': 150}} self._state_index = 'state1' self._coord = (x, y) # top left self._dimensions = (w, h) self.velocity = (0, 0) self.min_speed = 0 self.current_speed = 0 self.normal_speed = 0 self.feared_speed = 0 self.fear_radius = 50 self.scared_of = [] self.fears = FearsList(self) self.rect = rect.Rect(self.coord, self.dimensions) self.update_timer = 40 self.fear_timer = 0 self.scream_timer = 0 self.fear = 0 self.scream_thresh = 50 #variables for animation if sprite_sheet is not None: self.sprite_sheet_name = sprite_sheet else: self.sprite_sheet_name = 'DudeSheet.png' self.sprite_sheet = image.load(os.path.join(CHARACTERS_DIR, self.sprite_sheet_name)) # disable texture filtering texture = self.sprite_sheet.get_texture() gl.glBindTexture(texture.target, texture.id) gl.glTexParameteri(texture.target, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glBindTexture(texture.target, 0) self._animation_state = 0 self.sprite_height = sprite_height self.sprite_width = sprite_width self._animations = [] self._create_animations() self.sprite = sprite.Sprite(self._animations[self._animation_state], x=self._coord[0], y=self._coord[1]) #trigger functions self.has_touched_function = [] self.is_touched_function = [] self.has_untouched_function = [] self.is_untouched_function = [] self.move_up = False self.move_down = False self.move_left = False self.move_right = False self.highlight_radius = 20 self.flair = {} self.collision_weight = 1 # set to 0 for no collision, can only push things that are lighter, or same weight self.cutscene_controlling = [] self.path = []
def __init__(self, width, height, aa=1): """ :param width and height: size of the window in pixels. :param aa: antialiasing level, a higher value will give better result but also slow down the animation. (aa=2 is recommended) """ pyglet.window.Window.__init__(self, width, height, caption="Wythoff Explorer", resizable=True, visible=False, vsync=False) self._start_time = time.clock() self._frame_count = 0 # count number of frames rendered so far self._speed = 1 # control speed of the animation self.aa = aa # shader A draws the UI self.shaderA = Shader(["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/BufferA.frag"]) # shadwr B draws the polyhedra self.shaderB = Shader(["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/BufferB.frag"]) # shader C puts them together self.shaderC = Shader(["./glsl/wythoff.vert"], ["./glsl/common.frag", "./glsl/main.frag"]) self.font_texture = create_image_texture(FONT_TEXTURE) self.iChannel0 = pyglet.image.Texture.create_for_size( gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA32F_ARB) self.iChannel1 = pyglet.image.Texture.create_for_size( gl.GL_TEXTURE_2D, width, height, gl.GL_RGBA32F_ARB) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindTexture(self.iChannel0.target, self.iChannel0.id) gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindTexture(self.iChannel1.target, self.iChannel1.id) gl.glActiveTexture(gl.GL_TEXTURE2) gl.glBindTexture(gl.GL_TEXTURE_2D, self.font_texture) # frame buffer A renders the UI to texture iChannel0 with FrameBuffer() as self.bufferA: self.bufferA.attach_texture(self.iChannel0) # frame buffer B render the polyhedra to texture iChannel1 with FrameBuffer() as self.bufferB: self.bufferB.attach_texture(self.iChannel1) # initialize the shaders with self.shaderA: self.shaderA.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderA.uniformf("iResolution", width, height, 0.0) self.shaderA.uniformf("iTime", 0.0) self.shaderA.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderA.uniformi("iChannel0", 0) self.shaderA.uniformi("iFrame", 0) with self.shaderB: self.shaderB.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderB.uniformf("iResolution", width, height, 0.0) self.shaderB.uniformf("iTime", 0.0) self.shaderB.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderB.uniformi("iChannel0", 0) self.shaderB.uniformi("AA", self.aa) with self.shaderC: self.shaderC.vertex_attrib("position", [-1, -1, 1, -1, -1, 1, 1, 1]) self.shaderC.uniformf("iResolution", width, height, 0.0) self.shaderC.uniformf("iTime", 0.0) self.shaderC.uniformf("iMouse", 0.0, 0.0, 0.0, 0.0) self.shaderC.uniformi("iChannel0", 0) self.shaderC.uniformi("iChannel1", 1) self.shaderC.uniformi("iTexture", 2)
def __init__( self, ctx: "Context", size: Tuple[int, int], *, components: int = 4, dtype: str = "f1", data: Any = None, filter: Tuple[gl.GLuint, gl.GLuint] = None, wrap_x: gl.GLuint = None, wrap_y: gl.GLuint = None, target=gl.GL_TEXTURE_2D, depth=False, ): """ A texture can be created with or without initial data. NOTE: Currently does not support multisample textures even thought ``samples`` is exposed. :param Context ctx: The context the object belongs to :param Tuple[int,int] size: The size of the texture :param int components: The number of components (1: R, 2: RG, 3: RGB, 4: RGBA) :param str dtype: The data type of each component: f1, f2, f4 / i1, i2, i4 / u1, u2, u4 :param Any data: The byte data of the texture. bytes or anything supporting the buffer protocol. :param Tuple[gl.GLuint, gl.GLuint] filter: The minification/magnification filter of the texture :param gl.GLuint wrap_x: Wrap mode x :param gl.GLuint wrap_y: Wrap mode y :param int target: The texture type :param bool depth: creates a depth texture if `True` """ self._ctx = ctx self._width, self._height = size self._dtype = dtype self._components = components self._alignment = 1 self._target = target self._samples = 0 self._depth = depth self._compare_func = None # Default filters for float and integer textures # Integer textures should have NEAREST interpolation # by default 3.3 core doesn't really support it consistently. if "f" in self._dtype: self._filter = gl.GL_LINEAR, gl.GL_LINEAR else: self._filter = gl.GL_NEAREST, gl.GL_NEAREST self._wrap_x = gl.GL_REPEAT self._wrap_y = gl.GL_REPEAT if self._components not in [1, 2, 3, 4]: raise ValueError("Components must be 1, 2, 3 or 4") gl.glActiveTexture(gl.GL_TEXTURE0) # Create textures in the default channel (0) self._glo = glo = gl.GLuint() gl.glGenTextures(1, byref(self._glo)) if self._glo.value == 0: raise RuntimeError( "Cannot create Texture. OpenGL failed to generate a texture id" ) gl.glBindTexture(self._target, self._glo) if data is not None: byte_length, data = data_to_ctypes(data) if self._target == gl.GL_TEXTURE_2D: self._texture_2d(data) else: raise ValueError("Unsupported texture target") self.filter = filter or self._filter self.wrap_x = wrap_x or self._wrap_x self.wrap_y = wrap_y or self._wrap_y self.ctx.stats.incr("texture") weakref.finalize(self, Texture.release, self._ctx, glo)