def render_to_texture(): # select the target to draw into gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) gl.glViewport(0, 0, FB_WIDTH, FB_HEIGHT) # clear the destination gl.glClearColor(0.5, 0.6, 0.7, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) # prepare the rendering gl.glUseProgram(render_program) # send the vertex data data = (COLOR_VERTEX * 3)(((-0.6, -0.5), (1.0, 0.0, 0.0, 1.0)), ((0.6, -0.5), (0.0, 1.0, 0.0, 1.0)), ((0.0, 0.5), (0.0, 0.0, 1.0, 1.0))) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data), data, gl.GL_DYNAMIC_DRAW) # draw using the vertex array for vertex information gl.glBindVertexArray(render_vao) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) gl.glBindVertexArray(0)
def __init__(self, width, height, window, num_color_attachments=1, mapping_mode=None, provide_depth=False, provide_stencil=False): """"Create an arbitrary layer framebuffer, I'll add stencil and depthbuffers if I ever package this for resuse, in pyweek, those args are pretty much placeholders""" if mapping_mode is None: mapping_mode = gl.GL_NEAREST assert not provide_stencil, 'stencil buffer not implemented' assert not provide_depth, 'depth buffer not implemented' self.window = window self.width = width self.height = height self.bufferId = gl.GLuint(0) self.textureIds = [] self.buffer_args = [] #create the vram objects? gl.glGenFramebuffers(1, rf(self.bufferId)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.bufferId) for bufferIndex in range(num_color_attachments): newTex = gl.GLuint(0) gl.glGenTextures(1, rf(newTex)) self.textureIds.append(newTex) gl.glBindTexture(gl.GL_TEXTURE_2D, newTex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, width, height, 0, gl.GL_RGB, gl.GL_UNSIGNED_INT, 0) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, mapping_mode) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, mapping_mode) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0 + bufferIndex, gl.GL_TEXTURE_2D, newTex, 0) self.buffer_args.append(gl.GL_COLOR_ATTACHMENT0 + bufferIndex) #assign one of the vram objects to the framebuffer cache? if provide_depth: self.buffer_args.append(gl.GL_DEPTH_ATTACHMENT) if provide_stencil: self.buffer_args.append(gl.GL_STENCIL_ATTACHMENT) self.buffers_provided = (gl.GLenum * len(self.buffer_args))(*self.buffer_args) gl.glDrawBuffers(len(self.buffer_args), self.buffers_provided) self.textures = [ Texture(self.width, self.height, gl.GL_TEXTURE_2D, texId.value) for texId in self.textureIds ] assert gl.glCheckFramebufferStatus( gl.GL_FRAMEBUFFER ) == gl.GL_FRAMEBUFFER_COMPLETE, "I don't know why this happened, but at least I can find out"
def _use(self): """Internal use that do not change the global active framebuffer""" if self.ctx.active_framebuffer == self: return gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self._glo) # NOTE: gl.glDrawBuffer(GL_NONE) if no texture attachments (future) # NOTE: Default framebuffer currently has this set to None if self._draw_buffers: gl.glDrawBuffers(len(self._draw_buffers), self._draw_buffers) gl.glDepthMask(self._depth_mask) gl.glViewport(*self._viewport)
def __init__(self, width, height): self.fbo = gl.GLuint(0) gl.glGenFramebuffers(1, ctypes.byref(self.fbo)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo) self.texture = pyglet.image.Texture.create(width, height) gl.glBindTexture(self.texture.target, 0) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.texture.id, 0) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) assert gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
def setup_framebuffer(): gl.glGenFramebuffers(1, ctypes.byref(framebuffer)) gl.glGenTextures(1, ctypes.byref(rendered_texture)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer) # Set up the texture as the target for color output gl.glBindTexture(gl.GL_TEXTURE_2D, rendered_texture) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, FB_WIDTH, FB_HEIGHT, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, 0) 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.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, rendered_texture, 0) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) assert gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE
def __init__(self, width, height): self.fbo = gl.GLuint(0) gl.glGenFramebuffers(1, ctypes.byref(self.fbo)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo) self.texture = pyglet.image.Texture.create(width, height) gl.glBindTexture(self.texture.target, 0) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.texture.id, 0) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) assert gl.glCheckFramebufferStatus( gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
def __init__(self, size: Tuple[int, int], textures: Dict[str, Texture] = {}, depth_unit: int = None, autoclear: bool = False, set_viewport: bool = False): self.name = gl.GLuint() self.size = w, h = size self.autoclear = autoclear self.set_viewport = set_viewport gl.glCreateFramebuffers(1, byref(self.name)) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.name) # Create textures that we can use to read the results. self.textures = {} draw_attachments = [] max_unit = 0 for name, texture in textures.items(): self.textures[name] = texture attachment = gl.GL_COLOR_ATTACHMENT0 + texture.unit gl.glFramebufferTexture(gl.GL_FRAMEBUFFER, attachment, texture.name, 0) draw_attachments.append(attachment) max_unit = max(max_unit, texture.unit) # Setup a depth buffer (presumably we always want that) depth_unit = depth_unit if depth_unit is not None else max_unit + 1 self.textures["depth"] = depth_texture = DepthTexture(self.size, unit=depth_unit) gl.glFramebufferTexture(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, depth_texture.name, 0) # Setup draw buffers and connect them to the textures. self.draw_buffers = (gl.GLenum * len(textures))(*draw_attachments) gl.glDrawBuffers(len(self.draw_buffers), self.draw_buffers) # Check that it all went smoothly assert (gl.glCheckFramebufferStatus( gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE ), "Could not setup framebuffer!" gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
def render_to_texture(in_size, out_size, view_z=None): z0, z1 = (0, in_size[2]) if view_z == None else view_z vertices = (VERTEX * 6)(((-1, -1), (0, 0)), ((1, -1), (1, 0)), ((1, 1), (1, 1)), ((1, 1), (1, 1)), ((-1, 1), (0, 1)), ((-1, -1), (0, 0))) gl.glBindTexture(gl.GL_TEXTURE_3D, rendered_texture) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) gl.glViewport(0, 0, out_size[0], out_size[1]) gl.glUseProgram(render_program) loc_depth = gl.glGetUniformLocation(render_program, ctypes.create_string_buffer(b'depth')) loc_texelSize = gl.glGetUniformLocation( render_program, ctypes.create_string_buffer(b'texelSize')) gl.glUniform3f(loc_texelSize, 1 / in_size[0], 1 / in_size[1], 1 / in_size[2]) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(vertices), vertices, gl.GL_DYNAMIC_DRAW) gl.glBindVertexArray(render_vao) gl.glClearColor(0.0, 0.0, 0.0, 0.0) for z in range(out_size[2]): gl.glFramebufferTexture3D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_3D, rendered_texture, 0, z) fbs = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) assert fbs == gl.GL_FRAMEBUFFER_COMPLETE, 'FramebufferStatus is {}'.format( fbs) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glUniform1f(loc_depth, (z0 + z * (z1 - z0)) / in_size[2] / out_size[2]) gl.glBindTexture(gl.GL_TEXTURE_3D, input_texture) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) if z % 10 == 0: gl.glFinish() print('\033[K{}/{}'.format(z, out_size[2] - 1), end='\r') gl.glFinish() gl.glBindVertexArray(0)
def resize(self, width, height): ''' resizes the framebuffer to the given dimensions ''' gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo) gl.glBindTexture(gl.GL_TEXTURE_2D, self.rendered_texture) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB, width, height, 0, gl.GL_RGB, gl.GL_UNSIGNED_BYTE, 0) 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.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.rendered_texture, 0) gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self.depthrenderbuffer) gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_DEPTH_COMPONENT, width, height) gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_DEPTH_ATTACHMENT, gl.GL_RENDERBUFFER, self.depthrenderbuffer) gl.glBindRenderbuffer(gl.GL_RENDERBUFFER, self.pickingbuffer) gl.glRenderbufferStorage(gl.GL_RENDERBUFFER, gl.GL_R16UI, width, height) gl.glFramebufferRenderbuffer(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT1, gl.GL_RENDERBUFFER, self.pickingbuffer) draw_buffers = (gl.GLenum * 2)(gl.GL_COLOR_ATTACHMENT0, gl.GL_COLOR_ATTACHMENT1) gl.glDrawBuffers(2, draw_buffers) if gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) != gl.GL_FRAMEBUFFER_COMPLETE: logging.error('setting up fbo failed') gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0)
def setupFBOandTextures(self): self.framebufferA0 = gl.GLuint(0) self.framebufferA1 = gl.GLuint(0) self.framebufferB0 = gl.GLuint(0) self.framebufferB1 = gl.GLuint(0) self.A0_tex = gl.GLuint(0) self.A1_tex = gl.GLuint(0) self.B0_tex = gl.GLuint(0) self.B1_tex = gl.GLuint(0) self.draw_buffersA0 = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) self.draw_buffersA1 = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) self.draw_buffersB0 = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) self.draw_buffersB1 = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glGenFramebuffers(1, ctypes.byref(self.framebufferA0)) gl.glGenFramebuffers(1, ctypes.byref(self.framebufferA1)) gl.glGenFramebuffers(1, ctypes.byref(self.framebufferB0)) gl.glGenFramebuffers(1, ctypes.byref(self.framebufferB1)) gl.glGenTextures(1, ctypes.byref(self.A0_tex)) gl.glGenTextures(1, ctypes.byref(self.A1_tex)) gl.glGenTextures(1, ctypes.byref(self.B0_tex)) gl.glGenTextures(1, ctypes.byref(self.B1_tex)) #A gl.glActiveTexture(gl.GL_TEXTURE0) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferA0) gl.glBindTexture(gl.GL_TEXTURE_2D, self.A0_tex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.dimx, self.dimy, 0, gl.GL_RGBA, gl.GL_FLOAT, self.Ap) 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) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.A0_tex, 0) gl.glDrawBuffers(1, self.draw_buffersA0) assert gl.glCheckFramebufferStatus( gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE gl.glActiveTexture(gl.GL_TEXTURE1) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferA1) # Set up the texture as the target for color output gl.glBindTexture(gl.GL_TEXTURE_2D, self.A1_tex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.dimx, self.dimy, 0, gl.GL_RGBA, gl.GL_FLOAT, self.Ap) 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) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.A1_tex, 0) gl.glDrawBuffers(1, self.draw_buffersA1) assert gl.glCheckFramebufferStatus( gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE #B gl.glActiveTexture(gl.GL_TEXTURE2) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferB0) gl.glBindTexture(gl.GL_TEXTURE_2D, self.B0_tex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.dimx, self.dimy, 0, gl.GL_RGBA, gl.GL_FLOAT, self.Bp) 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) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.B0_tex, 0) gl.glDrawBuffers(1, self.draw_buffersB0) assert gl.glCheckFramebufferStatus( gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE gl.glActiveTexture(gl.GL_TEXTURE3) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebufferB1) # Set up the texture as the target for color output gl.glBindTexture(gl.GL_TEXTURE_2D, self.B1_tex) gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA, self.dimx, self.dimy, 0, gl.GL_RGBA, gl.GL_FLOAT, self.Bp) 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) gl.glFramebufferTexture2D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_2D, self.B1_tex, 0) gl.glDrawBuffers(1, self.draw_buffersB1) assert gl.glCheckFramebufferStatus( gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE
def __enter__(self): gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.framebuffer) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) gl.glViewport(0, 0, self.width, self.height)
def __enter__(self): gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.bufferId) gl.glDrawBuffers(len(self.buffer_args), self.buffers_provided) gl.glViewport(0, 0, self.width, self.height) return self