def __init__(self, texture, *args, **kwargs): """A Framebuffer object, which when bound redirects draws to its texture. This is useful for deferred rendering.""" super(FBO, self).__init__(*args, **kwargs) self._old_viewport_size = (gl.GLint * 4)() self.texture = texture self.renderbuffer = tex.RenderBuffer( texture.width, texture.height) if not isinstance( texture, tex.DepthTexture) else None with self: #, self.texture: # TODO: Figure out whether texture should also be bound here. # Attach the textures to the FBO for texture in [self.texture, self.renderbuffer ] if self.renderbuffer else [self.texture]: texture.attach_to_fbo() # Set Draw and Read locations for the FBO (currently, just turn it off if not doing any color stuff) if isinstance(texture, tex.DepthTexture): gl.glDrawBuffer(gl.GL_NONE) # No color in this buffer gl.glReadBuffer(gl.GL_NONE) # check FBO status (warning appears for debugging) FBOstatus = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) if FBOstatus != gl.GL_FRAMEBUFFER_COMPLETE_EXT: raise BufferError( "GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO.\n{0}\n". format(FBOstatus))
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 __init__(self, texture, *args, **kwargs): """A Framebuffer object, which when bound redirects draws to its texture. This is useful for deferred rendering.""" super(FBO, self).__init__(*args, **kwargs) self.id = create_opengl_object(gl.glGenFramebuffersEXT) self._old_viewport = get_viewport() self.texture = texture self.renderbuffer = RenderBuffer( texture.width, texture.height) if not isinstance(texture, DepthTexture) else None with self: # Attach the textures to the FBO self.texture.attach_to_fbo() if self.renderbuffer: self.renderbuffer.attach_to_fbo() # Set Draw and Read locations for the FBO (currently, just turn it off if not doing any color stuff) if isinstance(texture, DepthTexture): gl.glDrawBuffer(gl.GL_NONE) # No color in this buffer gl.glReadBuffer(gl.GL_NONE) # check FBO status (warning appears for debugging) FBOstatus = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) if FBOstatus != gl.GL_FRAMEBUFFER_COMPLETE_EXT: raise BufferError( "GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO.\n{0}\n". format(FBOstatus))
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 __init__(self, width = 512, height = 512, screen_size=None ): self.render_target_size = width, height # create the framebuffer self._buffer = (c_uint * 1)() ; gl.glGenFramebuffersEXT(1,self._buffer) self._buffer = self._buffer[0] gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, self._buffer) self.rgb_texture = self._create_texture(texture_size=self.render_target_size) gl.glFramebufferTexture2DEXT(gl.GL_FRAMEBUFFER_EXT, gl.GL_COLOR_ATTACHMENT0_EXT, gl.GL_TEXTURE_2D, self.rgb_texture, 0) status = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) if status != gl.GL_FRAMEBUFFER_COMPLETE_EXT: print("ERROR on FRAMEBUFFER") return gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, 0)
def __init__(self, texture, *args, **kwargs): """A Framebuffer object, which when bound redirects draws to its texture. This is useful for deferred rendering.""" super(FBO, self).__init__(*args, **kwargs) self._old_viewport_size = (gl.GLint * 4)() self.texture = texture self.renderbuffer = tex.RenderBuffer(texture.width, texture.height) if not isinstance(texture, tex.DepthTexture) else None with self: #, self.texture: # TODO: Figure out whether texture should also be bound here. # Attach the textures to the FBO for texture in [self.texture, self.renderbuffer] if self.renderbuffer else [self.texture]: texture.attach_to_fbo() # Set Draw and Read locations for the FBO (currently, just turn it off if not doing any color stuff) if isinstance(texture, tex.DepthTexture): gl.glDrawBuffer(gl.GL_NONE) # No color in this buffer gl.glReadBuffer(gl.GL_NONE) # check FBO status (warning appears for debugging) FBOstatus = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) if FBOstatus != gl.GL_FRAMEBUFFER_COMPLETE_EXT: raise BufferError("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO.\n{0}\n".format(FBOstatus))
def check_status(self): """Check that currently set framebuffer is ready for rendering""" status = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) if status != gl.GL_FRAMEBUFFER_COMPLETE_EXT: raise Exception("Frambuffer not complete: %d" % status)
def renderToTexture(w, h, function): import ctypes from pyglet import gl from pyglet import image from pyglet.gl import gl_info global has_fbo if has_fbo is None: has_fbo = gl_info.have_extension('GL_EXT_framebuffer_object') # enforce dimensions are ints w, h = int(w), int(h) # set up viewport gl.glPushAttrib(gl.GL_VIEWPORT_BIT | gl.GL_TRANSFORM_BIT) gl.glViewport(0, 0, w, h) gl.glMatrixMode(gl.GL_PROJECTION) gl.glPushMatrix() gl.glLoadIdentity() gl.glOrtho(0, w, 0, h, -1, 1) gl.glMatrixMode(gl.GL_MODELVIEW) if has_fbo: # render directly to texture # create our frame buffer fbo = gl.GLuint() gl.glGenFramebuffersEXT(1, ctypes.byref(fbo)) gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, fbo) # allocate a texture and add to the frame buffer tex = image.Texture.create_for_size(gl.GL_TEXTURE_2D, w, h, 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 # now render gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, fbo) function() gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, 0) # clean up gl.glDeleteFramebuffersEXT(1, ctypes.byref(fbo)) else: # render and copy to texture # render function() # grab the buffer and copy contents to the texture buffer = image.get_buffer_manager().get_color_buffer() tex = image.Texture.create_for_size(gl.GL_TEXTURE_2D, w, h, gl.GL_RGBA) tex.blit_into(buffer.get_region(0, 0, w, h), 0, 0, 0) gl.glMatrixMode(gl.GL_PROJECTION) gl.glPopMatrix() gl.glPopAttrib() # return the region (the whole texture will most likely be larger) return tex.get_region(0, 0, w, h)
def main(image_file, num_polygons=250, resume=False): global image_pixels global keeps global newdrawing, olddrawing global blitted pic = image.load(image_file) width = pic.width height = pic.height size = width*height #setup the framebuffer # create our frame buffer fbo = gl.GLuint() gl.glGenFramebuffersEXT(1, ctypes.byref(fbo)) gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, fbo) # allocate a texture and add to the frame buffer 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 newdrawing = Drawing(width,height,fbo) try: os.path.isfile(resume) except TypeError: svg_file = image_file + '.svg' if resume == True: newdrawing.svg_import(svg_file) else: newdrawing.generate(num_polygons) else: newdrawing.svg_import(resume) svg_file = resume w = window.Window(width*2,height,"cows", vsync = False) w.set_visible(True) gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) fps = pyglet.clock.Clock() #use this for pixel dumps a = (gl.GLubyte * (4*size))(0) @w.event def on_close(): gl.glDeleteFramebuffersEXT(1, ctypes.byref(olddrawing.fb)) olddrawing.svg_export(image_file, svg_file) @w.event def on_draw(): #w.clear() global parent global parentdiff global olddrawing,newdrawing global blitted global image_pixels global keeps global i if not blitted: """ At the start we've not seen the target before, so draw it and store the pixel data. """ gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, 0) gl.glClear(gl.GL_COLOR_BUFFER_BIT) pic.blit(0,0) blitted = 1 image_pixels = (gl.GLubyte * (4*size))(0) gl.glReadPixels(0, 0, newdrawing.width, newdrawing.height, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, image_pixels ) image_pixels = np.frombuffer(image_pixels, dtype=np.uint8).astype(np.int32) # Draw the new child newdrawing.draw() # Read the pixel data for the child and find out if its any good gl.glReadPixels(0, 0, newdrawing.width, newdrawing.height, gl.GL_RGBA, gl.GL_UNSIGNED_BYTE, a) diff = compute_diff(a) if parent == None or diff < parentdiff: # The new drawing is better. # Redraw the parent as this child. # Set this child's diff as the new one to beat. parent = image.ImageData(newdrawing.width,newdrawing.height,"RGBA",a) parentdiff = diff draw_parent(parent, newdrawing.width) else: # The new drawing sucks. Replace it newdrawing = olddrawing i += 1 if (i % 20 == 0): # Use the window title to let the user know how we're doing w.set_caption(str(fps.get_fps())+" "+str(parentdiff) + " " + str(log(parentdiff,10))+ " " + str(i)) fps.tick() # Isolate and mutate the child on each clock tick pyglet.clock.schedule(update) # Set it running pyglet.app.run()
def add_texture(self, shape, dtype=gl.GL_FLOAT): """Add texture image to the framebuffer object. Parameters ---------- shape : tuple of ints Dimension of framebuffer. Note that for earlier versions of OpenGL, height and width dimensions must be a power of two. Valid shapes include (16,), (16, 17), (16, 16, 3). dtype : opengl data-type, e.g. GL_FLOAT, GL_UNSIGNED_BYTE Returns ------- slot : int The slot number to which the texture was bound. E.g., in the case of GL_COLOR_ATTACHMENT3_EXT, returns 3. """ if dtype != gl.GL_FLOAT: warnings.warn("While OpenGL < 3.0 implementations allow the " "storage of textures with data-types other " "than FLOAT, gl_FragColor only accepts " "assigned a floating point value. In OpenGL 3.0 " "this can be changed (see READING.txt).", RuntimeWarning) if len(self._textures) >= MAX_COLOR_ATTACHMENTS: raise RuntimeError("Maximum number of textures reached. This " "platform supports %d attachments." % \ MAX_COLOR_ATTACHMENTS) slot = getattr(gl, "GL_COLOR_ATTACHMENT%d_EXT" % len(self._textures)) width, height, bands = _shape_to_3d(shape) if bands > 4: raise ValueError("Texture cannot have more than 4 colour layers.") colour_bands = {1: gl.GL_LUMINANCE, 2: gl.GL_LUMINANCE_ALPHA, 3: gl.GL_RGB, 4: gl.GL_RGBA} # allocate a texture and add to the frame buffer tex = Texture(width, height, format=colour_bands[bands], dtype=dtype, internalformat=gl.GL_RGB32F_ARB, ) gl.glBindTexture(tex.target, tex.id) gl.glFramebufferTexture2DEXT(gl.GL_FRAMEBUFFER_EXT, gl.GL_COLOR_ATTACHMENT0_EXT, tex.target, tex.id, 0) if (gl.glGetError() != gl.GL_NO_ERROR): raise RuntimeError("Could not create framebuffer texture.") status = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) if not (status == gl.GL_FRAMEBUFFER_COMPLETE_EXT): raise RuntimeError("Could not set up framebuffer.") self._textures.append(tex) return len(self._textures) - 1
def renderToTexture(w, h, function): import ctypes from pyglet import gl from pyglet import image from pyglet.gl import gl_info global has_fbo if has_fbo is None: has_fbo = gl_info.have_extension("GL_EXT_framebuffer_object") # enforce dimensions are ints w, h = int(w), int(h) # set up viewport gl.glPushAttrib(gl.GL_VIEWPORT_BIT | gl.GL_TRANSFORM_BIT) gl.glViewport(0, 0, w, h) gl.glMatrixMode(gl.GL_PROJECTION) gl.glPushMatrix() gl.glLoadIdentity() gl.glOrtho(0, w, 0, h, -1, 1) gl.glMatrixMode(gl.GL_MODELVIEW) if has_fbo: # render directly to texture # create our frame buffer fbo = gl.GLuint() gl.glGenFramebuffersEXT(1, ctypes.byref(fbo)) gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, fbo) # allocate a texture and add to the frame buffer tex = image.Texture.create_for_size(gl.GL_TEXTURE_2D, w, h, 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 # now render gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, fbo) function() gl.glBindFramebufferEXT(gl.GL_FRAMEBUFFER_EXT, 0) # clean up gl.glDeleteFramebuffersEXT(1, ctypes.byref(fbo)) else: # render and copy to texture # render function() # grab the buffer and copy contents to the texture buffer = image.get_buffer_manager().get_color_buffer() tex = image.Texture.create_for_size(gl.GL_TEXTURE_2D, w, h, gl.GL_RGBA) tex.blit_into(buffer.get_region(0, 0, w, h), 0, 0, 0) gl.glMatrixMode(gl.GL_PROJECTION) gl.glPopMatrix() gl.glPopAttrib() # return the region (the whole texture will most likely be larger) return tex.get_region(0, 0, w, h)
def __init__(self, width, height): """Creates a FBO""" self.initialized = False assert self.supported() self.width = width self.height = height self.framebuffer_id = ctypes.c_uint(0) self.depthbuffer_id = ctypes.c_uint(0) self.texture_id = ctypes.c_uint(0) # Frame buffer gl.glGenFramebuffersEXT( 1, # number of buffers created ctypes.byref(self.framebuffer_id), # dest. id ) self.initialized = True with self._bound_context(gl.GL_FRAMEBUFFER_EXT): # Depth buffer gl.glGenRenderbuffersEXT( 1, # no. of buffers created ctypes.byref(self.depthbuffer_id), # dest. id ) gl.glBindRenderbufferEXT( gl.GL_RENDERBUFFER_EXT, # target self.depthbuffer_id, # id ) gl.glRenderbufferStorageEXT( gl.GL_RENDERBUFFER_EXT, # target gl.GL_DEPTH_COMPONENT, # internal format self.width, self.height, # size ) gl.glFramebufferRenderbufferEXT( gl.GL_FRAMEBUFFER_EXT, # target gl.GL_DEPTH_ATTACHMENT_EXT, # attachment point gl.GL_RENDERBUFFER_EXT, # renderbuffer target self.depthbuffer_id, # renderbuffer id ) # Target Texture gl.glGenTextures( 1, # no. of textures ctypes.byref(self.texture_id), # dest. id ) gl.glBindTexture( gl.GL_TEXTURE_2D, # target self.texture_id, # texture id ) # Black magic (props to pyprocessing!) # (nearest works, as well as linear) gl.glTexParameteri( gl.GL_TEXTURE_2D, # target gl.GL_TEXTURE_MAG_FILTER, # property name gl.GL_LINEAR, # value ) gl.glTexParameteri( gl.GL_TEXTURE_2D, # target gl.GL_TEXTURE_MIN_FILTER, # property name gl.GL_LINEAR, # value ) # Attach texture to FBO gl.glTexImage2D( gl.GL_TEXTURE_2D, # target 0, # mipmap level (0=default) gl.GL_RGBA8, # internal format self.width, self.height, # size 0, # border gl.GL_RGBA, # format gl.GL_UNSIGNED_BYTE, # type None, # data ) gl.glFramebufferTexture2DEXT( gl.GL_FRAMEBUFFER_EXT, # target gl.GL_COLOR_ATTACHMENT0_EXT, # attachment point gl.GL_TEXTURE_2D, # texture target self.texture_id, # tex id 0, # mipmap level ) # sanity check status = gl.glCheckFramebufferStatusEXT(gl.GL_FRAMEBUFFER_EXT) assert status == gl.GL_FRAMEBUFFER_COMPLETE_EXT