Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'doc/python_api/examples/gpu.offscreen.1.py')
-rw-r--r--doc/python_api/examples/gpu.offscreen.1.py192
1 files changed, 192 insertions, 0 deletions
diff --git a/doc/python_api/examples/gpu.offscreen.1.py b/doc/python_api/examples/gpu.offscreen.1.py
new file mode 100644
index 00000000000..06f0d915361
--- /dev/null
+++ b/doc/python_api/examples/gpu.offscreen.1.py
@@ -0,0 +1,192 @@
+# Draws an off-screen buffer and display it in the corner of the view.
+import bpy
+from bgl import *
+
+
+class OffScreenDraw(bpy.types.Operator):
+ bl_idname = "view3d.offscreen_draw"
+ bl_label = "View3D Offscreen Draw"
+
+ _handle_calc = None
+ _handle_draw = None
+ is_enabled = False
+
+ # manage draw handler
+ @staticmethod
+ def draw_callback_px(self, context):
+ scene = context.scene
+ aspect_ratio = scene.render.resolution_x / scene.render.resolution_y
+
+ self._update_offscreen(context, self._offscreen)
+ self._opengl_draw(context, self._texture, aspect_ratio, 0.2)
+
+ @staticmethod
+ def handle_add(self, context):
+ OffScreenDraw._handle_draw = bpy.types.SpaceView3D.draw_handler_add(
+ self.draw_callback_px, (self, context),
+ 'WINDOW', 'POST_PIXEL',
+ )
+
+ @staticmethod
+ def handle_remove():
+ if OffScreenDraw._handle_draw is not None:
+ bpy.types.SpaceView3D.draw_handler_remove(OffScreenDraw._handle_draw, 'WINDOW')
+
+ OffScreenDraw._handle_draw = None
+
+ # off-screen buffer
+ @staticmethod
+ def _setup_offscreen(context):
+ import gpu
+ scene = context.scene
+ aspect_ratio = scene.render.resolution_x / scene.render.resolution_y
+
+ try:
+ offscreen = gpu.offscreen.new(512, int(512 / aspect_ratio))
+ except Exception as e:
+ print(e)
+ offscreen = None
+
+ return offscreen
+
+ @staticmethod
+ def _update_offscreen(context, offscreen):
+ scene = context.scene
+ render = scene.render
+ camera = scene.camera
+
+ modelview_matrix = camera.matrix_world.inverted()
+ projection_matrix = camera.calc_matrix_camera(
+ render.resolution_x,
+ render.resolution_y,
+ render.pixel_aspect_x,
+ render.pixel_aspect_y,
+ )
+
+
+ offscreen.draw_view3d(
+ scene,
+ context.space_data,
+ context.region,
+ projection_matrix,
+ modelview_matrix,
+ )
+
+ @staticmethod
+ def _opengl_draw(context, texture, aspect_ratio, scale):
+ """
+ OpenGL code to draw a rectangle in the viewport
+ """
+
+ glDisable(GL_DEPTH_TEST)
+
+ # view setup
+ glMatrixMode(GL_PROJECTION)
+ glPushMatrix()
+ glLoadIdentity()
+
+ glMatrixMode(GL_MODELVIEW)
+ glPushMatrix()
+ glLoadIdentity()
+
+ glOrtho(-1, 1, -1, 1, -15, 15)
+ gluLookAt(0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
+
+ act_tex = Buffer(GL_INT, 1)
+ glGetIntegerv(GL_TEXTURE_2D, act_tex)
+
+ viewport = Buffer(GL_INT, 4)
+ glGetIntegerv(GL_VIEWPORT, viewport)
+
+ width = int(scale * viewport[2])
+ height = int(width / aspect_ratio)
+
+ glViewport(viewport[0], viewport[1], width, height)
+ glScissor(viewport[0], viewport[1], width, height)
+
+ # draw routine
+ glEnable(GL_TEXTURE_2D)
+ glActiveTexture(GL_TEXTURE0)
+
+ glBindTexture(GL_TEXTURE_2D, texture)
+
+ texco = [(1, 1), (0, 1), (0, 0), (1, 0)]
+ verco = [(1.0, 1.0), (-1.0, 1.0), (-1.0, -1.0), (1.0, -1.0)]
+
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
+
+ glColor4f(1.0, 1.0, 1.0, 1.0)
+
+ glBegin(GL_QUADS)
+ for i in range(4):
+ glTexCoord3f(texco[i][0], texco[i][1], 0.0)
+ glVertex2f(verco[i][0], verco[i][1])
+ glEnd()
+
+ # restoring settings
+ glBindTexture(GL_TEXTURE_2D, act_tex[0])
+
+ glDisable(GL_TEXTURE_2D)
+
+ # reset view
+ glMatrixMode(GL_PROJECTION)
+ glPopMatrix()
+
+ glMatrixMode(GL_MODELVIEW)
+ glPopMatrix()
+
+ glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
+ glScissor(viewport[0], viewport[1], viewport[2], viewport[3])
+
+ # operator functions
+ @classmethod
+ def poll(cls, context):
+ return context.area.type == 'VIEW_3D'
+
+ def modal(self, context, event):
+ if context.area:
+ context.area.tag_redraw()
+
+ return {'PASS_THROUGH'}
+
+ def invoke(self, context, event):
+ if OffScreenDraw.is_enabled:
+ self.cancel(context)
+
+ return {'FINISHED'}
+
+ else:
+ self._offscreen = OffScreenDraw._setup_offscreen(context)
+ if self._offscreen:
+ self._texture = self._offscreen.color_texture
+ else:
+ self.report({'ERROR'}, "Error initializing offscreen buffer. More details in the console")
+ return {'CANCELLED'}
+
+ OffScreenDraw.handle_add(self, context)
+ OffScreenDraw.is_enabled = True
+
+ if context.area:
+ context.area.tag_redraw()
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+ def cancel(self, context):
+ OffScreenDraw.handle_remove()
+ OffScreenDraw.is_enabled = False
+
+ if context.area:
+ context.area.tag_redraw()
+
+
+def register():
+ bpy.utils.register_class(OffScreenDraw)
+
+
+def unregister():
+ bpy.utils.unregister_class(OffScreenDraw)
+
+
+if __name__ == "__main__":
+ register()