def bind(self): if self is not _SnapOffscreen.bound: if _SnapOffscreen.bound is None: bgl.glGetIntegerv(bgl.GL_FRAMEBUFFER_BINDING, self.cur_fbo) bgl.glGetIntegerv(bgl.GL_VIEWPORT, self.cur_viewport) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.fbo[0]) bgl.glViewport(0, 0, self.width, self.height) _SnapOffscreen.bound = self
def __init__(self, width, height): import ctypes self.freed = False self.is_bound = False self.width = width self.height = height self.fbo = bgl.Buffer(bgl.GL_INT, 1) self.buf_color = bgl.Buffer(bgl.GL_INT, 1) self.buf_depth = bgl.Buffer(bgl.GL_INT, 1) self.cur_fbo = bgl.Buffer(bgl.GL_INT, 1) self.cur_viewport = bgl.Buffer(bgl.GL_INT, 4) bgl.glGenRenderbuffers(1, self.buf_depth) bgl.glBindRenderbuffer(bgl.GL_RENDERBUFFER, self.buf_depth[0]) bgl.glRenderbufferStorage(bgl.GL_RENDERBUFFER, bgl.GL_DEPTH_COMPONENT, width, height) bgl.glGenTextures(1, self.buf_color) bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.buf_color[0]) NULL = bgl.Buffer(bgl.GL_INT, 1, (ctypes.c_int32 * 1).from_address(0)) bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_R32UI, width, height, 0, bgl.GL_RED_INTEGER, bgl.GL_UNSIGNED_INT, NULL) del NULL bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_NEAREST) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST) bgl.glGetIntegerv(bgl.GL_FRAMEBUFFER_BINDING, self.cur_fbo) bgl.glGenFramebuffers(1, self.fbo) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.fbo[0]) bgl.glFramebufferRenderbuffer(bgl.GL_FRAMEBUFFER, bgl.GL_DEPTH_ATTACHMENT, bgl.GL_RENDERBUFFER, self.buf_depth[0]) bgl.glFramebufferTexture(bgl.GL_FRAMEBUFFER, bgl.GL_COLOR_ATTACHMENT0, self.buf_color[0], 0) bgl.glDrawBuffers( 1, bgl.Buffer(bgl.GL_INT, 1, [bgl.GL_COLOR_ATTACHMENT0])) status = bgl.glCheckFramebufferStatus(bgl.GL_FRAMEBUFFER) if status != bgl.GL_FRAMEBUFFER_COMPLETE: print("Framebuffer Invalid", status) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.cur_fbo[0])
def genfb(self, width, height): buf = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenFramebuffers(1, buf) self.fb = buf[0] bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.fb) bgl.glGenTextures(1, buf) self.tex = buf[0] bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.tex) bgl.glTexImage2D(bgl.GL_TEXTURE_2D, 0, bgl.GL_RGBA16F, width, height, 0, bgl.GL_RGBA, bgl.GL_FLOAT, None) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_NEAREST) bgl.glFramebufferTexture(bgl.GL_FRAMEBUFFER, bgl.GL_COLOR_ATTACHMENT0, self.tex, 0) bgl.glGenRenderbuffers(1, buf) self.depth = buf[0] bgl.glBindRenderbuffer(bgl.GL_RENDERBUFFER, self.depth) bgl.glRenderbufferStorage(bgl.GL_RENDERBUFFER, bgl.GL_DEPTH_COMPONENT, width, height) bgl.glFramebufferRenderbuffer(bgl.GL_FRAMEBUFFER, bgl.GL_DEPTH_ATTACHMENT, bgl.GL_RENDERBUFFER, self.depth) status = bgl.glCheckFramebufferStatus(bgl.GL_FRAMEBUFFER) if status == 0: glerr("Could not get framebuffer status") elif status != bgl.GL_FRAMEBUFFER_COMPLETE: msg = { bgl.GL_FRAMEBUFFER_UNDEFINED: "undefined", bgl.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: "incomplete attachment", bgl.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: "missing attachment", bgl.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: "incomplete draw buffer", bgl.GL_FRAMEBUFFER_UNSUPPORTED: "unsupported", bgl.GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: "incomplete multisample", bgl.GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: "incomplete layer targets", }.get(status, "unknown ({:x})".format(status)) raise RuntimeError("Could not initialize GL framebuffer: " + msg)
def render(self, dg): scene = dg.scene scale = scene.render.resolution_percentage / 100.0 width = int(scene.render.resolution_x * scale) height = int(scene.render.resolution_y * scale) zu.blen_gl_enable() try: # Create drawing target self.genfb(width, height) # Prep Zu scene self.scene = zu.scene_new() view_mat = self.camera_model_matrix(scene.camera) view_mat.invert() win_mat = scene.camera.calc_matrix_camera(dg, x=width, y=height) cam = win_mat @ view_mat zu.scene_cam(self.scene, mat(cam)) self.load_dg(dg) # Render bgl.glViewport(0, 0, width, height) zu.scene_draw(self.scene, self.fb) # Retrieve texture data pixels = bgl.Buffer(bgl.GL_FLOAT, width * height * 4) bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, pixels) # Copy pixel data to output result = self.begin_result(0, 0, width, height) layer = result.layers[0].passes["Combined"] pixels = pixels.to_list() layer.rect = list( zip(*[pixels[i::4] for i in range(4)])) # FIXME: holy f**k this is slow self.end_result(result) finally: del self.objects self.objects = None del self.scene self.scene = None bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, 0) self.delfb() zu.blen_gl_disable()
def prepare_viewport(self, ctx, dg): width, height = ctx.region.width, ctx.region.height self.dim = (width, height) buf = bgl.Buffer(bgl.GL_INT, 1) bgl.glGetIntegerv(bgl.GL_DRAW_FRAMEBUFFER_BINDING, buf) fb = buf[0] self.genfb(width, height) bgl.glGenVertexArrays(1, buf) self.vao = buf[0] bgl.glBindVertexArray(self.vao) quad = bgl.Buffer(bgl.GL_FLOAT, 2 * 4, [0, 0, width, 0, width, height, 0, height]) uv = bgl.Buffer(bgl.GL_FLOAT, 2 * 4, [0, 0, 1, 0, 1, 1, 0, 1]) self.bind_display_space_shader(dg.scene) bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, buf) self.unbind_display_space_shader() self.quad_in = bgl.glGetAttribLocation(buf[0], "pos") self.uv_in = bgl.glGetAttribLocation(buf[0], "texCoord") bgl.glEnableVertexAttribArray(self.quad_in) bgl.glEnableVertexAttribArray(self.uv_in) self.vtx_buf = bgl.Buffer(bgl.GL_INT, 2) bgl.glGenBuffers(2, self.vtx_buf) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vtx_buf[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 2 * 4 * 4, quad, bgl.GL_STATIC_DRAW) bgl.glVertexAttribPointer(self.quad_in, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vtx_buf[1]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, 2 * 4 * 4, uv, bgl.GL_STATIC_DRAW) bgl.glVertexAttribPointer(self.uv_in, 2, bgl.GL_FLOAT, bgl.GL_FALSE, 0, None) bgl.glDisableVertexAttribArray(self.quad_in) bgl.glDisableVertexAttribArray(self.uv_in) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, fb)
def __init__(self, width, height): self.freed = False self.is_bound = False self.width = width self.height = height self.fbo = bgl.Buffer(bgl.GL_INT, 1) self.buf_color = bgl.Buffer(bgl.GL_INT, 1) self.buf_depth = bgl.Buffer(bgl.GL_INT, 1) self.cur_fbo = bgl.Buffer(bgl.GL_INT, 1) self.cur_viewport = bgl.Buffer(bgl.GL_INT, 4) bgl.glGenRenderbuffers(1, self.buf_depth) bgl.glGenTextures(1, self.buf_color) self._config_textures() bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_NEAREST) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_NEAREST) bgl.glGetIntegerv(bgl.GL_FRAMEBUFFER_BINDING, self.cur_fbo) bgl.glGenFramebuffers(1, self.fbo) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.fbo[0]) bgl.glFramebufferRenderbuffer(bgl.GL_FRAMEBUFFER, bgl.GL_DEPTH_ATTACHMENT, bgl.GL_RENDERBUFFER, self.buf_depth[0]) bgl.glFramebufferTexture(bgl.GL_FRAMEBUFFER, bgl.GL_COLOR_ATTACHMENT0, self.buf_color[0], 0) bgl.glDrawBuffers( 1, bgl.Buffer(bgl.GL_INT, 1, [bgl.GL_COLOR_ATTACHMENT0])) status = bgl.glCheckFramebufferStatus(bgl.GL_FRAMEBUFFER) if status != bgl.GL_FRAMEBUFFER_COMPLETE: print("Framebuffer Invalid", status) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.cur_fbo[0])
def view_draw(self, ctx, dg): if self.scene is None: return buf = bgl.Buffer(bgl.GL_INT, 1) bgl.glGetIntegerv(bgl.GL_DRAW_FRAMEBUFFER_BINDING, buf) if buf[0] == 0: return width, height = ctx.region.width, ctx.region.height if self.dim != (width, height): self.delfb() self.prepare_viewport(ctx, dg) # Render the scene bgl.glViewport(0, 0, width, height) cam = ctx.region_data.perspective_matrix zu.scene_cam(self.scene, mat(cam)) zu.scene_draw(self.scene, self.fb) # Copy the rendered scene to the viewport (through the color space adjustment shader) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, buf[0]) bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) self.bind_display_space_shader(dg.scene) bgl.glBindVertexArray(self.vao) bgl.glEnableVertexAttribArray(self.quad_in) bgl.glEnableVertexAttribArray(self.uv_in) bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.tex) bgl.glDrawArrays(bgl.GL_TRIANGLE_FAN, 0, 4) bgl.glBindTexture(bgl.GL_TEXTURE_2D, 0) bgl.glDisableVertexAttribArray(self.quad_in) bgl.glDisableVertexAttribArray(self.uv_in) bgl.glBindVertexArray(0) self.unbind_display_space_shader() bgl.glDisable(bgl.GL_BLEND)
def __init__(self, width, height): self.freed = False self.is_bound = False self.width = width self.height = height self.fbo = bgl.Buffer(bgl.GL_INT, 1) self.buf_color = bgl.Buffer(bgl.GL_INT, 1) self.buf_depth = bgl.Buffer(bgl.GL_INT, 1) self.cur_fbo = bgl.Buffer(bgl.GL_INT, 1) self.cur_viewport = bgl.Buffer(bgl.GL_INT, 4) bgl.glGenRenderbuffers(1, self.buf_depth) bgl.glGenTextures(1, self.buf_color) self._config_textures() bgl.glGetIntegerv(bgl.GL_FRAMEBUFFER_BINDING, self.cur_fbo) bgl.glGenFramebuffers(1, self.fbo) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.fbo[0]) bgl.glFramebufferRenderbuffer( bgl.GL_FRAMEBUFFER, bgl.GL_DEPTH_ATTACHMENT, bgl.GL_RENDERBUFFER, self.buf_depth[0]) bgl.glFramebufferTexture(bgl.GL_FRAMEBUFFER, bgl.GL_COLOR_ATTACHMENT0, self.buf_color[0], 0) bgl.glDrawBuffers(1, bgl.Buffer(bgl.GL_INT, 1, [bgl.GL_COLOR_ATTACHMENT0])) status = bgl.glCheckFramebufferStatus(bgl.GL_FRAMEBUFFER) if status != bgl.GL_FRAMEBUFFER_COMPLETE: print("Framebuffer Invalid", status) bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.cur_fbo[0])
def unbind(self): if self is _SnapOffscreen.bound: bgl.glBindFramebuffer(bgl.GL_FRAMEBUFFER, self.cur_fbo[0]) bgl.glViewport(*self.cur_viewport) _SnapOffscreen.bound = None