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
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/python_api/examples/gpu.types.GPUOffScreen.py207
1 files changed, 139 insertions, 68 deletions
diff --git a/doc/python_api/examples/gpu.types.GPUOffScreen.py b/doc/python_api/examples/gpu.types.GPUOffScreen.py
index a1b38837278..b7f11b94a11 100644
--- a/doc/python_api/examples/gpu.types.GPUOffScreen.py
+++ b/doc/python_api/examples/gpu.types.GPUOffScreen.py
@@ -1,16 +1,58 @@
# Draws an off-screen buffer and display it in the corner of the view.
import bpy
-from bgl import *
-
-
-class OffScreenDraw(bpy.types.Operator):
+import bgl
+import gpu
+import numpy as np
+
+g_imageVertSrc = '''
+in vec2 texCoord;
+in vec2 pos;
+
+out vec2 texCoord_interp;
+
+void main()
+{
+ gl_Position = vec4(pos.xy, 0.0f, 1.0);
+ gl_Position.z = 1.0f;
+ texCoord_interp = texCoord;
+}
+'''
+
+g_imageFragSrc = '''
+in vec2 texCoord_interp;
+out vec4 fragColor;
+
+uniform sampler2D image;
+
+void main()
+{
+ fragColor = texture(image, texCoord_interp);
+}
+'''
+
+g_plane_vertices = np.array([
+ ([-1.0, -1.0], [0.0, 0.0]),
+ ([1.0, -1.0], [1.0, 0.0]),
+ ([1.0, 1.0], [1.0, 1.0]),
+ ([1.0, 1.0], [1.0, 1.0]),
+ ([-1.0, 1.0], [0.0, 1.0]),
+ ([-1.0, -1.0], [0.0, 0.0]),
+], [('pos', 'f4', 2), ('uv', 'f4', 2)])
+
+
+class VIEW3D_OT_draw_offscreen(bpy.types.Operator):
bl_idname = "view3d.offscreen_draw"
- bl_label = "View3D Offscreen Draw"
+ bl_label = "Viewport Offscreen Draw"
_handle_calc = None
_handle_draw = None
is_enabled = False
+ global_shader = None
+ batch_plane = None
+ uniform_image = -1
+ shader = None
+
# manage draw handler
@staticmethod
def draw_callback_px(self, context):
@@ -22,22 +64,21 @@ class OffScreenDraw(bpy.types.Operator):
@staticmethod
def handle_add(self, context):
- OffScreenDraw._handle_draw = bpy.types.SpaceView3D.draw_handler_add(
+ VIEW3D_OT_draw_offscreen._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')
+ if VIEW3D_OT_draw_offscreen._handle_draw is not None:
+ bpy.types.SpaceView3D.draw_handler_remove(VIEW3D_OT_draw_offscreen._handle_draw, 'WINDOW')
- OffScreenDraw._handle_draw = None
+ VIEW3D_OT_draw_offscreen._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
@@ -58,86 +99,96 @@ class OffScreenDraw(bpy.types.Operator):
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,
+ context.depsgraph,
+ x=render.resolution_x,
+ y=render.resolution_y,
+ scale_x=render.pixel_aspect_x,
+ scale_y=render.pixel_aspect_y,
)
offscreen.draw_view3d(
scene,
- render_layer,
+ view_layer,
context.space_data,
context.region,
projection_matrix,
modelview_matrix,
)
- @staticmethod
- def _opengl_draw(context, texture, aspect_ratio, scale):
+ def _opengl_draw(self, 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()
+ bgl.glDisable(bgl.GL_DEPTH_TEST)
- glMatrixMode(GL_MODELVIEW)
- glPushMatrix()
- glLoadIdentity()
+ viewport = bgl.Buffer(bgl.GL_INT, 4)
+ bgl.glGetIntegerv(bgl.GL_VIEWPORT, viewport)
- 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)
+ active_texture = bgl.Buffer(bgl.GL_INT, 1)
+ bgl.glGetIntegerv(bgl.GL_TEXTURE_2D, active_texture)
width = int(scale * viewport[2])
height = int(width / aspect_ratio)
- glViewport(viewport[0], viewport[1], width, height)
- glScissor(viewport[0], viewport[1], width, height)
+ bgl.glViewport(viewport[0], viewport[1], width, height)
+ bgl.glScissor(viewport[0], viewport[1], width, height)
# draw routine
- glEnable(GL_TEXTURE_2D)
- glActiveTexture(GL_TEXTURE0)
+ batch_plane = self.get_batch_plane()
- glBindTexture(GL_TEXTURE_2D, texture)
+ shader = VIEW3D_OT_draw_offscreen.shader
+ # bind it so we can pass the new uniform values
+ shader.bind()
- 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)]
+ bgl.glEnable(bgl.GL_TEXTURE_2D)
+ bgl.glActiveTexture(bgl.GL_TEXTURE0)
+ bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture)
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
+ shader.uniform_int(VIEW3D_OT_draw_offscreen.uniform_image, 0)
+ batch_plane.draw()
- glColor4f(1.0, 1.0, 1.0, 1.0)
+ # restoring settings
+ bgl.glBindTexture(bgl.GL_TEXTURE_2D, active_texture[0])
+ bgl.glDisable(bgl.GL_TEXTURE_2D)
- 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()
+ # reset view
+ bgl.glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
+ bgl.glScissor(viewport[0], viewport[1], viewport[2], viewport[3])
- # restoring settings
- glBindTexture(GL_TEXTURE_2D, act_tex[0])
+ def get_batch_plane(self):
+ if self.batch_plane is None:
+ global g_plane_vertices
- glDisable(GL_TEXTURE_2D)
+ format = gpu.types.GPUVertFormat()
+ pos_id = format.attr_add(
+ id="pos",
+ comp_type="F32",
+ len=2,
+ fetch_mode="FLOAT")
- # reset view
- glMatrixMode(GL_PROJECTION)
- glPopMatrix()
+ uv_id = format.attr_add(
+ id="texCoord",
+ comp_type="F32",
+ len=2,
+ fetch_mode="FLOAT")
- glMatrixMode(GL_MODELVIEW)
- glPopMatrix()
+ vbo = gpu.types.GPUVertBuf(
+ len=len(g_plane_vertices),
+ format=format)
- glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
- glScissor(viewport[0], viewport[1], viewport[2], viewport[3])
+ vbo.fill(id=pos_id, data=g_plane_vertices["pos"])
+ vbo.fill(id=uv_id, data=g_plane_vertices["uv"])
+
+ batch_plane = gpu.types.GPUBatch(type="TRIS", buf=vbo)
+ shader = self.global_shader
+
+ VIEW3D_OT_draw_offscreen.shader = shader
+ VIEW3D_OT_draw_offscreen.uniform_image = shader.uniform_from_name("image")
+
+ batch_plane.program_set(shader)
+ VIEW3D_OT_draw_offscreen.batch_plane = batch_plane
+ return VIEW3D_OT_draw_offscreen.batch_plane
# operator functions
@classmethod
@@ -148,24 +199,26 @@ class OffScreenDraw(bpy.types.Operator):
if context.area:
context.area.tag_redraw()
+ if event.type in {'RIGHTMOUSE', 'ESC'}:
+ self.cancel(context)
+ return {'CANCELLED'}
+
return {'PASS_THROUGH'}
def invoke(self, context, event):
- if OffScreenDraw.is_enabled:
+ if VIEW3D_OT_draw_offscreen.is_enabled:
self.cancel(context)
-
return {'FINISHED'}
-
else:
- self._offscreen = OffScreenDraw._setup_offscreen(context)
+ self._offscreen = VIEW3D_OT_draw_offscreen._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
+ VIEW3D_OT_draw_offscreen.handle_add(self, context)
+ VIEW3D_OT_draw_offscreen.is_enabled = True
if context.area:
context.area.tag_redraw()
@@ -174,20 +227,38 @@ class OffScreenDraw(bpy.types.Operator):
return {'RUNNING_MODAL'}
def cancel(self, context):
- OffScreenDraw.handle_remove()
- OffScreenDraw.is_enabled = False
+ VIEW3D_OT_draw_offscreen.handle_remove()
+ VIEW3D_OT_draw_offscreen.is_enabled = False
+
+ if VIEW3D_OT_draw_offscreen.batch_plane is not None:
+ del VIEW3D_OT_draw_offscreen.batch_plane
+ VIEW3D_OT_draw_offscreen.batch_plane = None
+
+ VIEW3D_OT_draw_offscreen.shader = None
if context.area:
context.area.tag_redraw()
def register():
- bpy.utils.register_class(OffScreenDraw)
+ if hasattr(bpy.types, "VIEW3D_OT_draw_offscreen"):
+ del VIEW3D_OT_draw_offscreen.global_shader
+
+ shader = gpu.types.GPUShader(g_imageVertSrc, g_imageFragSrc)
+ VIEW3D_OT_draw_offscreen.global_shader = shader
+
+ bpy.utils.register_class(VIEW3D_OT_draw_offscreen)
def unregister():
- bpy.utils.unregister_class(OffScreenDraw)
+ bpy.utils.unregister_class(VIEW3D_OT_draw_offscreen)
+ VIEW3D_OT_draw_offscreen.global_shader = None
if __name__ == "__main__":
+ try:
+ unregister()
+ except RuntimeError:
+ pass
+
register()