Created
November 20, 2023 09:50
-
-
Save emailandxu/f30849c40d5fe0a70a73e16ee27ada17 to your computer and use it in GitHub Desktop.
Revisions
-
emailandxu created this gist
Nov 20, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,111 @@ #from this: https://blender.stackexchange.com/a/231881 import bpy import gpu # Draw function which copies data from the 3D View def draw(self, context): if self.modal_redraw == True: # get currently bound framebuffer self.framebuffer = gpu.state.active_framebuffer_get() # get information on current viewport self.viewport_info = gpu.state.viewport_get() self.width = self.viewport_info[2] self.height = self.viewport_info[3] # Write copied data to image ###################################################### # resize image obect to fit the current 3D View size self.framebuffer_image.scale(self.width, self.height) # obtain pixels from the framebuffer self.pixelBuffer = self.framebuffer.read_color(0, 0, self.width, self.height, 4, 0, 'FLOAT') # write all pixels into the blender image self.pixelBuffer.dimensions = self.width * self.height * 4 self.framebuffer_image.pixels.foreach_set(self.pixelBuffer) # reset draw variable: # This is here to prevent excessive redrawing self.modal_redraw = False # Modal operator for controlled redrawing of the image object # NOTE: This code is only for a more conveniant testing of the draw function # If you want to stop the test, press 'ESC' class ModalFramebufferCopy(bpy.types.Operator): bl_idname = "view3d.modal_framebuffer_copy" bl_label = "Draw 3D View Framebuffer" def __init__(self): print("Start example code") # init variables self.width = 32 self.height = 32 self.modal_redraw = False self.image_name = "color_buffer_copy" self.framebuffer = None self.viewport_info = None self.pixelBuffer = None # create or update image object to which the framebuffer # data will be copied if not self.image_name in bpy.data.images: self.framebuffer_image = bpy.data.images.new(self.image_name , 32, 32, float_buffer=True) else: self.framebuffer_image = bpy.data.images[self.image_name ] # def __del__(self): print("End example code") # modal operator for controlled redraw of the image def modal(self, context, event): # stop the execution of this example code if 'ESC' is pressed if event.type in {'ESC'}: bpy.types.SpaceView3D.draw_handler_remove(self._handle_3d, 'WINDOW') print("Removing draw handler") return {'CANCELLED'} else: # set draw variable to update: # This is here to prevent excessive redrawing self.modal_redraw = True return {'PASS_THROUGH'} #return {'RUNNING_MODAL'} def invoke(self, context, event): print("Invoking modal operator") # Add the region OpenGL drawing callback # draw in view space with 'POST_VIEW' and 'PRE_VIEW' self._handle_3d = bpy.types.SpaceView3D.draw_handler_add(draw, (self, context), 'WINDOW', 'PRE_VIEW') # this draws the viewport objects alone (without grid) # self._handle_3d = bpy.types.SpaceView3D.draw_handler_add(draw, (self, context), 'WINDOW', 'POST_VIEW') # this draws the grid alone (without objects) context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} def register(): bpy.utils.register_class(ModalFramebufferCopy) def unregister(): bpy.utils.unregister_class(ModalFramebufferCopy) if __name__ == "__main__": register() # Invoke modal operator for the example code bpy.ops.view3d.modal_framebuffer_copy('INVOKE_DEFAULT')