From 3c8c9760865d14c8dffa3a4cd091e4027b1501e3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 20 Nov 2018 07:32:49 +1100 Subject: Cleanup: gpu docs --- doc/python_api/examples/gpu.1.py | 69 +++++++++++++++++++++-------------- doc/python_api/examples/gpu.10.py | 7 +++- doc/python_api/examples/gpu.11.py | 16 +++++--- doc/python_api/examples/gpu.2.py | 5 ++- doc/python_api/examples/gpu.3.py | 6 ++- doc/python_api/examples/gpu.4.py | 14 ++++--- doc/python_api/examples/gpu.5.py | 21 ++++++----- doc/python_api/examples/gpu.6.py | 6 ++- doc/python_api/examples/gpu.7.py | 14 +++++-- doc/python_api/examples/gpu.8.py | 21 +++++++---- doc/python_api/examples/gpu.9.py | 6 +-- doc/python_api/examples/gpu.shader.py | 31 ++++++++-------- 12 files changed, 130 insertions(+), 86 deletions(-) (limited to 'doc/python_api') diff --git a/doc/python_api/examples/gpu.1.py b/doc/python_api/examples/gpu.1.py index c8ae3b01ee3..831349e5430 100644 --- a/doc/python_api/examples/gpu.1.py +++ b/doc/python_api/examples/gpu.1.py @@ -4,7 +4,8 @@ Geometry Batches Geometry is drawn in batches. A batch contains the necessary data to perform the drawing. -That includes an obligatory *Vertex Buffer* and an optional *Index Buffer*, each of which is described in more detail in the following sections. +That includes an obligatory *Vertex Buffer* and an optional *Index Buffer*, +each of which is described in more detail in the following sections. A batch also defines a draw type. Typical draw types are `POINTS`, `LINES` and `TRIS`. The draw type determines how the data will be interpreted and drawn. @@ -12,25 +13,29 @@ The draw type determines how the data will be interpreted and drawn. Vertex Buffers ++++++++++++++ -A *Vertex Buffer Object* (VBO) (:class:`gpu.types.GPUVertBuf`) is an array that contains the vertex attributes needed for drawing using a specific shader. +A *Vertex Buffer Object* (VBO) (:class:`gpu.types.GPUVertBuf`) +is an array that contains the vertex attributes needed for drawing using a specific shader. Typical vertex attributes are *location*, *normal*, *color*, and *uv*. -Every vertex buffer has a *Vertex Format* (:class:`gpu.types.GPUVertFormat`) and a length corresponding to the number of vertices in the buffer. +Every vertex buffer has a *Vertex Format* (:class:`gpu.types.GPUVertFormat`) +and a length corresponding to the number of vertices in the buffer. A vertex format describes the attributes stored per vertex and their types. The following code demonstrates the creation of a vertex buffer that contains 6 vertices. -For each vertex 2 attributes will be stored: The position and the normal:: +For each vertex 2 attributes will be stored: The position and the normal. - import gpu - vertex_positions = [(0, 0, 0), ...] - vertex_normals = [(0, 0, 1), ...] +.. code-block:: python - fmt = gpu.types.GPUVertFormat() - fmt.attr_add(id="pos", comp_type='F32', len=3, fetch_mode='FLOAT') - fmt.attr_add(id="normal", comp_type='F32', len=3, fetch_mode='FLOAT') + import gpu + vertex_positions = [(0, 0, 0), ...] + vertex_normals = [(0, 0, 1), ...] - vbo = gpu.types.GPUVertBuf(len=6, format=fmt) - vbo.attr_fill(id="pos", data=vertex_positions) - vbo.attr_fill(id="normal", data=vertex_normals) + fmt = gpu.types.GPUVertFormat() + fmt.attr_add(id="pos", comp_type='F32', len=3, fetch_mode='FLOAT') + fmt.attr_add(id="normal", comp_type='F32', len=3, fetch_mode='FLOAT') + + vbo = gpu.types.GPUVertBuf(len=6, format=fmt) + vbo.attr_fill(id="pos", data=vertex_positions) + vbo.attr_fill(id="normal", data=vertex_normals) This vertex buffer could be used to draw 6 points, 3 separate lines, 5 consecutive lines, 2 separate triangles, ... E.g. in the case of lines, each two consecutive vertices define a line. @@ -42,19 +47,24 @@ Index Buffers Often triangles and lines share one or more vertices. With only a vertex buffer one would have to store all attributes for the these vertices multiple times. This is very inefficient because in a connected triangle mesh every vertex is used 6 times on average. -A more efficient approach would be to use an *Index Buffer* (IBO) (:class:`gpu.types.GPUIndexBuf`), sometimes referred to as *Element Buffer*. +A more efficient approach would be to use an *Index Buffer* (IBO) (:class:`gpu.types.GPUIndexBuf`), +sometimes referred to as *Element Buffer*. An *Index Buffer* is an array that references vertices based on their index in the vertex buffer. -For instance, to draw a rectangle composed of two triangles, one could use an index buffer:: - positions = ( - (-1, 1), (1, 1), - (-1, -1), (1, -1)) +For instance, to draw a rectangle composed of two triangles, one could use an index buffer. + +.. code-block:: python + + positions = ( + (-1, 1), (1, 1), + (-1, -1), (1, -1)) - indices = ((0, 1, 2), (2, 1, 3)) + indices = ((0, 1, 2), (2, 1, 3)) - ibo = gpu.types.GPUIndexBuf(type='TRIS', seq=indices) + ibo = gpu.types.GPUIndexBuf(type='TRIS', seq=indices) -Here the first tuple in `indices` describes which vertices should be used for the first triangle (same for the second tuple). +Here the first tuple in `indices` describes which vertices should be used for the first triangle +(same for the second tuple). Note how the diagonal vertices 1 and 2 are shared between both triangles. Shaders @@ -66,7 +76,8 @@ The most important ones are *Vertex Shaders* and *Fragment Shaders*. Typically multiple shaders are linked together into a *Program*. However, in the Blender Python API the term *Shader* refers to an OpenGL Program. Every :class:`gpu.types.GPUShader` consists of a vertex shader, a fragment shader and an optional geometry shader. -For common drawing tasks there are some built-in shaders accessible from :class:`gpu.shader.from_builtin` with an identifier such as `2D_UNIFORM_COLOR` or `3D_FLAT_COLOR`. +For common drawing tasks there are some built-in shaders accessible from :class:`gpu.shader.from_builtin` +with an identifier such as `2D_UNIFORM_COLOR` or `3D_FLAT_COLOR`. Every shader defines a set of attributes and uniforms that have to be set in order to use the shader. Attributes are properties that are set using a vertex buffer and can be different for individual vertices. @@ -89,14 +100,18 @@ Offscreen Rendering +++++++++++++++++++ What one can see on the screen after rendering is called the *Front Buffer*. -When draw calls are issued, batches are drawn on a *Back Buffer* that will only be displayed when all drawing is done and the current back buffer will become the new front buffer. -Sometimes, one might want to draw the batches into a distinct buffer that could be used as texture to display on another object or to be saved as image on disk. +When draw calls are issued, batches are drawn on a *Back Buffer* that will only be displayed +when all drawing is done and the current back buffer will become the new front buffer. +Sometimes, one might want to draw the batches into a distinct buffer that could be used as +texture to display on another object or to be saved as image on disk. This is called Offscreen Rendering. In Blender Offscreen Rendering is done using the :class:`gpu.types.GPUOffScreen` type. .. warning:: - `GPUOffScreen` objects are bound to the OpenGL context they have been created in. - This means that once Blender discards this context (i.e. the window is closed), the offscreen instance will be freed. + + `GPUOffScreen` objects are bound to the OpenGL context they have been created in. + This means that once Blender discards this context (i.e. the window is closed), + the offscreen instance will be freed. Examples ++++++++ @@ -104,4 +119,4 @@ 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. -""" \ No newline at end of file +""" diff --git a/doc/python_api/examples/gpu.10.py b/doc/python_api/examples/gpu.10.py index aa5574c44bb..6e7a3f6db6f 100644 --- a/doc/python_api/examples/gpu.10.py +++ b/doc/python_api/examples/gpu.10.py @@ -3,7 +3,8 @@ Rendering the 3D View into a Texture ------------------------------------ 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. +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 bgl @@ -15,6 +16,7 @@ HEIGHT = 256 offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT) + def draw(): context = bpy.context scene = context.scene @@ -35,4 +37,5 @@ def draw(): bgl.glDisable(bgl.GL_DEPTH_TEST) draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') \ No newline at end of file + +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') diff --git a/doc/python_api/examples/gpu.11.py b/doc/python_api/examples/gpu.11.py index 61e7a842a59..2f255b7127d 100644 --- a/doc/python_api/examples/gpu.11.py +++ b/doc/python_api/examples/gpu.11.py @@ -3,8 +3,9 @@ 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. +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 @@ -47,9 +48,11 @@ 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}) +batch = batch_for_shader( + shader, 'LINE_STRIP', + {"position": coords, "arcLength": arc_lengths}, +) + def draw(): shader.bind() @@ -58,4 +61,5 @@ def draw(): shader.uniform_float("u_Scale", 10) batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') \ No newline at end of file + +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 8188110d096..d1e8ac32589 100644 --- a/doc/python_api/examples/gpu.2.py +++ b/doc/python_api/examples/gpu.2.py @@ -8,12 +8,13 @@ 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}) +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') +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.3.py b/doc/python_api/examples/gpu.3.py index 30f340c30ff..4bee9acebe3 100644 --- a/doc/python_api/examples/gpu.3.py +++ b/doc/python_api/examples/gpu.3.py @@ -32,7 +32,8 @@ fragment_shader = ''' 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}) +batch = batch_for_shader(shader, 'TRIS', {"position": coords}) + def draw(): shader.bind() @@ -41,4 +42,5 @@ def draw(): shader.uniform_float("brightness", 0.5) batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') \ No newline at end of file + +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.4.py b/doc/python_api/examples/gpu.4.py index 392f010e7c2..0c86b52bcf5 100644 --- a/doc/python_api/examples/gpu.4.py +++ b/doc/python_api/examples/gpu.4.py @@ -7,10 +7,10 @@ import gpu 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)) + (-1, -1, -1), (+1, -1, -1), + (-1, +1, -1), (+1, +1, -1), + (-1, -1, +1), (+1, -1, +1), + (-1, +1, +1), (+1, +1, +1)) indices = ( (0, 1), (0, 2), (1, 3), (2, 3), @@ -18,11 +18,13 @@ indices = ( (0, 4), (1, 5), (2, 6), (3, 7)) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') -batch = batch_for_shader(shader, 'LINES', {"pos" : coords}, indices=indices) +batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices) + def draw(): shader.bind() shader.uniform_float("color", (1, 0, 0, 1)) batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') \ No newline at end of file + +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 7af3a518457..855f9a28e44 100644 --- a/doc/python_api/examples/gpu.5.py +++ b/doc/python_api/examples/gpu.5.py @@ -14,20 +14,23 @@ mesh.calc_loop_triangles() vertices = np.empty((len(mesh.vertices), 3), 'f') indices = np.empty((len(mesh.loop_triangles), 3), 'i') -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)) +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) +batch = batch_for_shader( + shader, 'TRIS', + {"pos": vertices, "color": vertex_colors}, + indices=indices, +) + def draw(): batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') \ No newline at end of file + +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.6.py b/doc/python_api/examples/gpu.6.py index df28d801960..2edde46a364 100644 --- a/doc/python_api/examples/gpu.6.py +++ b/doc/python_api/examples/gpu.6.py @@ -14,11 +14,13 @@ indices = ( (0, 1, 2), (2, 1, 3)) shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') -batch = batch_for_shader(shader, 'TRIS', {"pos" : vertices}, indices=indices) +batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices) + def draw(): shader.bind() shader.uniform_float("color", (0, 0.5, 0.5, 1.0)) batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') \ No newline at end of file + +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') diff --git a/doc/python_api/examples/gpu.7.py b/doc/python_api/examples/gpu.7.py index 486ed5fd411..69af65e163e 100644 --- a/doc/python_api/examples/gpu.7.py +++ b/doc/python_api/examples/gpu.7.py @@ -13,13 +13,18 @@ IMAGE_NAME = "Untitled" image = bpy.data.images[IMAGE_NAME] 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))}) +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)), + }, +) if image.gl_load(): raise Exception() + def draw(): bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode) @@ -28,4 +33,5 @@ def draw(): shader.uniform_int("image", 0) batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') \ No newline at end of file + +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL') diff --git a/doc/python_api/examples/gpu.8.py b/doc/python_api/examples/gpu.8.py index 28964d2e6b2..56cbb93c61a 100644 --- a/doc/python_api/examples/gpu.8.py +++ b/doc/python_api/examples/gpu.8.py @@ -2,10 +2,10 @@ Generate a texture using Offscreen Rendering -------------------------------------------- -1. Create an :class:`gpu.types.GPUOffScreen` object. -2. Draw some circles into it. -3. Make a new shader for drawing a planar texture in 3D. -4. Draw the generated texture using the new shader. +#. 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 @@ -63,9 +63,13 @@ fragment_shader = ''' ''' 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))}) +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)), + }, +) def draw(): @@ -78,4 +82,5 @@ def draw(): shader.uniform_float("image", 0) batch.draw(shader) -bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') \ No newline at end of file + +bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW') diff --git a/doc/python_api/examples/gpu.9.py b/doc/python_api/examples/gpu.9.py index 84e279946da..470bd8a2dad 100644 --- a/doc/python_api/examples/gpu.9.py +++ b/doc/python_api/examples/gpu.9.py @@ -6,7 +6,8 @@ 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 `bgl.Buffer` and `Image.pixels` (aka `bpy_prop_array`). +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 @@ -35,7 +36,6 @@ with offscreen.bind(): (random.uniform(-1, 1), random.uniform(-1, 1)), (1, 1, 1, 1), random.uniform(0.1, 1), 20) - 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) @@ -47,4 +47,4 @@ 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] \ No newline at end of file +image.pixels = [v / 255 for v in buffer] diff --git a/doc/python_api/examples/gpu.shader.py b/doc/python_api/examples/gpu.shader.py index 7ffd3fe85c8..3c72e70378c 100644 --- a/doc/python_api/examples/gpu.shader.py +++ b/doc/python_api/examples/gpu.shader.py @@ -4,32 +4,33 @@ Built-in shaders All built-in shaders have the ``mat4 ModelViewProjectionMatrix`` uniform. The value of it can only be modified using the :class:`gpu.matrix` module. -""" 2D_UNIFORM_COLOR: - attributes: vec3 pos - uniforms: vec4 color + attributes: vec3 pos + uniforms: vec4 color 2D_FLAT_COLOR: - attributes: vec3 pos, vec4 color - uniforms: - + attributes: vec3 pos, vec4 color + uniforms: - 2D_SMOOTH_COLOR: - attributes: vec3 pos, vec4 color - uniforms: - + attributes: vec3 pos, vec4 color + uniforms: - 2D_IMAGE: - attributes: vec3 pos, vec2 texCoord - uniforms: sampler2D image + attributes: vec3 pos, vec2 texCoord + uniforms: sampler2D image 3D_UNIFORM_COLOR: - attributes: vec3 pos - uniforms: vec4 color + attributes: vec3 pos + uniforms: vec4 color 3D_FLAT_COLOR: - attributes: vec3 pos, vec4 color - uniforms: - + attributes: vec3 pos, vec4 color + uniforms: - 3D_SMOOTH_COLOR: - attributes: vec3 pos, vec4 color - uniforms: - + attributes: vec3 pos, vec4 color + uniforms: - + +""" -- cgit v1.2.3