Cleanup: gpu docs
This commit is contained in:
parent
5f21030a81
commit
3c8c976086
|
@ -4,7 +4,8 @@ Geometry Batches
|
||||||
|
|
||||||
Geometry is drawn in batches.
|
Geometry is drawn in batches.
|
||||||
A batch contains the necessary data to perform the drawing.
|
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.
|
A batch also defines a draw type.
|
||||||
Typical draw types are `POINTS`, `LINES` and `TRIS`.
|
Typical draw types are `POINTS`, `LINES` and `TRIS`.
|
||||||
The draw type determines how the data will be interpreted and drawn.
|
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
|
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*.
|
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.
|
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.
|
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
|
.. code-block:: python
|
||||||
vertex_positions = [(0, 0, 0), ...]
|
|
||||||
vertex_normals = [(0, 0, 1), ...]
|
|
||||||
|
|
||||||
fmt = gpu.types.GPUVertFormat()
|
import gpu
|
||||||
fmt.attr_add(id="pos", comp_type='F32', len=3, fetch_mode='FLOAT')
|
vertex_positions = [(0, 0, 0), ...]
|
||||||
fmt.attr_add(id="normal", comp_type='F32', len=3, fetch_mode='FLOAT')
|
vertex_normals = [(0, 0, 1), ...]
|
||||||
|
|
||||||
vbo = gpu.types.GPUVertBuf(len=6, format=fmt)
|
fmt = gpu.types.GPUVertFormat()
|
||||||
vbo.attr_fill(id="pos", data=vertex_positions)
|
fmt.attr_add(id="pos", comp_type='F32', len=3, fetch_mode='FLOAT')
|
||||||
vbo.attr_fill(id="normal", data=vertex_normals)
|
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, ...
|
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.
|
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.
|
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.
|
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.
|
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.
|
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 = (
|
For instance, to draw a rectangle composed of two triangles, one could use an index buffer.
|
||||||
(-1, 1), (1, 1),
|
|
||||||
(-1, -1), (1, -1))
|
|
||||||
|
|
||||||
indices = ((0, 1, 2), (2, 1, 3))
|
.. code-block:: python
|
||||||
|
|
||||||
ibo = gpu.types.GPUIndexBuf(type='TRIS', seq=indices)
|
positions = (
|
||||||
|
(-1, 1), (1, 1),
|
||||||
|
(-1, -1), (1, -1))
|
||||||
|
|
||||||
Here the first tuple in `indices` describes which vertices should be used for the first triangle (same for the second tuple).
|
indices = ((0, 1, 2), (2, 1, 3))
|
||||||
|
|
||||||
|
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).
|
||||||
Note how the diagonal vertices 1 and 2 are shared between both triangles.
|
Note how the diagonal vertices 1 and 2 are shared between both triangles.
|
||||||
|
|
||||||
Shaders
|
Shaders
|
||||||
|
@ -66,7 +76,8 @@ The most important ones are *Vertex Shaders* and *Fragment Shaders*.
|
||||||
Typically multiple shaders are linked together into a *Program*.
|
Typically multiple shaders are linked together into a *Program*.
|
||||||
However, in the Blender Python API the term *Shader* refers to an OpenGL 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.
|
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.
|
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.
|
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*.
|
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.
|
When draw calls are issued, batches are drawn on a *Back Buffer* that will only be displayed
|
||||||
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 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.
|
This is called Offscreen Rendering.
|
||||||
In Blender Offscreen Rendering is done using the :class:`gpu.types.GPUOffScreen` type.
|
In Blender Offscreen Rendering is done using the :class:`gpu.types.GPUOffScreen` type.
|
||||||
|
|
||||||
.. warning::
|
.. 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
|
Examples
|
||||||
++++++++
|
++++++++
|
||||||
|
@ -104,4 +119,4 @@ Examples
|
||||||
To try these examples, just copy them into Blenders text editor and execute them.
|
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.
|
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.
|
Blender has to be restarted in order to delete the draw handlers.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -3,7 +3,8 @@ Rendering the 3D View into a Texture
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
The scene has to have a camera for this example to work.
|
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 bpy
|
||||||
import bgl
|
import bgl
|
||||||
|
@ -15,6 +16,7 @@ HEIGHT = 256
|
||||||
|
|
||||||
offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)
|
offscreen = gpu.types.GPUOffScreen(WIDTH, HEIGHT)
|
||||||
|
|
||||||
|
|
||||||
def draw():
|
def draw():
|
||||||
context = bpy.context
|
context = bpy.context
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
|
@ -35,4 +37,5 @@ def draw():
|
||||||
bgl.glDisable(bgl.GL_DEPTH_TEST)
|
bgl.glDisable(bgl.GL_DEPTH_TEST)
|
||||||
draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT)
|
draw_texture_2d(offscreen.color_texture, (10, 10), WIDTH, HEIGHT)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
|
||||||
|
|
|
@ -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.
|
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.
|
Between the vertex and fragment shader that value is automatically interpolated
|
||||||
In the fragment shader the `sin` of the arc length is calculated.
|
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.
|
Based on the result a decision is made on whether the fragment should be drawn or not.
|
||||||
"""
|
"""
|
||||||
import bpy
|
import bpy
|
||||||
|
@ -47,9 +48,11 @@ for a, b in zip(coords[:-1], coords[1:]):
|
||||||
arc_lengths.append(arc_lengths[-1] + (a - b).length)
|
arc_lengths.append(arc_lengths[-1] + (a - b).length)
|
||||||
|
|
||||||
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||||
batch = batch_for_shader(shader, 'LINE_STRIP',
|
batch = batch_for_shader(
|
||||||
{"position" : coords,
|
shader, 'LINE_STRIP',
|
||||||
"arcLength" : arc_lengths})
|
{"position": coords, "arcLength": arc_lengths},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw():
|
def draw():
|
||||||
shader.bind()
|
shader.bind()
|
||||||
|
@ -58,4 +61,5 @@ def draw():
|
||||||
shader.uniform_float("u_Scale", 10)
|
shader.uniform_float("u_Scale", 10)
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||||
|
|
|
@ -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)]
|
coords = [(1, 1, 1), (-2, 0, 0), (-2, -1, 3), (0, 1, 1)]
|
||||||
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
|
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():
|
def draw():
|
||||||
shader.bind()
|
shader.bind()
|
||||||
shader.uniform_float("color", (1, 1, 0, 1))
|
shader.uniform_float("color", (1, 1, 0, 1))
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
|
||||||
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||||
|
|
|
@ -32,7 +32,8 @@ fragment_shader = '''
|
||||||
|
|
||||||
coords = [(1, 1, 1), (2, 0, 0), (-2, -1, 3)]
|
coords = [(1, 1, 1), (2, 0, 0), (-2, -1, 3)]
|
||||||
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
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():
|
def draw():
|
||||||
shader.bind()
|
shader.bind()
|
||||||
|
@ -41,4 +42,5 @@ def draw():
|
||||||
shader.uniform_float("brightness", 0.5)
|
shader.uniform_float("brightness", 0.5)
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||||
|
|
|
@ -7,10 +7,10 @@ import gpu
|
||||||
from gpu_extras.batch import batch_for_shader
|
from gpu_extras.batch import batch_for_shader
|
||||||
|
|
||||||
coords = (
|
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 = (
|
indices = (
|
||||||
(0, 1), (0, 2), (1, 3), (2, 3),
|
(0, 1), (0, 2), (1, 3), (2, 3),
|
||||||
|
@ -18,11 +18,13 @@ indices = (
|
||||||
(0, 4), (1, 5), (2, 6), (3, 7))
|
(0, 4), (1, 5), (2, 6), (3, 7))
|
||||||
|
|
||||||
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
|
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():
|
def draw():
|
||||||
shader.bind()
|
shader.bind()
|
||||||
shader.uniform_float("color", (1, 0, 0, 1))
|
shader.uniform_float("color", (1, 0, 0, 1))
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||||
|
|
|
@ -14,20 +14,23 @@ mesh.calc_loop_triangles()
|
||||||
vertices = np.empty((len(mesh.vertices), 3), 'f')
|
vertices = np.empty((len(mesh.vertices), 3), 'f')
|
||||||
indices = np.empty((len(mesh.loop_triangles), 3), 'i')
|
indices = np.empty((len(mesh.loop_triangles), 3), 'i')
|
||||||
|
|
||||||
mesh.vertices.foreach_get("co",
|
mesh.vertices.foreach_get(
|
||||||
np.reshape(vertices, len(mesh.vertices) * 3))
|
"co", np.reshape(vertices, len(mesh.vertices) * 3))
|
||||||
mesh.loop_triangles.foreach_get("vertices",
|
mesh.loop_triangles.foreach_get(
|
||||||
np.reshape(indices, len(mesh.loop_triangles) * 3))
|
"vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
|
||||||
|
|
||||||
vertex_colors = [(random(), random(), random(), 1) for _ in range(len(mesh.vertices))]
|
vertex_colors = [(random(), random(), random(), 1) for _ in range(len(mesh.vertices))]
|
||||||
|
|
||||||
shader = gpu.shader.from_builtin('3D_SMOOTH_COLOR')
|
shader = gpu.shader.from_builtin('3D_SMOOTH_COLOR')
|
||||||
batch = batch_for_shader(shader, 'TRIS',
|
batch = batch_for_shader(
|
||||||
{"pos" : vertices,
|
shader, 'TRIS',
|
||||||
"color" : vertex_colors},
|
{"pos": vertices, "color": vertex_colors},
|
||||||
indices=indices)
|
indices=indices,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw():
|
def draw():
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||||
|
|
|
@ -14,11 +14,13 @@ indices = (
|
||||||
(0, 1, 2), (2, 1, 3))
|
(0, 1, 2), (2, 1, 3))
|
||||||
|
|
||||||
shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
|
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():
|
def draw():
|
||||||
shader.bind()
|
shader.bind()
|
||||||
shader.uniform_float("color", (0, 0.5, 0.5, 1.0))
|
shader.uniform_float("color", (0, 0.5, 0.5, 1.0))
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
|
||||||
|
|
|
@ -13,13 +13,18 @@ IMAGE_NAME = "Untitled"
|
||||||
image = bpy.data.images[IMAGE_NAME]
|
image = bpy.data.images[IMAGE_NAME]
|
||||||
|
|
||||||
shader = gpu.shader.from_builtin('2D_IMAGE')
|
shader = gpu.shader.from_builtin('2D_IMAGE')
|
||||||
batch = batch_for_shader(shader, 'TRI_FAN',
|
batch = batch_for_shader(
|
||||||
{"pos" : ((100, 100), (200, 100), (200, 200), (100, 200)),
|
shader, 'TRI_FAN',
|
||||||
"texCoord" : ((0, 0), (1, 0), (1, 1), (0, 1))})
|
{
|
||||||
|
"pos": ((100, 100), (200, 100), (200, 200), (100, 200)),
|
||||||
|
"texCoord": ((0, 0), (1, 0), (1, 1), (0, 1)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
if image.gl_load():
|
if image.gl_load():
|
||||||
raise Exception()
|
raise Exception()
|
||||||
|
|
||||||
|
|
||||||
def draw():
|
def draw():
|
||||||
bgl.glActiveTexture(bgl.GL_TEXTURE0)
|
bgl.glActiveTexture(bgl.GL_TEXTURE0)
|
||||||
bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)
|
bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode)
|
||||||
|
@ -28,4 +33,5 @@ def draw():
|
||||||
shader.uniform_int("image", 0)
|
shader.uniform_int("image", 0)
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
Generate a texture using Offscreen Rendering
|
Generate a texture using Offscreen Rendering
|
||||||
--------------------------------------------
|
--------------------------------------------
|
||||||
|
|
||||||
1. Create an :class:`gpu.types.GPUOffScreen` object.
|
#. Create an :class:`gpu.types.GPUOffScreen` object.
|
||||||
2. Draw some circles into it.
|
#. Draw some circles into it.
|
||||||
3. Make a new shader for drawing a planar texture in 3D.
|
#. Make a new shader for drawing a planar texture in 3D.
|
||||||
4. Draw the generated texture using the new shader.
|
#. Draw the generated texture using the new shader.
|
||||||
"""
|
"""
|
||||||
import bpy
|
import bpy
|
||||||
import gpu
|
import gpu
|
||||||
|
@ -63,9 +63,13 @@ fragment_shader = '''
|
||||||
'''
|
'''
|
||||||
|
|
||||||
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||||
batch = batch_for_shader(shader, 'TRI_FAN',
|
batch = batch_for_shader(
|
||||||
{"position" : ((-1, -1), (1, -1), (1, 1), (-1, 1)),
|
shader, 'TRI_FAN',
|
||||||
"uv" : ((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)),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def draw():
|
def draw():
|
||||||
|
@ -78,4 +82,5 @@ def draw():
|
||||||
shader.uniform_float("image", 0)
|
shader.uniform_float("image", 0)
|
||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
|
||||||
|
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||||
|
|
|
@ -6,7 +6,8 @@ This will create a new image with the given name.
|
||||||
If it already exists, it will override the existing one.
|
If it already exists, it will override the existing one.
|
||||||
|
|
||||||
Currently almost all of the execution time is spent in the last line.
|
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 bpy
|
||||||
import gpu
|
import gpu
|
||||||
|
@ -35,7 +36,6 @@ with offscreen.bind():
|
||||||
(random.uniform(-1, 1), random.uniform(-1, 1)),
|
(random.uniform(-1, 1), random.uniform(-1, 1)),
|
||||||
(1, 1, 1, 1), random.uniform(0.1, 1), 20)
|
(1, 1, 1, 1), random.uniform(0.1, 1), 20)
|
||||||
|
|
||||||
|
|
||||||
buffer = bgl.Buffer(bgl.GL_BYTE, WIDTH * HEIGHT * 4)
|
buffer = bgl.Buffer(bgl.GL_BYTE, WIDTH * HEIGHT * 4)
|
||||||
bgl.glReadBuffer(bgl.GL_BACK)
|
bgl.glReadBuffer(bgl.GL_BACK)
|
||||||
bgl.glReadPixels(0, 0, WIDTH, HEIGHT, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer)
|
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)
|
bpy.data.images.new(IMAGE_NAME, WIDTH, HEIGHT)
|
||||||
image = bpy.data.images[IMAGE_NAME]
|
image = bpy.data.images[IMAGE_NAME]
|
||||||
image.scale(WIDTH, HEIGHT)
|
image.scale(WIDTH, HEIGHT)
|
||||||
image.pixels = [v / 255 for v in buffer]
|
image.pixels = [v / 255 for v in buffer]
|
||||||
|
|
|
@ -4,32 +4,33 @@ Built-in shaders
|
||||||
|
|
||||||
All built-in shaders have the ``mat4 ModelViewProjectionMatrix`` uniform.
|
All built-in shaders have the ``mat4 ModelViewProjectionMatrix`` uniform.
|
||||||
The value of it can only be modified using the :class:`gpu.matrix` module.
|
The value of it can only be modified using the :class:`gpu.matrix` module.
|
||||||
"""
|
|
||||||
|
|
||||||
2D_UNIFORM_COLOR:
|
2D_UNIFORM_COLOR:
|
||||||
attributes: vec3 pos
|
attributes: vec3 pos
|
||||||
uniforms: vec4 color
|
uniforms: vec4 color
|
||||||
|
|
||||||
2D_FLAT_COLOR:
|
2D_FLAT_COLOR:
|
||||||
attributes: vec3 pos, vec4 color
|
attributes: vec3 pos, vec4 color
|
||||||
uniforms: -
|
uniforms: -
|
||||||
|
|
||||||
2D_SMOOTH_COLOR:
|
2D_SMOOTH_COLOR:
|
||||||
attributes: vec3 pos, vec4 color
|
attributes: vec3 pos, vec4 color
|
||||||
uniforms: -
|
uniforms: -
|
||||||
|
|
||||||
2D_IMAGE:
|
2D_IMAGE:
|
||||||
attributes: vec3 pos, vec2 texCoord
|
attributes: vec3 pos, vec2 texCoord
|
||||||
uniforms: sampler2D image
|
uniforms: sampler2D image
|
||||||
|
|
||||||
3D_UNIFORM_COLOR:
|
3D_UNIFORM_COLOR:
|
||||||
attributes: vec3 pos
|
attributes: vec3 pos
|
||||||
uniforms: vec4 color
|
uniforms: vec4 color
|
||||||
|
|
||||||
3D_FLAT_COLOR:
|
3D_FLAT_COLOR:
|
||||||
attributes: vec3 pos, vec4 color
|
attributes: vec3 pos, vec4 color
|
||||||
uniforms: -
|
uniforms: -
|
||||||
|
|
||||||
3D_SMOOTH_COLOR:
|
3D_SMOOTH_COLOR:
|
||||||
attributes: vec3 pos, vec4 color
|
attributes: vec3 pos, vec4 color
|
||||||
uniforms: -
|
uniforms: -
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
Loading…
Reference in New Issue