Add Chromium-only Blender WebEngine parity work
This commit is contained in:
187
blender-5.2.0/doc/python_api/examples/gpu.1.py
Normal file
187
blender-5.2.0/doc/python_api/examples/gpu.1.py
Normal file
@@ -0,0 +1,187 @@
|
||||
"""
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import gpu
|
||||
vertex_positions = [(0, 0, 0), ...]
|
||||
vertex_normals = [(0, 0, 1), ...]
|
||||
|
||||
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.
|
||||
The type that will actually be drawn is determined when the batch is created later.
|
||||
|
||||
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*.
|
||||
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.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
positions = (
|
||||
(-1, 1), (1, 1),
|
||||
(-1, -1), (1, -1))
|
||||
|
||||
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.
|
||||
|
||||
Shaders
|
||||
+++++++
|
||||
|
||||
A shader is a program that runs on the GPU (written in GLSL in our case).
|
||||
There are multiple types of shaders.
|
||||
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 ``UNIFORM_COLOR`` or ``FLAT_COLOR``. There are specific builtin shaders for
|
||||
drawing triangles, lines and points.
|
||||
|
||||
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.
|
||||
Uniforms are properties that are constant per draw call.
|
||||
They can be set using the ``shader.uniform_*`` functions after the shader has been bound.
|
||||
|
||||
.. note::
|
||||
|
||||
It is important to note that GLSL sources are reinterpreted to MSL (Metal Shading Language)
|
||||
on Apple operating systems.
|
||||
This uses a small compatibility layer that does not cover the whole GLSL language specification.
|
||||
Here is a list of differences to keep in mind when targeting compatibility with Apple platforms:
|
||||
|
||||
- The only matrix constructors available are:
|
||||
|
||||
- diagonal scalar (example: ``mat2(1)``)
|
||||
- all scalars (example: ``mat2(1, 0, 0, 1)``)
|
||||
- column vector (example: ``mat2(vec2(1,0), vec2(0,1))``)
|
||||
- reshape constructors work only for square matrices (example: ``mat3(mat4(1))``)
|
||||
|
||||
- ``vertex``, ``fragment`` and ``kernel`` are reserved keywords.
|
||||
- all types and keywords defined by the
|
||||
`MSL specification <https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf>`__
|
||||
are reserved keywords and should not be used.
|
||||
|
||||
|
||||
Batch Creation
|
||||
++++++++++++++
|
||||
|
||||
Batches can be created by first manually creating VBOs and IBOs.
|
||||
However, it is recommended to use the :class:`gpu_extras.batch.batch_for_shader` function.
|
||||
It makes sure that all the vertex attributes necessary for a specific shader are provided.
|
||||
Consequently, the shader has to be passed to the function as well.
|
||||
When using this function one rarely has to care about the vertex format, VBOs and IBOs created in the background.
|
||||
This is still something one should know when drawing stuff though.
|
||||
|
||||
Since batches can be drawn multiple times, they should be cached and reused whenever possible.
|
||||
|
||||
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.
|
||||
This is called Offscreen Rendering.
|
||||
In Blender Offscreen Rendering is done using the :class:`gpu.types.GPUOffScreen` type.
|
||||
|
||||
.. warning::
|
||||
|
||||
:class:`gpu.types.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
|
||||
++++++++
|
||||
|
||||
To try these examples, just copy them into Blender's 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 Points 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('POINT_UNIFORM_COLOR')
|
||||
batch = batch_for_shader(shader, 'POINTS', {"pos": coords})
|
||||
|
||||
|
||||
def draw():
|
||||
shader.uniform_float("color", (1, 1, 0, 1))
|
||||
gpu.state.point_size_set(4.5)
|
||||
batch.draw(shader)
|
||||
|
||||
|
||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||
|
||||
|
||||
"""
|
||||
|
||||
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('POLYLINE_UNIFORM_COLOR')
|
||||
batch = batch_for_shader(shader, 'LINES', {"pos": coords})
|
||||
|
||||
|
||||
def draw():
|
||||
shader.uniform_float("viewportSize", gpu.state.viewport_get()[2:])
|
||||
shader.uniform_float("lineWidth", 4.5)
|
||||
shader.uniform_float("color", (1, 1, 0, 1))
|
||||
batch.draw(shader)
|
||||
|
||||
|
||||
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
|
||||
Reference in New Issue
Block a user