def draw(self, context): if self._area != context.area: return Globals.drawing.glCheckError('UI_Document.draw: start') time_start = time.time() self.force_clean(context) Globals.drawing.glCheckError('UI_Document.draw: setting options') ScissorStack.start(context) bgl.glClearColor(0, 0, 0, 0) bgl.glBlendColor(0, 0, 0, 0) # bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) bgl.glEnable(bgl.GL_BLEND) bgl.glEnable(bgl.GL_SCISSOR_TEST) bgl.glDisable(bgl.GL_DEPTH_TEST) bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT) Globals.drawing.glCheckError('UI_Document.draw: drawing') self._body.draw() ScissorStack.end() self._draw_count += 1 self._draw_time += time.time() - time_start if self._draw_count % 100 == 0: fps = (self._draw_count / self._draw_time) if self._draw_time > 0 else float('inf') self._draw_fps = fps # print('~%f fps (%f / %d = %f)' % (self._draw_fps, self._draw_time, self._draw_count, self._draw_time / self._draw_count)) self._draw_count = 0 self._draw_time = 0 Globals.drawing.glCheckError('UI_Document.draw: done')
def update_all(self): self.drawn_count = 0 self._offset_cur = 1 bgl.glClearColor(0.0, 0.0, 0.0, 0.0) check_error("glClearColor") bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) check_error("glClear")
def draw(self, context): log("Draw") if not self.is_synced: return stage = self.stage if not stage: return view_settings = ViewSettings(context) if view_settings.width * view_settings.height == 0: return gf_camera = view_settings.export_camera() self.renderer.SetCameraState( gf_camera.frustum.ComputeViewMatrix(), gf_camera.frustum.ComputeProjectionMatrix()) if self.is_gl_delegate: self.renderer.SetRenderViewport( (*view_settings.border[0], *view_settings.border[1])) else: self.renderer.SetRenderViewport((0, 0, *view_settings.border[1])) self.renderer.SetRendererAov('color') self.render_params.renderResolution = (view_settings.width, view_settings.height) if self.is_gl_delegate: bgl.glEnable(bgl.GL_DEPTH_TEST) else: bgl.glDisable(bgl.GL_DEPTH_TEST) bgl.glViewport(*view_settings.border[0], *view_settings.border[1]) bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClearDepth(1.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) # Bind shader that converts from scene linear to display space, bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ONE_MINUS_SRC_ALPHA) self.render_engine.bind_display_space_shader(context.scene) try: self.renderer.Render(stage.GetPseudoRoot(), self.render_params) except Exception as e: log.error(e) self.render_engine.unbind_display_space_shader() bgl.glDisable(bgl.GL_BLEND) if not self.renderer.IsConverged(): self.notify_status("Rendering...", "") else: self.notify_status("Rendering Done", "", False)
def render_debug_cross(context, props: MasterProperties) -> (bgl.Buffer, int): """ Render debug cross :returns buffer with image and draw call count """ shaders = Shaders() offscreen = gpu.types.GPUOffScreen(props.resolution.resolution_x, props.resolution.resolution_y) draw_count = 0 quad_batch = batch_quad(shaders.debug) with offscreen.bind(): # black background bgl.glClearColor(0.0, 0.0, 0.0, 1.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE) shaders.debug.bind() for position in props.positions: pos = Vector((position.manual_x, position.manual_y)) # set position from object if position.variant == 'auto' and position.auto_object is not None: world_pos = position.auto_object.matrix_world.to_translation() pos = bpy_extras.object_utils.world_to_camera_view( context.scene, context.scene.camera, world_pos) uniforms = { "flare_position": pos.xy, "aspect_ratio": props.resolution.resolution_x / props.resolution.resolution_y, } set_float_uniforms(shaders.debug, uniforms) quad_batch.draw(shaders.debug) draw_count += 1 # copy rendered image to RAM buffer = bgl.Buffer( bgl.GL_FLOAT, props.resolution.resolution_x * props.resolution.resolution_y * 4) bgl.glReadBuffer(bgl.GL_BACK) bgl.glReadPixels(0, 0, props.resolution.resolution_x, props.resolution.resolution_y, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) return buffer, draw_count
def export(filepath, face_data, colors, width, height, opacity): offscreen = gpu.types.GPUOffScreen(width, height) offscreen.bind() try: bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) draw_image(face_data, opacity) pixel_data = get_pixel_data_from_current_back_buffer(width, height) save_pixels(filepath, pixel_data, width, height) finally: offscreen.unbind() offscreen.free()
def clear(self): is_bound = self is _SnapOffscreen.bound if not is_bound: self.bind() bgl.glColorMask(bgl.GL_TRUE, bgl.GL_TRUE, bgl.GL_TRUE, bgl.GL_TRUE) bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glDepthMask(bgl.GL_TRUE) bgl.glClearDepth(1.0); bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) if not is_bound: self.unbind()
def h_clip_begin(bounds, padding=[0, 0, 0, 0]): vp = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_VIEWPORT, vp) B = [bounds[0]+padding[0], bounds[1]+padding[1], bounds[2]-padding[2]*2, bounds[3]-padding[3]*2] # Do some math to invert the coords scp = [0, 0, int(B[2]), int(B[3])] scp[0] = int(B[0] + vp[0]) scp[1] = int(vp[1] + (vp[3] - B[1] - B[3])) bgl.glEnable(bgl.GL_SCISSOR_TEST) bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_SCISSOR_BIT) bgl.glScissor(*scp)
def _render_gl(self, scene): CLEAR_COLOR = (0.0, 0.0, 0.0, 0.0) CLEAR_DEPTH = 1.0 # creating draw_target draw_target = Glf.DrawTarget(self.width, self.height) draw_target.Bind() draw_target.AddAttachment("color", bgl.GL_RGBA, bgl.GL_FLOAT, bgl.GL_RGBA) draw_target.AddAttachment("depth", bgl.GL_DEPTH_COMPONENT, bgl.GL_FLOAT, bgl.GL_DEPTH_COMPONENT32F) # creating renderer renderer = UsdImagingGL.Engine() log("Hydra render:", scene.hdusd.final.delegate) renderer.SetRendererPlugin(scene.hdusd.final.delegate) # setting camera self._set_scene_camera(renderer, scene) renderer.SetRenderViewport((0, 0, self.width, self.height)) renderer.SetRendererAov('color') bgl.glEnable(bgl.GL_DEPTH_TEST) bgl.glViewport(0, 0, self.width, self.height) bgl.glClearColor(*CLEAR_COLOR) bgl.glClearDepth(CLEAR_DEPTH) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) root = self.stage.GetPseudoRoot() params = UsdImagingGL.RenderParams() params.renderResolution = (self.width, self.height) params.frame = Usd.TimeCode.Default() params.clearColor = CLEAR_COLOR try: renderer.Render(root, params) except Exception as e: log.error(e) self.update_render_result({ 'Combined': gl.get_framebuffer_data(self.width, self.height) }) draw_target.Unbind() # it's important to clear data explicitly draw_target = None renderer = None
def draw_callback_px(context): # Note that the "context" passed in here is a regular dictionary and not the Blender context global screen_display_lines pid = None if 'mcell' in bpy.context.scene: mcell = bpy.context.scene.mcell if 'run_simulation' in mcell: rs = mcell.run_simulation if len(rs.processes_list) > 0: pid_str = rs.processes_list[rs.active_process_index].name pid = pid_str.split(',')[0].split()[1] bgl.glPushAttrib(bgl.GL_ENABLE_BIT) if parameter_dictionary['Clear']['val']: bgl.glClearColor(0.0, 0.0, 0.0, 1.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) font_id = 0 # XXX, need to find out how best to get this. y_pos = 15 * (scroll_offset + 1) if pid and (pid in screen_display_lines): for l in screen_display_lines[pid]: blf.position(font_id, 15, y_pos, 0) y_pos += 15 blf.size(font_id, 14, 72) # fontid, size, DPI bgl.glColor4f(1.0, 1.0, 1.0, 0.5) blf.draw(font_id, l) else: keys = screen_display_lines.keys() for k in keys: for l in screen_display_lines[k]: blf.position(font_id, 15, y_pos, 0) y_pos += 15 blf.size(font_id, 14, 72) # fontid, size, DPI bgl.glColor4f(1.0, 1.0, 1.0, 0.5) blf.draw(font_id, l) # 100% alpha, 2 pixel width line bgl.glEnable(bgl.GL_BLEND) bgl.glPopAttrib() # restore opengl defaults bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0)
def render_ghost(props: MasterProperties, ghost, ghost_shader, ghost_batch, flare_vector, flare_position): """ Renders ghost to active buffer """ # black background bgl.glClearColor(0.0, 0.0, 0.0, 1.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE) # calculate position ghost_x = ((flare_position.x - 0.5) * 2.0) * ghost.offset ghost_y = ((flare_position.y - 0.5) * 2.0) * ghost.offset # add perpendicular offset ghost_x += flare_vector.y * ghost.perpendicular_offset ghost_y += -flare_vector.x * ghost.perpendicular_offset ratio = props.resolution.resolution_x / props.resolution.resolution_y ghost_shader.bind() # transform matrix model_matrix = Matrix.Translation( (ghost_x, ghost_y, 0.0)) @ Matrix.Scale(ghost.size / 100, 4) ghost_uniforms = { # move and scale ghosts "modelMatrix": model_matrix, # rotate ghost "rotationMatrix": Matrix.Rotation(props.camera.rotation, 4, 'Z'), # set color and intensity "color": Vector((ghost.color[0], ghost.color[1], ghost.color[2], 1)), # set centers "empty": ghost.center_transparency, # aspect ratio of destination image "aspect_ratio": ratio, # anamorphic lens simulation "ratio": ghost.ratio, } set_float_uniforms(ghost_shader, ghost_uniforms) ghost_batch.draw(ghost_shader)
def offscreen_refresh(self, context): if self.offscreen is not None: self.offscreen.free() width, height = self.get_resolution() self.offscreen = gpu.types.GPUOffScreen(width, height) mat_offscreen = Matrix() mat_offscreen[0][0] = 2 / width mat_offscreen[0][3] = -1 mat_offscreen[1][1] = 2 / height mat_offscreen[1][3] = -1 with self.offscreen.bind(): bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) with gpu.matrix.push_pop(): gpu.matrix.load_matrix(mat_offscreen) gpu.matrix.load_projection_matrix(Matrix()) draw_gems(self, context, gamma_corr=True)
def render_main(self, context, objlist, animation=False): # noinspection PyBroadException,PyBroadException # Save old info scene = context.scene render = scene.render settings = render.image_settings depth = settings.color_depth settings.color_depth = '8' # noinspection PyBroadException try: # Get visible layers layers = [] for x in range(0, 20): if scene.layers[x] is True: layers.extend([x]) # -------------------- # Get resolution # -------------------- render_scale = render.resolution_percentage / 100 width = int(render.resolution_x * render_scale) height = int(render.resolution_y * render_scale) # --------------------------------------- # Get output path # --------------------------------------- temp_path = path.realpath(bpy.app.tempdir) if len(temp_path) > 0: outpath = path.join(temp_path, "archipack_tmp_render.png") else: self.report({ 'ERROR' }, "Archipack: Unable to save temporary render image. Define a valid temp path" ) settings.color_depth = depth return False # Get Render Image img = self.get_render_image(outpath) if img is None: self.report({ 'ERROR' }, "Archipack: Unable to save temporary render image. Define a valid temp path" ) settings.color_depth = depth return False # ----------------------------- # Calculate rows and columns # ----------------------------- tile_x = 240 tile_y = 216 row_num = ceil(height / tile_y) col_num = ceil(width / tile_x) print("Archipack: Image divided in " + str(row_num) + "x" + str(col_num) + " tiles") # pixels out of visible area cut4 = (col_num * tile_x * 4) - width * 4 # pixels aout of drawing area totpixel4 = width * height * 4 # total pixels RGBA viewport_info = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info) # Load image on memory img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST) # 2.77 API change if bpy.app.version >= (2, 77, 0): tex = img.bindcode[0] else: tex = img.bindcode # -------------------------------------------- # Create output image (to apply texture) # -------------------------------------------- if "archipack_output" in bpy.data.images: out_img = bpy.data.images["archipack_output"] if out_img is not None: out_img.user_clear() bpy.data.images.remove(out_img) out = bpy.data.images.new("archipack_output", width, height) tmp_pixels = [1] * totpixel4 # -------------------------------- # Loop for all tiles # -------------------------------- for row in range(0, row_num): for col in range(0, col_num): buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4) bgl.glDisable( bgl.GL_SCISSOR_TEST ) # if remove this line, get blender screenshot not image bgl.glViewport(0, 0, tile_x, tile_y) bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glLoadIdentity() # defines ortographic view for single tile x1 = tile_x * col y1 = tile_y * row bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y) # Clear bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex) # defines drawing area bgl.glBegin(bgl.GL_QUADS) bgl.glColor3f(1.0, 1.0, 1.0) bgl.glTexCoord2f(0.0, 0.0) bgl.glVertex2f(0.0, 0.0) bgl.glTexCoord2f(1.0, 0.0) bgl.glVertex2f(width, 0.0) bgl.glTexCoord2f(1.0, 1.0) bgl.glVertex2f(width, height) bgl.glTexCoord2f(0.0, 1.0) bgl.glVertex2f(0.0, height) bgl.glEnd() # ----------------------------- # Loop to draw all lines # ----------------------------- for o, d in objlist: if o.hide is False: # verify visible layer for x in range(0, 20): if o.layers[x] is True: if x in layers: context.scene.objects.active = o # print("%s: %s" % (o.name, d.manip_stack)) manipulators = d.manip_stack if manipulators is not None: for m in manipulators: if m is not None: m.draw_callback( m, context, render=True) break # ----------------------------- # Loop to draw all debug # ----------------------------- """ if scene.archipack_debug is True: selobj = bpy.context.selected_objects for myobj in selobj: if scene.archipack_debug_vertices is True: draw_vertices(context, myobj, None, None) if scene.archipack_debug_faces is True or scene.archipack_debug_normals is True: draw_faces(context, myobj, None, None) """ """ if scene.archipack_rf is True: bgl.glColor3f(1.0, 1.0, 1.0) rfcolor = scene.archipack_rf_color rfborder = scene.archipack_rf_border rfline = scene.archipack_rf_line bgl.glLineWidth(rfline) bgl.glColor4f(rfcolor[0], rfcolor[1], rfcolor[2], rfcolor[3]) x1 = rfborder x2 = width - rfborder y1 = int(ceil(rfborder / (width / height))) y2 = height - y1 draw_rectangle((x1, y1), (x2, y2)) """ # -------------------------------- # copy pixels to temporary area # -------------------------------- bgl.glFinish() bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) # read image data for y in range(0, tile_y): # final image pixels position p1 = (y * width * 4) + (row * tile_y * width * 4) + (col * tile_x * 4) p2 = p1 + (tile_x * 4) # buffer pixels position b1 = y * width * 4 b2 = b1 + (tile_x * 4) if p1 < totpixel4: # avoid pixel row out of area if col == col_num - 1: # avoid pixel columns out of area p2 -= cut4 b2 -= cut4 tmp_pixels[p1:p2] = buffer[b1:b2] # ----------------------- # Copy temporary to final # ----------------------- out.pixels = tmp_pixels[:] # Assign image data img.gl_free() # free opengl image memory # delete image img.user_clear() bpy.data.images.remove(img) # remove temp file remove(outpath) # reset bgl.glEnable(bgl.GL_SCISSOR_TEST) # ----------------------- # restore opengl defaults # ----------------------- bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0) # Saves image if out is not None: # and (scene.archipack_render is True or animation is True): ren_path = bpy.context.scene.render.filepath filename = "ap_frame" if len(ren_path) > 0: if ren_path.endswith(path.sep): initpath = path.realpath(ren_path) + path.sep else: (initpath, filename) = path.split(ren_path) ftxt = "%04d" % scene.frame_current outpath = path.realpath( path.join(initpath, filename + ftxt + ".png")) self.save_image(outpath, out) settings.color_depth = depth return True except: settings.color_depth = depth print("Unexpected error:" + str(exc_info())) self.report({ 'ERROR' }, "Archipack: Unable to create render image. Be sure the output render path is correct" ) return False
def drawBoltGPU(self, lines, pixels, coord, w, h): vertexSource = ''' in vec3 position; void main() { gl_Position = vec4(position, 1.0); } ''' geometrySource = ''' layout(lines) in; layout(triangle_strip, max_vertices = 4) out; void main() { float width = gl_in[1].gl_Position.z; vec2 line = gl_in[1].gl_Position.xy - gl_in[0].gl_Position.xy; vec2 normal = normalize(vec2(line.y, -line.x))*(width/2.0); for(int i=0; i<4; i++) { vec2 coords = gl_in[i/2].gl_Position.xy+(1-2*(i%2))*normal; gl_Position = vec4(coords, 0.0, 1.0); EmitVertex(); } EndPrimitive(); } ''' fragmentSource = ''' out vec4 fragColor; void main() { fragColor = vec4(1.0,1.0,1.0,1.0); } ''' positions = [] for segment in lines.segments: pts = lines.getCoords(segment)[0] ptA = np.divide(pts[0], np.array([w, h])) * 2 - 1.0 ptB = np.divide(pts[1], np.array([w, h])) * 2 - 1.0 width = bl_math.clamp( self.thickness * (1.0 - (segment.level / (self.falloff * lines.getMaxLevel()))), 0, self.thickness) / w positions.append((ptA[0], ptA[1], width)) positions.append((ptB[0], ptB[1], width)) offscreen = gpu.types.GPUOffScreen(w, h) shaders = gpu.types.GPUShader(vertexSource, fragmentSource, geocode=geometrySource) batch = batch_for_shader(shaders, 'LINES', {"position": tuple(positions)}) with offscreen.bind(): bgl.glClearColor(0.0, 0.0, 0.0, 1.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) with gpu.matrix.push_pop(): gpu.matrix.load_matrix(mathutils.Matrix.Identity(4)) gpu.matrix.load_projection_matrix(mathutils.Matrix.Identity(4)) shaders.bind() batch.draw(shaders) buffer = bgl.Buffer(bgl.GL_FLOAT, w * h * 4) bgl.glReadBuffer(bgl.GL_BACK) bgl.glReadPixels(0, 0, w, h, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) pixels.foreach_set(buffer) offscreen.free()
def render_opengl(self, context): from math import ceil layers = [] scene = context.scene for x in range(0, 20): if scene.layers[x] is True: layers.extend([x]) objlist = context.scene.objects render_scale = scene.render.resolution_percentage / 100 width = int(scene.render.resolution_x * render_scale) height = int(scene.render.resolution_y * render_scale) # I cant use file_format becuase the pdf writer needs jpg format # the file_format returns 'JPEG' not 'JPG' # file_format = context.scene.render.image_settings.file_format.lower() ren_path = bpy.path.abspath(bpy.context.scene.render.filepath) + ".jpg" # if len(ren_path) > 0: # if ren_path.endswith(os.path.sep): # initpath = os.path.realpath(ren_path) + os.path.sep # else: # (initpath, filename) = os.path.split(ren_path) # outpath = os.path.join(initpath, "ogl_tmp.png") # else: # self.report({'ERROR'}, "Invalid render path") # return False img = get_render_image(ren_path) if img is None: self.report({'ERROR'}, "Invalid render path:" + ren_path) return False tile_x = 240 tile_y = 216 row_num = ceil(height / tile_y) col_num = ceil(width / tile_x) cut4 = (col_num * tile_x * 4) - width * 4 totpixel4 = width * height * 4 viewport_info = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info) img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST) # 2.77 API change if bpy.app.version >= (2, 77, 0): tex = img.bindcode[0] else: tex = img.bindcode if context.scene.name in bpy.data.images: old_img = bpy.data.images[context.scene.name] old_img.user_clear() bpy.data.images.remove(old_img) img_result = bpy.data.images.new(context.scene.name, width, height) tmp_pixels = [1] * totpixel4 #---------- Loop for all tiles for row in range(0, row_num): for col in range(0, col_num): buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4) bgl.glDisable( bgl.GL_SCISSOR_TEST ) # if remove this line, get blender screenshot not image bgl.glViewport(0, 0, tile_x, tile_y) bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glLoadIdentity() # defines ortographic view for single tile x1 = tile_x * col y1 = tile_y * row bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y) # Clear bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex) # defines drawing area bgl.glBegin(bgl.GL_QUADS) bgl.glColor3f(1.0, 1.0, 1.0) bgl.glTexCoord2f(0.0, 0.0) bgl.glVertex2f(0.0, 0.0) bgl.glTexCoord2f(1.0, 0.0) bgl.glVertex2f(width, 0.0) bgl.glTexCoord2f(1.0, 1.0) bgl.glVertex2f(width, height) bgl.glTexCoord2f(0.0, 1.0) bgl.glVertex2f(0.0, height) bgl.glEnd() for obj in objlist: if obj.mv.type == 'VISDIM_A': for x in range(0, 20): if obj.layers[x] is True: if x in layers: opengl_dim = obj.mv.opengl_dim if not opengl_dim.hide: draw_dimensions(context, obj, opengl_dim, None, None) break #---------- copy pixels to temporary area bgl.glFinish() bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) # read image data for y in range(0, tile_y): # final image pixels position p1 = (y * width * 4) + (row * tile_y * width * 4) + (col * tile_x * 4) p2 = p1 + (tile_x * 4) # buffer pixels position b1 = y * width * 4 b2 = b1 + (tile_x * 4) if p1 < totpixel4: # avoid pixel row out of area if col == col_num - 1: # avoid pixel columns out of area p2 -= cut4 b2 -= cut4 tmp_pixels[p1:p2] = buffer[b1:b2] img_result.pixels = tmp_pixels[:] img.gl_free() img.user_clear() bpy.data.images.remove(img) os.remove(ren_path) bgl.glEnable(bgl.GL_SCISSOR_TEST) #---------- restore opengl defaults bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0) if img_result is not None: return img_result
def render_lens_flare(context, props: MasterProperties) -> (bgl.Buffer, int): """ Renders lens flare effect to buffer :returns buffer with effect """ max_x = props.resolution.resolution_x max_y = props.resolution.resolution_y # render kinda circles blades = props.camera.blades if blades == 0: blades = 256 shaders = Shaders() offscreen = gpu.types.GPUOffScreen(max_x, max_y) ghost_fb = gpu.types.GPUOffScreen(max_x, max_y) ghost_batch = batch_from_blades(blades, shaders.ghost) quad_batch = batch_quad(shaders.flare) draw_count = 0 noise_tex = NoiseTexture() # clear framebuffer with offscreen.bind(): # black background bgl.glClearColor(0.0, 0.0, 0.0, 1.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) bgl.glEnable(bgl.GL_BLEND) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE) for position in props.positions: pos = Vector((position.manual_x, position.manual_y)) # set position from object if position.variant == 'auto' and position.auto_object is not None: world_pos = position.auto_object.matrix_world.to_translation() pos = bpy_extras.object_utils.world_to_camera_view( context.scene, context.scene.camera, world_pos) flare_vector = pos.xy - Vector((0.5, 0.5)) flare_vector.normalize() # first render ghosts one by one for ghost in props.ghosts: # calculate position ghost_x = ((pos.x - 0.5) * 2.0) * ghost.offset ghost_y = ((pos.y - 0.5) * 2.0) * ghost.offset # add perpendicular offset ghost_x += flare_vector.y * ghost.perpendicular_offset ghost_y += -flare_vector.x * ghost.perpendicular_offset with ghost_fb.bind(): render_ghost(props, ghost, shaders.ghost, ghost_batch, flare_vector, pos) draw_count += 1 with offscreen.bind(): # now copy to final buffer bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, ghost_fb.color_texture) # disable wrapping bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_BORDER) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_BORDER) border_color = bgl.Buffer(bgl.GL_FLOAT, 4, [0.0, 0.0, 0.0, 1.0]) bgl.glTexParameterfv(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_BORDER_COLOR, border_color) bgl.glActiveTexture(bgl.GL_TEXTURE2) bgl.glBindTexture(bgl.GL_TEXTURE_2D, props.spectrum_image.bindcode) bgl.glActiveTexture(bgl.GL_TEXTURE1) bgl.glBindTexture(bgl.GL_TEXTURE_2D, noise_tex.gl_code) copy_ghost(shaders.copy, quad_batch, ghost, props, Vector((ghost_x, ghost_y))) draw_count += 1 # finally render flare on top with offscreen.bind(): bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, noise_tex.gl_code) render_flare(props, pos.xy, shaders.flare, quad_batch) draw_count += 1 with offscreen.bind(): # copy rendered image to RAM buffer = bgl.Buffer(bgl.GL_FLOAT, max_x * max_y * 4) bgl.glReadBuffer(bgl.GL_BACK) bgl.glReadPixels(0, 0, max_x, max_y, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) offscreen.free() ghost_fb.free() noise_tex.free() return buffer, draw_count
def execute(self, refholder): # pass tr = self.nodeTree.properties.TextureResolution print("begining execution " + str(tr)) # compute A' mask = np.array([[0.05, 0.2, 0.05], [0.2, -1, 0.2], [0.05, 0.2, 0.05]]) # Input data pixels A = self.inputs[0].getPixels() B = self.inputs[1].getPixels() # print(A) bgl.glGetIntegerv(bgl.GL_CURRENT_PROGRAM, self.rdData[self.name]["prev_program"]) bgl.glUseProgram(self.rdData[self.name]["program"]) #set any uniforms needed bgl.glUniform1f(self.rdData[self.name]["feed_loc"], self.inputs[2].value) bgl.glUniform1f(self.rdData[self.name]["kill_loc"], self.inputs[3].value) bgl.glUniform1f(self.rdData[self.name]["da_loc"], self.inputs[4].value) bgl.glUniform1f(self.rdData[self.name]["db_loc"], self.inputs[5].value) bgl.glUniform1f(self.rdData[self.name]["dt_loc"], self.inputs[6].value) bgl.glUniform1f(self.rdData[self.name]["step_loc"], 1 / tr) bgl.glDisable(bgl.GL_SCISSOR_TEST) bgl.glViewport(0, 0, tr, tr) bgl.glMatrixMode(bgl.GL_MODELVIEW) bgl.glPushMatrix() bgl.glLoadIdentity() bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glPushMatrix() bgl.glLoadIdentity() bgl.gluOrtho2D(0, 1, 0, 1) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glActiveTexture(bgl.GL_TEXTURE0) channels = [] if self.channels == '0': channels = [0] elif self.channels == '1': channels = [0, 1, 2] for j in channels: self.rdData[self.name]["npArray"][:, :, 0] = A[:, :, j] self.rdData[self.name]["npArray"][:, :, 1] = B[:, :, j] # Caution: Interfacing with Cython requires toList() self.rdData[self.name]["image"].pixels = self.rdData[ self.name]["npArray"].flatten() self.rdData[self.name]["image"].gl_load(0, bgl.GL_LINEAR, bgl.GL_LINEAR) bgl.glBindTexture(bgl.GL_TEXTURE_2D, self.rdData[self.name]["image"].bindcode[0]) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_REPEAT) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_REPEAT) for i in range(self.inputs[7].value): bgl.glClearDepth(1.0) bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) bgl.glBegin(bgl.GL_TRIANGLES) bgl.glColor3f(1.0, 1.0, 1.0) bgl.glTexCoord2f(0.0, 0.0) bgl.glVertex2f(-1.0, -1.0) bgl.glTexCoord2f(1.0, 0.0) bgl.glVertex2f(1.0, -1.0) bgl.glTexCoord2f(1.0, 1.0) bgl.glVertex2f(1.0, 1.0) bgl.glColor3f(1.0, 1.0, 1.0) bgl.glTexCoord2f(0.0, 0.0) bgl.glVertex2f(-1.0, -1.0) bgl.glTexCoord2f(1.0, 1.0) bgl.glVertex2f(1.0, 1.0) bgl.glTexCoord2f(0.0, 1.0) bgl.glVertex2f(-1.0, 1.0) bgl.glEnd() bgl.glCopyTexImage2D( bgl.GL_TEXTURE_2D, #target 0, #level bgl.GL_RGBA, #internalformat 0, #x 0, #y tr, tr, 0 #border ) #glFlush glFinish or none here? bgl.glFinish() bgl.glReadPixels(0, 0, tr, tr, bgl.GL_RGBA, bgl.GL_FLOAT, self.rdData[self.name]["buffer"]) self.rdData[self.name]["image"].pixels = self.rdData[ self.name]["buffer"][:] #write the image channel npImage = np.asarray(self.rdData[self.name]["image"].pixels, dtype="float") self.rdData[self.name]["npArray"] = npImage.reshape( tr, tr, self.rdData[self.name]["image"].channels) self.outputs[0].setPackedImageFromChannels( self.rdData[self.name]["npArray"][:, :, 0], j, flatten=True) self.outputs[1].setPackedImageFromChannels( self.rdData[self.name]["npArray"][:, :, 1], j, flatten=True) self.outputs[2].setPackedImageFromPixels( self.rdData[self.name]["npArray"]) self.inputs[0].setPackedImageFromChannels( self.rdData[self.name]["npArray"][:, :, 0], j, flatten=True) self.inputs[1].setPackedImageFromChannels( self.rdData[self.name]["npArray"][:, :, 1], j, flatten=True) # ================================= Test bed # self.outputs[0].getTexture().image.copy() # self.outputs[1].getTexture().image.copy() # self.outputs[2].getTexture().image.copy() # nparr = np.asarray(self.outputs[0].getTexture().image.pixels, dtype="float") # nparr = nparr.reshape(tr, tr, 4) # print(nparr) self.rdData[self.name]["image"].gl_free() #restore the state so blender wont break bgl.glEnable(bgl.GL_SCISSOR_TEST) bgl.glUseProgram(self.rdData[self.name]["prev_program"][0]) bgl.glActiveTexture(bgl.GL_TEXTURE0)
def update_all(self): self.drawn_count = 0 self._offset_cur = 1 bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT)
def render_main(self, context, animation=False): # Save old info settings = bpy.context.scene.render.image_settings depth = settings.color_depth settings.color_depth = '8' # Get object list scene = context.scene objlist = context.scene.objects # -------------------- # Get resolution # -------------------- render_scale = scene.render.resolution_percentage / 100 width = int(scene.render.resolution_x * render_scale) height = int(scene.render.resolution_y * render_scale) # -------------------------------------- # Loop to draw all lines in Offsecreen # -------------------------------------- offscreen = gpu.types.GPUOffScreen(width, height) view_matrix = Matrix([[2 / width, 0, 0, -1], [0, 2 / height, 0, -1], [0, 0, 1, 0], [0, 0, 0, 1]]) with offscreen.bind(): bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) gpu.matrix.reset() gpu.matrix.load_matrix(view_matrix) gpu.matrix.load_projection_matrix(Matrix.Identity(4)) # ----------------------------- # Loop to draw all objects # ----------------------------- for myobj in objlist: if myobj.visible_get() is True: if 'MeasureGenerator' in myobj: op = myobj.MeasureGenerator[0] draw_segments(context, myobj, op, None, None) # ----------------------------- # Loop to draw all debug # ----------------------------- if scene.measureit_debug is True: selobj = bpy.context.selected_objects for myobj in selobj: if scene.measureit_debug_objects is True: draw_object(context, myobj, None, None) elif scene.measureit_debug_object_loc is True: draw_object(context, myobj, None, None) if scene.measureit_debug_vertices is True: draw_vertices(context, myobj, None, None) elif scene.measureit_debug_vert_loc is True: draw_vertices(context, myobj, None, None) if scene.measureit_debug_edges is True: draw_edges(context, myobj, None, None) if scene.measureit_debug_faces is True or scene.measureit_debug_normals is True: draw_faces(context, myobj, None, None) # ----------------------------- # Draw a rectangle frame # ----------------------------- if scene.measureit_rf is True: rfcolor = scene.measureit_rf_color rfborder = scene.measureit_rf_border rfline = scene.measureit_rf_line imm_set_line_width(rfline) x1 = rfborder x2 = width - rfborder y1 = int(ceil(rfborder / (width / height))) y2 = height - y1 draw_rectangle((x1, y1), (x2, y2), rfcolor) buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4) bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0) bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer) offscreen.free() # ----------------------------- # Create image # ----------------------------- image_name = "measureit_output" if not image_name in bpy.data.images: bpy.data.images.new(image_name, width, height) image = bpy.data.images[image_name] image.scale(width, height) image.pixels = [v / 255 for v in buffer] # Saves image if image is not None and (scene.measureit_render is True or animation is True): ren_path = bpy.context.scene.render.filepath filename = "mit_frame" if len(ren_path) > 0: if ren_path.endswith(path.sep): initpath = path.realpath(ren_path) + path.sep else: (initpath, filename) = path.split(ren_path) ftxt = "%04d" % scene.frame_current outpath = path.realpath(path.join(initpath, filename + ftxt + ".png")) save_image(self, outpath, image) # restore default value settings.color_depth = depth
def generate_icon(name, verts=None, faces=None): pcoll = preview_collections["shape_types"] if name in pcoll: thumb = pcoll.get(name) else: thumb = pcoll.new(name) thumb.image_size = (200, 200) if verts is not None: import bgl polygon_color = bpy.context.user_preferences.themes[0].view_3d.edge_facesel edge_color = bpy.context.user_preferences.themes[0].view_3d.edge_select vertex_color = bpy.context.user_preferences.themes[0].view_3d.vertex_select clear_color = bpy.context.user_preferences.themes[0].user_interface.wcol_menu.inner viewport_info = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info) buffer = bgl.Buffer(bgl.GL_FLOAT, 200 * 200 * 4) bgl.glDisable(bgl.GL_SCISSOR_TEST) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) bgl.glEnable(bgl.GL_LINE_SMOOTH) bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glViewport(0, 0, 200, 200) bgl.glMatrixMode(bgl.GL_MODELVIEW) bgl.glPushMatrix() bgl.glLoadIdentity() bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glPushMatrix() bgl.glLoadIdentity() bgl.gluOrtho2D(0, 0, 0, 0) bgl.glLineWidth(4.0) bgl.glPointSize(10.0) bgl.glClearColor(*clear_color) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) if faces is None: bgl.glBegin(bgl.GL_POLYGON) bgl.glColor3f(*polygon_color) for vert in verts: bgl.glVertex2f(*vert) bgl.glEnd() else: bgl.glBegin(bgl.GL_TRIANGLES) bgl.glColor3f(*polygon_color) for face in faces: bgl.glVertex2f(*verts[face[0]]) bgl.glVertex2f(*verts[face[1]]) bgl.glVertex2f(*verts[face[2]]) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_LOOP) bgl.glColor3f(*edge_color) for vert in verts: bgl.glVertex2f(*vert) bgl.glEnd() bgl.glBegin(bgl.GL_POINTS) bgl.glColor3f(*vertex_color) for vert in verts: bgl.glVertex2f(*vert) bgl.glEnd() bgl.glReadPixels(0, 0, 200, 200, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) bgl.glEnable(bgl.GL_SCISSOR_TEST) bgl.glLineWidth(1.0) bgl.glPointSize(1.0) buffer = buffer[:] for idx in range(0, 200 * 200 * 4, 4): if ( buffer[idx] == clear_color[0] and buffer[idx + 1] == clear_color[1] and buffer[idx + 2] == clear_color[2] ): buffer[idx + 3] = 0.0 thumb.image_pixels_float = buffer
def render_opengl(self, context): from math import ceil layers = [] scene = context.scene for x in range(0, 20): if scene.layers[x] is True: layers.extend([x]) objlist = context.scene.objects render_scale = scene.render.resolution_percentage / 100 width = int(scene.render.resolution_x * render_scale) height = int(scene.render.resolution_y * render_scale) # I cant use file_format becuase the pdf writer needs jpg format # the file_format returns 'JPEG' not 'JPG' # file_format = context.scene.render.image_settings.file_format.lower() ren_path = bpy.path.abspath(bpy.context.scene.render.filepath) + ".jpg" # if len(ren_path) > 0: # if ren_path.endswith(os.path.sep): # initpath = os.path.realpath(ren_path) + os.path.sep # else: # (initpath, filename) = os.path.split(ren_path) # outpath = os.path.join(initpath, "ogl_tmp.png") # else: # self.report({'ERROR'}, "Invalid render path") # return False img = get_render_image(ren_path) if img is None: self.report({'ERROR'}, "Invalid render path:" + ren_path) return False tile_x = 240 tile_y = 216 row_num = ceil(height / tile_y) col_num = ceil(width / tile_x) cut4 = (col_num * tile_x * 4) - width * 4 totpixel4 = width * height * 4 viewport_info = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info) img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST) # 2.77 API change if bpy.app.version >= (2, 77, 0): tex = img.bindcode[0] else: tex = img.bindcode if context.scene.name in bpy.data.images: old_img = bpy.data.images[context.scene.name] old_img.user_clear() bpy.data.images.remove(old_img) img_result = bpy.data.images.new(context.scene.name, width, height) tmp_pixels = [1] * totpixel4 #---------- Loop for all tiles for row in range(0, row_num): for col in range(0, col_num): buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4) bgl.glDisable(bgl.GL_SCISSOR_TEST) # if remove this line, get blender screenshot not image bgl.glViewport(0, 0, tile_x, tile_y) bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glLoadIdentity() # defines ortographic view for single tile x1 = tile_x * col y1 = tile_y * row bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y) # Clear bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex) # defines drawing area bgl.glBegin(bgl.GL_QUADS) bgl.glColor3f(1.0, 1.0, 1.0) bgl.glTexCoord2f(0.0, 0.0) bgl.glVertex2f(0.0, 0.0) bgl.glTexCoord2f(1.0, 0.0) bgl.glVertex2f(width, 0.0) bgl.glTexCoord2f(1.0, 1.0) bgl.glVertex2f(width, height) bgl.glTexCoord2f(0.0, 1.0) bgl.glVertex2f(0.0, height) bgl.glEnd() for obj in objlist: if obj.mv.type == 'VISDIM_A': for x in range(0, 20): if obj.layers[x] is True: if x in layers: opengl_dim = obj.mv.opengl_dim if not opengl_dim.hide: draw_dimensions(context, obj, opengl_dim, None, None) break #---------- copy pixels to temporary area bgl.glFinish() bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) # read image data for y in range(0, tile_y): # final image pixels position p1 = (y * width * 4) + (row * tile_y * width * 4) + (col * tile_x * 4) p2 = p1 + (tile_x * 4) # buffer pixels position b1 = y * width * 4 b2 = b1 + (tile_x * 4) if p1 < totpixel4: # avoid pixel row out of area if col == col_num - 1: # avoid pixel columns out of area p2 -= cut4 b2 -= cut4 tmp_pixels[p1:p2] = buffer[b1:b2] img_result.pixels = tmp_pixels[:] img.gl_free() img.user_clear() bpy.data.images.remove(img) os.remove(ren_path) bgl.glEnable(bgl.GL_SCISSOR_TEST) #---------- restore opengl defaults bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0) if img_result is not None: return img_result
def generate_icon(name, verts=None, faces=None, coll="shape_types"): pcoll = preview_collections[coll] if name in pcoll: thumb = pcoll.get(name) else: thumb = pcoll.new(name) thumb.image_size = (200, 200) if verts is not None: import bgl polygon_color = bpy.context.user_preferences.themes[0].view_3d.edge_facesel edge_color = bpy.context.user_preferences.themes[0].view_3d.edge_select vertex_color = bpy.context.user_preferences.themes[0].view_3d.vertex_select clear_color = bpy.context.user_preferences.themes[0].user_interface.wcol_menu.inner viewport_info = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info) buffer = bgl.Buffer(bgl.GL_FLOAT, 200 * 200 * 4) bgl.glDisable(bgl.GL_SCISSOR_TEST) bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) bgl.glEnable(bgl.GL_LINE_SMOOTH) bgl.glEnable(bgl.GL_POINT_SMOOTH) bgl.glViewport(0, 0, 200, 200) bgl.glMatrixMode(bgl.GL_MODELVIEW) bgl.glPushMatrix() bgl.glLoadIdentity() bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glPushMatrix() bgl.glLoadIdentity() bgl.gluOrtho2D(0, 0, 0, 0) bgl.glLineWidth(4.0) bgl.glPointSize(10.0) bgl.glClearColor(*clear_color) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) if faces is None: bgl.glBegin(bgl.GL_POLYGON) bgl.glColor3f(*polygon_color) for vert in verts: bgl.glVertex2f(*vert) bgl.glEnd() else: bgl.glBegin(bgl.GL_TRIANGLES) bgl.glColor3f(*polygon_color) for face in faces: bgl.glVertex2f(*verts[face[0]]) bgl.glVertex2f(*verts[face[1]]) bgl.glVertex2f(*verts[face[2]]) bgl.glEnd() bgl.glBegin(bgl.GL_LINE_LOOP) bgl.glColor3f(*edge_color) for vert in verts: bgl.glVertex2f(*vert) bgl.glEnd() bgl.glBegin(bgl.GL_POINTS) bgl.glColor3f(*vertex_color) for vert in verts: bgl.glVertex2f(*vert) bgl.glEnd() bgl.glReadPixels(0, 0, 200, 200, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) bgl.glEnable(bgl.GL_SCISSOR_TEST) bgl.glLineWidth(1.0) bgl.glPointSize(1.0) buffer = buffer[:] for idx in range(0, 200 * 200 * 4, 4): if buffer[idx] == clear_color[0] and \ buffer[idx + 1] == clear_color[1] and buffer[idx + 2] == clear_color[2]: buffer[idx + 3] = 0.0 thumb.image_pixels_float = buffer
def render_main(self, context, animation=False): scene = context.scene sceneProps = scene.MeasureItArchProps sceneProps.is_render_draw = True clipdepth = context.scene.camera.data.clip_end objlist = context.view_layer.objects # Get resolution render_scale = scene.render.resolution_percentage / 100 width = int(scene.render.resolution_x * render_scale) height = int(scene.render.resolution_y * render_scale) # Draw all lines in Offsecreen renderoffscreen = gpu.types.GPUOffScreen(width, height) view_matrix_3d = scene.camera.matrix_world.inverted() projection_matrix = scene.camera.calc_matrix_camera( context.view_layer.depsgraph, x=width, y=height) set_OpenGL_Settings(True) with renderoffscreen.bind(): # Clear Depth Buffer, set Clear Depth to Cameras Clip Distance bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT) bgl.glClearDepth(clipdepth) gpu.matrix.reset() gpu.matrix.load_matrix(view_matrix_3d) gpu.matrix.load_projection_matrix(projection_matrix) # Draw Scene for the depth buffer draw_scene(self, context, projection_matrix) # Clear Color Buffer, we only need the depth info bgl.glClearColor(0, 0, 0, 0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) # ----------------------------- # Loop to draw all objects # ----------------------------- draw3d_loop(context, objlist) draw_titleblock(context) buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4) bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0) bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer) # ----------------------------- # Create image # ----------------------------- image_name = "measureit_arch_output" if image_name not in bpy.data.images: image = bpy.data.images.new(image_name, width, height) image = bpy.data.images[image_name] image.scale(width, height) image.pixels = [v / 255 for v in buffer] renderoffscreen.free() # Saves image if image is not None and animation is True: ren_path = bpy.context.scene.render.filepath filename = "mit_frame" ftxt = "%04d" % scene.frame_current outpath = (ren_path + filename + ftxt + '.png') save_image(self, outpath, image) # restore default value set_OpenGL_Settings(False) sceneProps.is_render_draw = False return True, buffer
import bpy import gpu import bgl import random from mathutils import Matrix from gpu_extras.presets import draw_circle_2d IMAGE_NAME = "Generated Image" WIDTH = 512 HEIGHT = 512 RING_AMOUNT = 10 offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT) with offscreen.bind(): bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) with gpu.matrix.push_pop(): # reset matrices -> use normalized device coordinates [-1, 1] gpu.matrix.load_matrix(Matrix.Identity(4)) gpu.matrix.load_projection_matrix(Matrix.Identity(4)) for i in range(RING_AMOUNT): draw_circle_2d((random.uniform(-1, 1), random.uniform(-1, 1)), (1, 1, 1, 1), random.uniform(0.1, 1), 20) buffer = bgl.Buffer(bgl.GL_BYTE, WIDTH * HEIGHT * 4) bgl.glReadBuffer(bgl.GL_BACK) bgl.glReadPixels(0, 0, WIDTH, HEIGHT, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
def render_main(self, context, animation=False): # Save old info scene = context.scene sceneProps= scene.MeasureItArchProps sceneProps.is_render_draw = True bgl.glEnable(bgl.GL_MULTISAMPLE) clipdepth = context.scene.camera.data.clip_end objlist = context.view_layer.objects # -------------------- # Get resolution # -------------------- render_scale = scene.render.resolution_percentage / 100 width = int(scene.render.resolution_x * render_scale) height = int(scene.render.resolution_y * render_scale) # -------------------------------------- # Draw all lines in Offsecreen # -------------------------------------- offscreen = gpu.types.GPUOffScreen(width, height) view_matrix = Matrix([ [2 / width, 0, 0, -1], [0, 2 / height, 0, -1], [0, 0, 1, 0], [0, 0, 0, 1]]) view_matrix_3d = scene.camera.matrix_world.inverted() projection_matrix = scene.camera.calc_matrix_camera(context.view_layer.depsgraph, x=width, y=height) with offscreen.bind(): # Clear Depth Buffer, set Clear Depth to Cameras Clip Distance bgl.glClear(bgl.GL_DEPTH_BUFFER_BIT) bgl.glClearDepth(clipdepth) bgl.glEnable(bgl.GL_DEPTH_TEST) bgl.glDepthFunc(bgl.GL_LEQUAL) gpu.matrix.reset() gpu.matrix.load_matrix(view_matrix_3d) gpu.matrix.load_projection_matrix(projection_matrix) draw_scene(self, context, projection_matrix) # Clear Color Keep on depth info bgl.glClearColor(0,0,0,0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) # ----------------------------- # Loop to draw all objects # ----------------------------- for myobj in objlist: if myobj.visible_get() is True: mat = myobj.matrix_world sheetGen = myobj.SheetGenerator for sheet_view in sheetGen.sheet_views: draw_sheet_views(context,myobj,sheetGen,sheet_view,mat) if 'DimensionGenerator' in myobj: measureGen = myobj.DimensionGenerator[0] if 'alignedDimensions' in measureGen: for linDim in measureGen.alignedDimensions: draw_alignedDimension(context, myobj, measureGen,linDim,mat) if 'angleDimensions' in measureGen: for dim in measureGen.angleDimensions: draw_angleDimension(context, myobj, measureGen,dim,mat) if 'axisDimensions' in measureGen: for dim in measureGen.axisDimensions: draw_axisDimension(context, myobj, measureGen,dim,mat) if 'boundsDimensions' in measureGen: for dim in measureGen.boundsDimensions: draw_boundsDimension(context, myobj, measureGen,dim,mat) if 'arcDimensions' in measureGen: for dim in measureGen.arcDimensions: draw_arcDimension(context, myobj, measureGen,dim,mat) if 'areaDimensions' in measureGen: for dim in measureGen.areaDimensions: draw_areaDimension(context, myobj, measureGen,dim,mat) if 'LineGenerator' in myobj: # Set 3D Projection Martix gpu.matrix.reset() gpu.matrix.load_matrix(view_matrix_3d) gpu.matrix.load_projection_matrix(projection_matrix) # Draw Line Groups op = myobj.LineGenerator[0] draw_line_group(context, myobj, op, mat) if 'AnnotationGenerator' in myobj: # Set 3D Projection Martix gpu.matrix.reset() gpu.matrix.load_matrix(view_matrix_3d) gpu.matrix.load_projection_matrix(projection_matrix) # Draw Line Groups op = myobj.AnnotationGenerator[0] draw_annotation(context, myobj, op, mat) # Draw Instance deps = bpy.context.view_layer.depsgraph for obj_int in deps.object_instances: if obj_int.is_instance: myobj = obj_int.object mat = obj_int.matrix_world if 'LineGenerator' in myobj: lineGen = myobj.LineGenerator[0] draw_line_group(context,myobj,lineGen,mat) if sceneProps.instance_dims: if 'AnnotationGenerator' in myobj: annotationGen = myobj.AnnotationGenerator[0] draw_annotation(context,myobj,annotationGen,mat) if 'DimensionGenerator' in myobj: DimGen = myobj.DimensionGenerator[0] for alignedDim in DimGen.alignedDimensions: draw_alignedDimension(context, myobj, DimGen, alignedDim,mat) for angleDim in DimGen.angleDimensions: draw_angleDimension(context, myobj, DimGen, angleDim,mat) for axisDim in DimGen.axisDimensions: draw_axisDimension(context,myobj,DimGen,axisDim,mat) buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4) bgl.glReadBuffer(bgl.GL_COLOR_ATTACHMENT0) bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer) offscreen.free() # ----------------------------- # Create image # ----------------------------- image_name = "measureit_arch_output" if image_name not in bpy.data.images: bpy.data.images.new(image_name, width, height) image = bpy.data.images[image_name] image.scale(width, height) image.pixels = [v / 255 for v in buffer] # Saves image if image is not None and (scene.measureit_arch_render is True or animation is True): ren_path = bpy.context.scene.render.filepath filename = "mit_frame" ftxt = "%04d" % scene.frame_current outpath = (ren_path + filename + ftxt + '.png') save_image(self, outpath, image) # restore default value sceneProps.is_render_draw = False return True, buffer
def glsl_draw(self): if GlslDrawObj.myinstance is None and GlslDrawObj.draw_func is None: glsl_draw_obj = GlslDrawObj() glsl_draw_obj.build_scene() else: glsl_draw_obj = GlslDrawObj.myinstance model_offset = Matrix.Translation((glsl_draw_obj.draw_x_offset, 0, 0)) light_pos = [ i + n for i, n in zip(glsl_draw_obj.light.location, [-glsl_draw_obj.draw_x_offset, 0, 0]) ] batches = glsl_draw_obj.batches depth_shader = glsl_draw_obj.depth_shader toon_shader = glsl_draw_obj.toon_shader offscreen = glsl_draw_obj.offscreen # need bone etc changed only update depth_matrix = None light = glsl_draw_obj.light light_lookat = light.rotation_euler.to_quaternion() @ Vector( (0, 0, -1)) # TODO このへん tar = light_lookat.normalized() up = light.rotation_euler.to_quaternion() @ Vector((0, 1, 0)) tmp_bound_len = Vector(glsl_draw_obj.bounding_center).length camera_bias = 0.2 loc = Vector([ glsl_draw_obj.bounding_center[i] + tar[i] * (tmp_bound_len + camera_bias) for i in range(3) ]) loc = model_offset @ loc v_matrix = lookat_cross(loc, tar, up) const_proj = 2 * max(glsl_draw_obj.bounding_size) / 2 p_matrix = ortho_proj_mat(-const_proj, const_proj, -const_proj, const_proj, -const_proj, const_proj) depth_matrix = v_matrix @ p_matrix # reuse in main shader depth_matrix.transpose() # region shader depth path with offscreen.bind(): bgl.glClearColor(10, 10, 10, 1) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) for bat in batches: mat = bat[0] mat.update() depth_bat = bat[2] depth_shader.bind() bgl.glEnable(bgl.GL_BLEND) if mat.alpha_method == "TRANSPARENT": bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) bgl.glDepthMask(bgl.GL_TRUE) bgl.glEnable(bgl.GL_DEPTH_TEST) elif mat.alpha_method == "OPAQUE": bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ZERO) bgl.glDepthMask(bgl.GL_TRUE) bgl.glEnable(bgl.GL_DEPTH_TEST) elif mat.alpha_method == "CLIP": bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ZERO) bgl.glDepthMask(bgl.GL_TRUE) bgl.glEnable(bgl.GL_DEPTH_TEST) if mat.cull_mode == "BACK": bgl.glEnable(bgl.GL_CULL_FACE) bgl.glCullFace(bgl.GL_BACK) else: bgl.glDisable(bgl.GL_CULL_FACE) bgl.glEnable(bgl.GL_CULL_FACE) # そも輪郭線がの影は落ちる? bgl.glCullFace(bgl.GL_BACK) depth_shader.uniform_float("obj_matrix", model_offset) # obj.matrix_world) depth_shader.uniform_float("depthMVP", depth_matrix) depth_bat.draw(depth_shader) # endregion shader depth path # region shader main vp_mat = bpy.context.region_data.perspective_matrix projection_mat = bpy.context.region_data.window_matrix view_dir = bpy.context.region_data.view_matrix[2][:3] view_up = bpy.context.region_data.view_matrix[1][:3] normal_world_to_view_matrix = ( bpy.context.region_data.view_matrix.inverted_safe().transposed()) aspect = bpy.context.area.width / bpy.context.area.height for is_outline in [0, 1]: for bat in batches: toon_bat = bat[1] toon_shader.bind() mat = bat[0] if is_outline == 1 and mat.float_dic["OutlineWidthMode"] == 0: continue # mat.update() #already in depth path bgl.glEnable(bgl.GL_BLEND) bgl.glDepthMask(bgl.GL_TRUE) bgl.glEnable(bgl.GL_DEPTH_TEST) if mat.alpha_method == "TRANSPARENT": bgl.glBlendFunc(bgl.GL_SRC_ALPHA, bgl.GL_ONE_MINUS_SRC_ALPHA) elif mat.alpha_method == "OPAQUE": bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ZERO) elif mat.alpha_method == "CLIP": bgl.glBlendFunc(bgl.GL_ONE, bgl.GL_ZERO) if is_outline == 0: if mat.cull_mode == "BACK": bgl.glEnable(bgl.GL_CULL_FACE) bgl.glCullFace(bgl.GL_BACK) else: bgl.glDisable(bgl.GL_CULL_FACE) else: bgl.glEnable(bgl.GL_CULL_FACE) bgl.glCullFace(bgl.GL_BACK) toon_shader.uniform_float("obj_matrix", model_offset) # obj.matrix_world) toon_shader.uniform_float("projectionMatrix", projection_mat) toon_shader.uniform_float("viewProjectionMatrix", vp_mat) toon_shader.uniform_float("viewDirection", view_dir) toon_shader.uniform_float("viewUpDirection", view_up) toon_shader.uniform_float("normalWorldToViewMatrix", normal_world_to_view_matrix) toon_shader.uniform_float("depthMVP", depth_matrix) toon_shader.uniform_float("lightpos", light_pos) toon_shader.uniform_float("aspect", aspect) toon_shader.uniform_float("is_outline", is_outline) toon_shader.uniform_float("isDebug", 0.0) toon_shader.uniform_float( "is_cutout", 1.0 if mat.alpha_method == "CLIP" else 0.0) float_keys = [ "CutoffRate", "BumpScale", "ReceiveShadowRate", "ShadeShift", "ShadeToony", "RimLightingMix", "RimFresnelPower", "RimLift", "ShadingGradeRate", "LightColorAttenuation", "IndirectLightIntensity", "OutlineWidth", "OutlineScaleMaxDistance", "OutlineLightingMix", "UV_Scroll_X", "UV_Scroll_Y", "UV_Scroll_Rotation", "OutlineWidthMode", "OutlineColorMode", ] for k in float_keys: toon_shader.uniform_float(k, mat.float_dic[k]) for k, v in mat.vector_dic.items(): toon_shader.uniform_float(k, v) bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) # TODO bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) toon_shader.uniform_int("depth_image", 0) for i, k in enumerate(mat.texture_dic.keys()): bgl.glActiveTexture(bgl.GL_TEXTURE1 + i) texture = mat.texture_dic[k] bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture.bindcode) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) # TODO bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) toon_shader.uniform_int(k, 1 + i) toon_bat.draw(toon_shader)
def render_main(self, context, animation=False): # noinspection PyBroadException,PyBroadException try: # Get visible layers layers = [] scene = context.scene for x in range(0, 20): if scene.layers[x] is True: layers.extend([x]) # Get object list objlist = context.scene.objects # -------------------- # Get resolution # -------------------- scene = bpy.context.scene render_scale = scene.render.resolution_percentage / 100 width = int(scene.render.resolution_x * render_scale) height = int(scene.render.resolution_y * render_scale) # --------------------------------------- # Get output path # --------------------------------------- ren_path = bpy.context.scene.render.filepath if len(ren_path) > 0: if ren_path.endswith(os.path.sep): initpath = os.path.realpath(ren_path) + os.path.sep else: (initpath, filename) = os.path.split(ren_path) outpath = os.path.join(initpath, "measureit_tmp_render.png") else: self.report({'ERROR'}, "MeasureIt: Unable to save temporary render image. Define a valid render path") return False # Get Render Image img = get_render_image(outpath) if img is None: self.report({'ERROR'}, "MeasureIt: Unable to save temporary render image. Define a valid render path") return False # ----------------------------- # Calculate rows and columns # ----------------------------- tile_x = 240 tile_y = 216 row_num = ceil(height / tile_y) col_num = ceil(width / tile_x) print("MeasureIt: Image divided in " + str(row_num) + "x" + str(col_num) + " tiles") # pixels out of visible area cut4 = (col_num * tile_x * 4) - width * 4 # pixels aout of drawing area totpixel4 = width * height * 4 # total pixels RGBA viewport_info = bgl.Buffer(bgl.GL_INT, 4) bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport_info) # Load image on memory img.gl_load(0, bgl.GL_NEAREST, bgl.GL_NEAREST) tex = img.bindcode # -------------------------------------------- # Create output image (to apply texture) # -------------------------------------------- if "measureit_output" in bpy.data.images: out_img = bpy.data.images["measureit_output"] if out_img is not None: out_img.user_clear() bpy.data.images.remove(out_img) out = bpy.data.images.new("measureit_output", width, height) tmp_pixels = [1] * totpixel4 # -------------------------------- # Loop for all tiles # -------------------------------- for row in range(0, row_num): for col in range(0, col_num): buffer = bgl.Buffer(bgl.GL_FLOAT, width * height * 4) bgl.glDisable(bgl.GL_SCISSOR_TEST) # if remove this line, get blender screenshot not image bgl.glViewport(0, 0, tile_x, tile_y) bgl.glMatrixMode(bgl.GL_PROJECTION) bgl.glLoadIdentity() # defines ortographic view for single tile x1 = tile_x * col y1 = tile_y * row bgl.gluOrtho2D(x1, x1 + tile_x, y1, y1 + tile_y) # Clear bgl.glClearColor(0.0, 0.0, 0.0, 0.0) bgl.glClear(bgl.GL_COLOR_BUFFER_BIT | bgl.GL_DEPTH_BUFFER_BIT) bgl.glEnable(bgl.GL_TEXTURE_2D) bgl.glBindTexture(bgl.GL_TEXTURE_2D, tex) # defines drawing area bgl.glBegin(bgl.GL_QUADS) bgl.glColor3f(1.0, 1.0, 1.0) bgl.glTexCoord2f(0.0, 0.0) bgl.glVertex2f(0.0, 0.0) bgl.glTexCoord2f(1.0, 0.0) bgl.glVertex2f(width, 0.0) bgl.glTexCoord2f(1.0, 1.0) bgl.glVertex2f(width, height) bgl.glTexCoord2f(0.0, 1.0) bgl.glVertex2f(0.0, height) bgl.glEnd() # ----------------------------- # Loop to draw all lines # ----------------------------- for myobj in objlist: if myobj.hide is False: if 'MeasureGenerator' in myobj: # verify visible layer for x in range(0, 20): if myobj.layers[x] is True: if x in layers: op = myobj.MeasureGenerator[0] draw_segments(context, myobj, op, None, None) break if scene.measureit_rf is True: bgl.glColor3f(1.0, 1.0, 1.0) rfcolor = scene.measureit_rf_color rfborder = scene.measureit_rf_border rfline = scene.measureit_rf_line bgl.glLineWidth(rfline) bgl.glColor4f(rfcolor[0], rfcolor[1], rfcolor[2], rfcolor[3]) x1 = rfborder x2 = width - rfborder y1 = int(math.ceil(rfborder / (width / height))) y2 = height - y1 draw_rectangle((x1, y1), (x2, y2)) # -------------------------------- # copy pixels to temporary area # -------------------------------- bgl.glFinish() bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_FLOAT, buffer) # read image data for y in range(0, tile_y): # final image pixels position p1 = (y * width * 4) + (row * tile_y * width * 4) + (col * tile_x * 4) p2 = p1 + (tile_x * 4) # buffer pixels position b1 = y * width * 4 b2 = b1 + (tile_x * 4) if p1 < totpixel4: # avoid pixel row out of area if col == col_num - 1: # avoid pixel columns out of area p2 -= cut4 b2 -= cut4 tmp_pixels[p1:p2] = buffer[b1:b2] # ----------------------- # Copy temporary to final # ----------------------- out.pixels = tmp_pixels[:] # Assign image data img.gl_free() # free opengl image memory # delete image img.user_clear() bpy.data.images.remove(img) # remove temp file os.remove(outpath) # reset bgl.glEnable(bgl.GL_SCISSOR_TEST) # ----------------------- # restore opengl defaults # ----------------------- bgl.glLineWidth(1) bgl.glDisable(bgl.GL_BLEND) bgl.glColor4f(0.0, 0.0, 0.0, 1.0) # Saves image if out is not None and (scene.measureit_render is True or animation is True): ren_path = bpy.context.scene.render.filepath filename = "mit_frame" if len(ren_path) > 0: if ren_path.endswith(os.path.sep): initpath = os.path.realpath(ren_path) + os.path.sep else: (initpath, filename) = os.path.split(ren_path) ftxt = "%04d" % scene.frame_current outpath = os.path.join(initpath, filename + ftxt + ".png") save_image(self, outpath, out) return True except: print("Unexpected error:" + str(sys.exc_info())) self.report({'ERROR'}, "MeasureIt: Unable to create render image") return False