From 2e52b3206cc6a108e2b832c0a5c38684402565ea Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 2 Jun 2020 18:20:15 -0400 Subject: PyDoc: Fix warnings from out of bounds include statement --- doc/python_api/examples/gpu.1.py | 20 +++++++++ doc/python_api/examples/gpu.10.py | 76 +++++++++++++++++++++----------- doc/python_api/examples/gpu.11.py | 65 --------------------------- doc/python_api/examples/gpu.2.py | 38 +++++++++++++--- doc/python_api/examples/gpu.3.py | 44 ++++++------------- doc/python_api/examples/gpu.4.py | 39 ++++++++++------- doc/python_api/examples/gpu.5.py | 37 +++++----------- doc/python_api/examples/gpu.6.py | 31 ++++++++----- doc/python_api/examples/gpu.7.py | 77 ++++++++++++++++++++++++++------ doc/python_api/examples/gpu.8.py | 92 ++++++++++++--------------------------- doc/python_api/examples/gpu.9.py | 61 +++++++++++--------------- 11 files changed, 290 insertions(+), 290 deletions(-) delete mode 100644 doc/python_api/examples/gpu.11.py diff --git a/doc/python_api/examples/gpu.1.py b/doc/python_api/examples/gpu.1.py index 831349e5430..a014e69c2d2 100644 --- a/doc/python_api/examples/gpu.1.py +++ b/doc/python_api/examples/gpu.1.py @@ -119,4 +119,24 @@ Examples To try these examples, just copy them into Blenders text editor and execute them. To keep the examples relatively small, they just register a draw function that can't easily be removed anymore. Blender has to be restarted in order to delete the draw handlers. + +3D Lines with Single Color +-------------------------- """ + +import bpy +import gpu +from gpu_extras.batch import batch_for_shader + +coords = [(1, 1, 1), (-2, 0, 0), (-2, -1, 3), (0, 1, 1)] +shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') +batch = batch_for_shader(shader, 'LINES', {"pos": coords}) + + +def draw(): + shader.bind() + shader.uniform_float("color", (1, 1, 0, 1)) + batch.draw(shader) + + +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.10.py b/doc/python_api/examples/gpu.10.py index a4db576ecc0..2f255b7127d 100644 --- a/doc/python_api/examples/gpu.10.py +++ b/doc/python_api/examples/gpu.10.py @@ -1,41 +1,65 @@ """ -Rendering the 3D View into a Texture ------------------------------------- +Custom Shader for dotted 3D Line +-------------------------------- -The scene has to have a camera for this example to work. -You could also make this independent of a specific camera, -but Blender does not expose good functions to create view and projection matrices yet. +In this example the arc length (distance to the first point on the line) is calculated in every vertex. +Between the vertex and fragment shader that value is automatically interpolated +for all points that will be visible on the screen. +In the fragment shader the ``sin`` of the arc length is calculated. +Based on the result a decision is made on whether the fragment should be drawn or not. """ import bpy -import bgl import gpu -from gpu_extras.presets import draw_texture_2d +from random import random +from mathutils import Vector +from gpu_extras.batch import batch_for_shader -WIDTH = 512 -HEIGHT = 256 +vertex_shader = ''' + uniform mat4 u_ViewProjectionMatrix; -offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT) + in vec3 position; + in float arcLength; + out float v_ArcLength; -def draw(): - context = bpy.context - scene = context.scene + void main() + { + v_ArcLength = arcLength; + gl_Position = u_ViewProjectionMatrix * vec4(position, 1.0f); + } +''' + +fragment_shader = ''' + uniform float u_Scale; + + in float v_ArcLength; - view_matrix = scene.camera.matrix_world.inverted() + void main() + { + if (step(sin(v_ArcLength * u_Scale), 0.5) == 1) discard; + gl_FragColor = vec4(1.0); + } +''' - projection_matrix = scene.camera.calc_matrix_camera( - context.evaluated_depsgraph_get(), x=WIDTH, y=HEIGHT) +coords = [Vector((random(), random(), random())) * 5 for _ in range(5)] - offscreen.draw_view3d( - scene, - context.view_layer, - context.space_data, - context.region, - view_matrix, - projection_matrix) +arc_lengths = [0] +for a, b in zip(coords[:-1], coords[1:]): + arc_lengths.append(arc_lengths[-1] + (a - b).length) - bgl.glDisable(bgl.GL_DEPTH_TEST) - draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT) +shader = gpu.types.GPUShader(vertex_shader, fragment_shader) +batch = batch_for_shader( + shader, 'LINE_STRIP', + {"position": coords, "arcLength": arc_lengths}, +) + + +def draw(): + shader.bind() + matrix = bpy.context.region_data.perspective_matrix + shader.uniform_float("u_ViewProjectionMatrix", matrix) + shader.uniform_float("u_Scale", 10) + batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.11.py b/doc/python_api/examples/gpu.11.py deleted file mode 100644 index 2f255b7127d..00000000000 --- a/doc/python_api/examples/gpu.11.py +++ /dev/null @@ -1,65 +0,0 @@ -""" -Custom Shader for dotted 3D Line --------------------------------- - -In this example the arc length (distance to the first point on the line) is calculated in every vertex. -Between the vertex and fragment shader that value is automatically interpolated -for all points that will be visible on the screen. -In the fragment shader the ``sin`` of the arc length is calculated. -Based on the result a decision is made on whether the fragment should be drawn or not. -""" -import bpy -import gpu -from random import random -from mathutils import Vector -from gpu_extras.batch import batch_for_shader - -vertex_shader = ''' - uniform mat4 u_ViewProjectionMatrix; - - in vec3 position; - in float arcLength; - - out float v_ArcLength; - - void main() - { - v_ArcLength = arcLength; - gl_Position = u_ViewProjectionMatrix * vec4(position, 1.0f); - } -''' - -fragment_shader = ''' - uniform float u_Scale; - - in float v_ArcLength; - - void main() - { - if (step(sin(v_ArcLength * u_Scale), 0.5) == 1) discard; - gl_FragColor = vec4(1.0); - } -''' - -coords = [Vector((random(), random(), random())) * 5 for _ in range(5)] - -arc_lengths = [0] -for a, b in zip(coords[:-1], coords[1:]): - arc_lengths.append(arc_lengths[-1] + (a - b).length) - -shader = gpu.types.GPUShader(vertex_shader, fragment_shader) -batch = batch_for_shader( - shader, 'LINE_STRIP', - {"position": coords, "arcLength": arc_lengths}, -) - - -def draw(): - shader.bind() - matrix = bpy.context.region_data.perspective_matrix - shader.uniform_float("u_ViewProjectionMatrix", matrix) - shader.uniform_float("u_Scale", 10) - batch.draw(shader) - - -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.2.py b/doc/python_api/examples/gpu.2.py index d1e8ac32589..4bee9acebe3 100644 --- a/doc/python_api/examples/gpu.2.py +++ b/doc/python_api/examples/gpu.2.py @@ -1,19 +1,45 @@ """ -3D Lines with Single Color --------------------------- +Triangle with Custom Shader +--------------------------- """ import bpy import gpu from gpu_extras.batch import batch_for_shader -coords = [(1, 1, 1), (-2, 0, 0), (-2, -1, 3), (0, 1, 1)] -shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') -batch = batch_for_shader(shader, 'LINES', {"pos": coords}) +vertex_shader = ''' + uniform mat4 viewProjectionMatrix; + + in vec3 position; + out vec3 pos; + + void main() + { + pos = position; + gl_Position = viewProjectionMatrix * vec4(position, 1.0f); + } +''' + +fragment_shader = ''' + uniform float brightness; + + in vec3 pos; + + void main() + { + gl_FragColor = vec4(pos * brightness, 1.0); + } +''' + +coords = [(1, 1, 1), (2, 0, 0), (-2, -1, 3)] +shader = gpu.types.GPUShader(vertex_shader, fragment_shader) +batch = batch_for_shader(shader, 'TRIS', {"position": coords}) def draw(): shader.bind() - shader.uniform_float("color", (1, 1, 0, 1)) + matrix = bpy.context.region_data.perspective_matrix + shader.uniform_float("viewProjectionMatrix", matrix) + shader.uniform_float("brightness", 0.5) batch.draw(shader) diff --git a/doc/python_api/examples/gpu.3.py b/doc/python_api/examples/gpu.3.py index 4bee9acebe3..0c86b52bcf5 100644 --- a/doc/python_api/examples/gpu.3.py +++ b/doc/python_api/examples/gpu.3.py @@ -1,45 +1,29 @@ """ -Triangle with Custom Shader ---------------------------- +Wireframe Cube using Index Buffer +--------------------------------- """ import bpy import gpu from gpu_extras.batch import batch_for_shader -vertex_shader = ''' - uniform mat4 viewProjectionMatrix; +coords = ( + (-1, -1, -1), (+1, -1, -1), + (-1, +1, -1), (+1, +1, -1), + (-1, -1, +1), (+1, -1, +1), + (-1, +1, +1), (+1, +1, +1)) - in vec3 position; - out vec3 pos; +indices = ( + (0, 1), (0, 2), (1, 3), (2, 3), + (4, 5), (4, 6), (5, 7), (6, 7), + (0, 4), (1, 5), (2, 6), (3, 7)) - void main() - { - pos = position; - gl_Position = viewProjectionMatrix * vec4(position, 1.0f); - } -''' - -fragment_shader = ''' - uniform float brightness; - - in vec3 pos; - - void main() - { - gl_FragColor = vec4(pos * brightness, 1.0); - } -''' - -coords = [(1, 1, 1), (2, 0, 0), (-2, -1, 3)] -shader = gpu.types.GPUShader(vertex_shader, fragment_shader) -batch = batch_for_shader(shader, 'TRIS', {"position": coords}) +shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') +batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices) def draw(): shader.bind() - matrix = bpy.context.region_data.perspective_matrix - shader.uniform_float("viewProjectionMatrix", matrix) - shader.uniform_float("brightness", 0.5) + shader.uniform_float("color", (1, 0, 0, 1)) batch.draw(shader) diff --git a/doc/python_api/examples/gpu.4.py b/doc/python_api/examples/gpu.4.py index 0c86b52bcf5..e05290a9442 100644 --- a/doc/python_api/examples/gpu.4.py +++ b/doc/python_api/examples/gpu.4.py @@ -1,30 +1,39 @@ """ -Wireframe Cube using Index Buffer ---------------------------------- +Mesh with Random Vertex Colors +------------------------------ """ import bpy import gpu +import bgl +import numpy as np +from random import random from gpu_extras.batch import batch_for_shader -coords = ( - (-1, -1, -1), (+1, -1, -1), - (-1, +1, -1), (+1, +1, -1), - (-1, -1, +1), (+1, -1, +1), - (-1, +1, +1), (+1, +1, +1)) +mesh = bpy.context.active_object.data +mesh.calc_loop_triangles() -indices = ( - (0, 1), (0, 2), (1, 3), (2, 3), - (4, 5), (4, 6), (5, 7), (6, 7), - (0, 4), (1, 5), (2, 6), (3, 7)) +vertices = np.empty((len(mesh.vertices), 3), 'f') +indices = np.empty((len(mesh.loop_triangles), 3), 'i') -shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') -batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices) +mesh.vertices.foreach_get( + "co", np.reshape(vertices, len(mesh.vertices) * 3)) +mesh.loop_triangles.foreach_get( + "vertices", np.reshape(indices, len(mesh.loop_triangles) * 3)) + +vertex_colors = [(random(), random(), random(), 1) for _ in range(len(mesh.vertices))] + +shader = gpu.shader.from_builtin('3D_SMOOTH_COLOR') +batch = batch_for_shader( + shader, 'TRIS', + {"pos": vertices, "color": vertex_colors}, + indices=indices, +) def draw(): - shader.bind() - shader.uniform_float("color", (1, 0, 0, 1)) + bgl.glEnable(bgl.GL_DEPTH_TEST) batch.draw(shader) + bgl.glDisable(bgl.GL_DEPTH_TEST) bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.5.py b/doc/python_api/examples/gpu.5.py index e05290a9442..2edde46a364 100644 --- a/doc/python_api/examples/gpu.5.py +++ b/doc/python_api/examples/gpu.5.py @@ -1,39 +1,26 @@ """ -Mesh with Random Vertex Colors ------------------------------- +2D Rectangle +------------ """ import bpy import gpu -import bgl -import numpy as np -from random import random from gpu_extras.batch import batch_for_shader -mesh = bpy.context.active_object.data -mesh.calc_loop_triangles() +vertices = ( + (100, 100), (300, 100), + (100, 200), (300, 200)) -vertices = np.empty((len(mesh.vertices), 3), 'f') -indices = np.empty((len(mesh.loop_triangles), 3), 'i') +indices = ( + (0, 1, 2), (2, 1, 3)) -mesh.vertices.foreach_get( - "co", np.reshape(vertices, len(mesh.vertices) * 3)) -mesh.loop_triangles.foreach_get( - "vertices", np.reshape(indices, len(mesh.loop_triangles) * 3)) - -vertex_colors = [(random(), random(), random(), 1) for _ in range(len(mesh.vertices))] - -shader = gpu.shader.from_builtin('3D_SMOOTH_COLOR') -batch = batch_for_shader( - shader, 'TRIS', - {"pos": vertices, "color": vertex_colors}, - indices=indices, -) +shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') +batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices) def draw(): - bgl.glEnable(bgl.GL_DEPTH_TEST) + shader.bind() + shader.uniform_float("color", (0, 0.5, 0.5, 1.0)) batch.draw(shader) - bgl.glDisable(bgl.GL_DEPTH_TEST) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') diff --git a/doc/python_api/examples/gpu.6.py b/doc/python_api/examples/gpu.6.py index 2edde46a364..69af65e163e 100644 --- a/doc/python_api/examples/gpu.6.py +++ b/doc/python_api/examples/gpu.6.py @@ -1,25 +1,36 @@ """ -2D Rectangle ------------- +2D Image +-------- + +To use this example you have to provide an image that should be displayed. """ import bpy import gpu +import bgl from gpu_extras.batch import batch_for_shader -vertices = ( - (100, 100), (300, 100), - (100, 200), (300, 200)) +IMAGE_NAME = "Untitled" +image = bpy.data.images[IMAGE_NAME] -indices = ( - (0, 1, 2), (2, 1, 3)) +shader = gpu.shader.from_builtin('2D_IMAGE') +batch = batch_for_shader( + shader, 'TRI_FAN', + { + "pos": ((100, 100), (200, 100), (200, 200), (100, 200)), + "texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)), + }, +) -shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') -batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices) +if image.gl_load(): + raise Exception() def draw(): + bgl.glActiveTexture(bgl.GL_TEXTURE0) + bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode) + shader.bind() - shader.uniform_float("color", (0, 0.5, 0.5, 1.0)) + shader.uniform_int("image", 0) batch.draw(shader) diff --git a/doc/python_api/examples/gpu.7.py b/doc/python_api/examples/gpu.7.py index 69af65e163e..56cbb93c61a 100644 --- a/doc/python_api/examples/gpu.7.py +++ b/doc/python_api/examples/gpu.7.py @@ -1,37 +1,86 @@ """ -2D Image --------- +Generate a texture using Offscreen Rendering +-------------------------------------------- -To use this example you have to provide an image that should be displayed. +#. Create an :class:`gpu.types.GPUOffScreen` object. +#. Draw some circles into it. +#. Make a new shader for drawing a planar texture in 3D. +#. Draw the generated texture using the new shader. """ import bpy import gpu import bgl +from mathutils import Matrix from gpu_extras.batch import batch_for_shader +from gpu_extras.presets import draw_circle_2d -IMAGE_NAME = "Untitled" -image = bpy.data.images[IMAGE_NAME] +# Create and fill offscreen +########################################## -shader = gpu.shader.from_builtin('2D_IMAGE') +offscreen = gpu.types.GPUOffScreen(512, 512) + +with offscreen.bind(): + 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)) + + amount = 10 + for i in range(-amount, amount + 1): + x_pos = i / amount + draw_circle_2d((x_pos, 0.0), (1, 1, 1, 1), 0.5, 200) + + +# Drawing the generated texture in 3D space +############################################# + +vertex_shader = ''' + uniform mat4 modelMatrix; + uniform mat4 viewProjectionMatrix; + + in vec2 position; + in vec2 uv; + + out vec2 uvInterp; + + void main() + { + uvInterp = uv; + gl_Position = viewProjectionMatrix * modelMatrix * vec4(position, 0.0, 1.0); + } +''' + +fragment_shader = ''' + uniform sampler2D image; + + in vec2 uvInterp; + + void main() + { + gl_FragColor = texture(image, uvInterp); + } +''' + +shader = gpu.types.GPUShader(vertex_shader, fragment_shader) batch = batch_for_shader( shader, 'TRI_FAN', { - "pos": ((100, 100), (200, 100), (200, 200), (100, 200)), - "texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)), + "position": ((-1, -1), (1, -1), (1, 1), (-1, 1)), + "uv": ((0, 0), (1, 0), (1, 1), (0, 1)), }, ) -if image.gl_load(): - raise Exception() - def draw(): bgl.glActiveTexture(bgl.GL_TEXTURE0) - bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode) + bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture) shader.bind() - shader.uniform_int("image", 0) + shader.uniform_float("modelMatrix", Matrix.Translation((1, 2, 3)) @ Matrix.Scale(3, 4)) + shader.uniform_float("viewProjectionMatrix", bpy.context.region_data.perspective_matrix) + shader.uniform_float("image", 0) batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.8.py b/doc/python_api/examples/gpu.8.py index 56cbb93c61a..470bd8a2dad 100644 --- a/doc/python_api/examples/gpu.8.py +++ b/doc/python_api/examples/gpu.8.py @@ -1,23 +1,28 @@ """ -Generate a texture using Offscreen Rendering --------------------------------------------- +Copy Offscreen Rendering result back to RAM +------------------------------------------- -#. Create an :class:`gpu.types.GPUOffScreen` object. -#. Draw some circles into it. -#. Make a new shader for drawing a planar texture in 3D. -#. Draw the generated texture using the new shader. +This will create a new image with the given name. +If it already exists, it will override the existing one. + +Currently almost all of the execution time is spent in the last line. +In the future this will hopefully be solved by implementing the Python buffer protocol +for :class:`bgl.Buffer` and :class:`bpy.types.Image.pixels` (aka ``bpy_prop_array``). """ import bpy import gpu import bgl +import random from mathutils import Matrix -from gpu_extras.batch import batch_for_shader from gpu_extras.presets import draw_circle_2d -# Create and fill offscreen -########################################## +IMAGE_NAME = "Generated Image" +WIDTH = 512 +HEIGHT = 512 +RING_AMOUNT = 10 + -offscreen = gpu.types.GPUOffScreen(512, 512) +offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT) with offscreen.bind(): bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) @@ -26,61 +31,20 @@ with offscreen.bind(): gpu.matrix.load_matrix(Matrix.Identity(4)) gpu.matrix.load_projection_matrix(Matrix.Identity(4)) - amount = 10 - for i in range(-amount, amount + 1): - x_pos = i / amount - draw_circle_2d((x_pos, 0.0), (1, 1, 1, 1), 0.5, 200) - - -# Drawing the generated texture in 3D space -############################################# - -vertex_shader = ''' - uniform mat4 modelMatrix; - uniform mat4 viewProjectionMatrix; - - in vec2 position; - in vec2 uv; - - out vec2 uvInterp; - - void main() - { - uvInterp = uv; - gl_Position = viewProjectionMatrix * modelMatrix * vec4(position, 0.0, 1.0); - } -''' - -fragment_shader = ''' - uniform sampler2D image; - - in vec2 uvInterp; - - void main() - { - gl_FragColor = texture(image, uvInterp); - } -''' - -shader = gpu.types.GPUShader(vertex_shader, fragment_shader) -batch = batch_for_shader( - shader, 'TRI_FAN', - { - "position": ((-1, -1), (1, -1), (1, 1), (-1, 1)), - "uv": ((0, 0), (1, 0), (1, 1), (0, 1)), - }, -) - + 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) -def draw(): - bgl.glActiveTexture(bgl.GL_TEXTURE0) - bgl.glBindTexture(bgl.GL_TEXTURE_2D, offscreen.color_texture) + 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) - shader.bind() - shader.uniform_float("modelMatrix", Matrix.Translation((1, 2, 3)) @ Matrix.Scale(3, 4)) - shader.uniform_float("viewProjectionMatrix", bpy.context.region_data.perspective_matrix) - shader.uniform_float("image", 0) - batch.draw(shader) +offscreen.free() -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') +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] diff --git a/doc/python_api/examples/gpu.9.py b/doc/python_api/examples/gpu.9.py index 470bd8a2dad..a4db576ecc0 100644 --- a/doc/python_api/examples/gpu.9.py +++ b/doc/python_api/examples/gpu.9.py @@ -1,50 +1,41 @@ """ -Copy Offscreen Rendering result back to RAM -------------------------------------------- +Rendering the 3D View into a Texture +------------------------------------ -This will create a new image with the given name. -If it already exists, it will override the existing one. - -Currently almost all of the execution time is spent in the last line. -In the future this will hopefully be solved by implementing the Python buffer protocol -for :class:`bgl.Buffer` and :class:`bpy.types.Image.pixels` (aka ``bpy_prop_array``). +The scene has to have a camera for this example to work. +You could also make this independent of a specific camera, +but Blender does not expose good functions to create view and projection matrices yet. """ import bpy -import gpu import bgl -import random -from mathutils import Matrix -from gpu_extras.presets import draw_circle_2d +import gpu +from gpu_extras.presets import draw_texture_2d -IMAGE_NAME = "Generated Image" WIDTH = 512 -HEIGHT = 512 -RING_AMOUNT = 10 - +HEIGHT = 256 offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT) -with offscreen.bind(): - 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) +def draw(): + context = bpy.context + scene = context.scene + + view_matrix = scene.camera.matrix_world.inverted() + + projection_matrix = scene.camera.calc_matrix_camera( + context.evaluated_depsgraph_get(), x=WIDTH, y=HEIGHT) - 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) + offscreen.draw_view3d( + scene, + context.view_layer, + context.space_data, + context.region, + view_matrix, + projection_matrix) -offscreen.free() + bgl.glDisable(bgl.GL_DEPTH_TEST) + draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT) -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] +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') -- cgit v1.2.3