Py API Docs: Remove older GPUOffScreen example
I think this example does not belong into the api docs and certainly not in the place where it was until now. Maybe this can become a template in Blender but personally I don't see much value in it as an "official example" because it is hard to see what is going on exactly. There are a few other examples that show how to use the GPUOffScreen object now.
This commit is contained in:
@@ -1,267 +0,0 @@
|
||||
# Draws an off-screen buffer and display it in the corner of the view.
|
||||
import bpy
|
||||
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 = "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):
|
||||
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):
|
||||
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 VIEW3D_OT_draw_offscreen._handle_draw is not None:
|
||||
bpy.types.SpaceView3D.draw_handler_remove(VIEW3D_OT_draw_offscreen._handle_draw, 'WINDOW')
|
||||
|
||||
VIEW3D_OT_draw_offscreen._handle_draw = None
|
||||
|
||||
# off-screen buffer
|
||||
@staticmethod
|
||||
def _setup_offscreen(context):
|
||||
scene = context.scene
|
||||
aspect_ratio = scene.render.resolution_x / scene.render.resolution_y
|
||||
|
||||
try:
|
||||
offscreen = gpu.types.GPUOffScreen(512, int(512 / aspect_ratio))
|
||||
except Exception as ex:
|
||||
print(ex)
|
||||
offscreen = None
|
||||
|
||||
return offscreen
|
||||
|
||||
@staticmethod
|
||||
def _update_offscreen(context, offscreen):
|
||||
scene = context.scene
|
||||
view_layer = context.view_layer
|
||||
render = scene.render
|
||||
camera = scene.camera
|
||||
|
||||
view_matrix = camera.matrix_world.inverted()
|
||||
projection_matrix = camera.calc_matrix_camera(
|
||||
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,
|
||||
view_layer,
|
||||
context.space_data,
|
||||
context.region,
|
||||
projection_matrix,
|
||||
view_matrix,
|
||||
)
|
||||
|
||||
def _opengl_draw(self, context, texture, aspect_ratio, scale):
|
||||
"""
|
||||
OpenGL code to draw a rectangle in the viewport
|
||||
"""
|
||||
# view setup
|
||||
bgl.glDisable(bgl.GL_DEPTH_TEST)
|
||||
|
||||
viewport = bgl.Buffer(bgl.GL_INT, 4)
|
||||
bgl.glGetIntegerv(bgl.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)
|
||||
|
||||
bgl.glViewport(viewport[0], viewport[1], width, height)
|
||||
bgl.glScissor(viewport[0], viewport[1], width, height)
|
||||
|
||||
# draw routine
|
||||
batch_plane = self.get_batch_plane()
|
||||
|
||||
shader = VIEW3D_OT_draw_offscreen.shader
|
||||
# bind it so we can pass the new uniform values
|
||||
shader.bind()
|
||||
|
||||
bgl.glEnable(bgl.GL_TEXTURE_2D)
|
||||
bgl.glActiveTexture(bgl.GL_TEXTURE0)
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture)
|
||||
|
||||
# # TODO, support passing ints
|
||||
# shader.uniform_int(VIEW3D_OT_draw_offscreen.uniform_image, 0)
|
||||
shader.uniform_int("image", 0)
|
||||
batch_plane.draw()
|
||||
|
||||
# restoring settings
|
||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, active_texture[0])
|
||||
bgl.glDisable(bgl.GL_TEXTURE_2D)
|
||||
|
||||
# reset view
|
||||
bgl.glViewport(viewport[0], viewport[1], viewport[2], viewport[3])
|
||||
bgl.glScissor(viewport[0], viewport[1], viewport[2], viewport[3])
|
||||
|
||||
def get_batch_plane(self):
|
||||
if self.batch_plane is None:
|
||||
global g_plane_vertices
|
||||
|
||||
format = gpu.types.GPUVertFormat()
|
||||
pos_id = format.attr_add(
|
||||
id="pos",
|
||||
comp_type='F32',
|
||||
len=2,
|
||||
fetch_mode='FLOAT',
|
||||
)
|
||||
uv_id = format.attr_add(
|
||||
id="texCoord",
|
||||
comp_type='F32',
|
||||
len=2,
|
||||
fetch_mode='FLOAT',
|
||||
)
|
||||
vbo = gpu.types.GPUVertBuf(
|
||||
len=len(g_plane_vertices),
|
||||
format=format,
|
||||
)
|
||||
|
||||
vbo.attr_fill(id=pos_id, data=g_plane_vertices["pos"])
|
||||
vbo.attr_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
|
||||
def poll(cls, context):
|
||||
return context.area.type == 'VIEW_3D'
|
||||
|
||||
def modal(self, context, event):
|
||||
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 VIEW3D_OT_draw_offscreen.is_enabled:
|
||||
self.cancel(context)
|
||||
return {'FINISHED'}
|
||||
else:
|
||||
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'}
|
||||
|
||||
VIEW3D_OT_draw_offscreen.handle_add(self, context)
|
||||
VIEW3D_OT_draw_offscreen.is_enabled = True
|
||||
|
||||
if context.area:
|
||||
context.area.tag_redraw()
|
||||
|
||||
context.window_manager.modal_handler_add(self)
|
||||
return {'RUNNING_MODAL'}
|
||||
|
||||
def cancel(self, context):
|
||||
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():
|
||||
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(VIEW3D_OT_draw_offscreen)
|
||||
VIEW3D_OT_draw_offscreen.global_shader = None
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
unregister()
|
||||
except RuntimeError:
|
||||
pass
|
||||
else:
|
||||
if hasattr(bpy.types, "VIEW3D_OT_draw_offscreen"):
|
||||
del bpy.types.VIEW3D_OT_draw_offscreen.global_shader
|
||||
|
||||
register()
|
Reference in New Issue
Block a user