API Docs: gpu api introduction + examples

This commit is contained in:
Jacques Lucke 2018-11-05 19:26:53 +01:00
parent abbe4df301
commit a8e9959e07
10 changed files with 281 additions and 15 deletions

View File

@ -0,0 +1,47 @@
"""
Geometry Batches
++++++++++++++++
To draw geometry using the gpu module you need to create a :class:`gpu.types.GPUBatch` object.
Batches contain a sequence of points, lines or triangles and associated geometry attributes.
A batch can be drawn multiple times, so they should be cached whenever possible.
This makes them much faster than using the legacy `glBegin` and `glEnd` method, which would recreate the geometry data every time.
Every batch has a so called `Vertex Buffer`.
It contains the attributes for every vertex.
Typical attributes are `position`, `color` and `uv`.
Which attributes the vertex buffer of a batch contains, depends on the shader that will be used to process the batch.
Shaders
+++++++
A shader is a small program that tells the GPU how to draw batch geometry.
There are a couple of built-in shaders for the most common tasks.
Built-in shaders can be accessed with :class:`gpu.shader.from_builtin`.
Every built-in shader has an identifier (e.g. `2D_UNIFORM_COLOR` and `3D_FLAT_COLOR`).
Custom shaders can be used as well.
The :class:`gpu.types.GPUShader` takes the shader code as input and compiles it.
Every shader has at least a vertex and a fragment shader.
Optionally a geometry shader can be used as well.
.. note::
A `GPUShader` is actually a `program` in OpenGL terminology.
Shaders define a set of `uniforms` and `attributes`.
**Uniforms** are properties that are constant for every vertex in a batch.
They have to be set before the batch but after the shader has been bound.
**Attributes** are properties that can be different for every vertex.
The attributes and uniforms used by built-in shaders are listed here: :class:`gpu.shader`
A batch can only be processed/drawn by a shader when it provides all the attributes that the shader specifies.
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.
"""

View File

@ -0,0 +1,19 @@
"""
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')

View File

@ -0,0 +1,44 @@
"""
Triangle with Custom Shader
---------------------------
"""
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
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()
matrix = bpy.context.region_data.perspective_matrix
shader.uniform_float("viewProjectionMatrix", matrix)
shader.uniform_float("brightness", 0.5)
batch.draw(shader)
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')

View File

@ -0,0 +1,28 @@
"""
Wireframe Cube using Index Buffer
---------------------------------
"""
import bpy
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))
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))
shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
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')

View File

@ -0,0 +1,33 @@
"""
Mesh with Random Vertex Colors
------------------------------
"""
import bpy
import gpu
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 = 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))
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():
batch.draw(shader)
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')

View File

@ -0,0 +1,24 @@
"""
2D Rectangle
------------
"""
import bpy
import gpu
from gpu_extras.batch import batch_for_shader
vertices = (
(100, 100), (300, 100),
(100, 200), (300, 200))
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)
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')

View File

@ -0,0 +1,49 @@
"""
2D Image
--------
"""
import bpy
import gpu
import bgl
from gpu_extras.batch import batch_for_shader
IMAGE_NAME = "Untitled"
image = bpy.data.images[IMAGE_NAME]
coords = [
(100, 100), (200, 100),
(100, 200), (200, 200)]
uvs = [(0, 0), (1, 0), (0, 1), (1, 1)]
indices = [(0, 1, 2), (2, 1, 3)]
shader = gpu.shader.from_builtin('2D_IMAGE')
batch = batch_for_shader(shader, 'TRIS',
{"pos" : coords,
"texCoord" : uvs},
indices=indices)
# send image to gpu if it isn't there already
if image.gl_load():
raise Exception()
# texture identifier on gpu
texture_id = image.bindcode
def draw():
# in case someone disabled it before
bgl.glEnable(bgl.GL_TEXTURE_2D)
# bind texture to image unit 0
bgl.glActiveTexture(bgl.GL_TEXTURE0)
bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture_id)
shader.bind()
# tell shader to use the image that is bound to image unit 0
shader.uniform_int("image", 0)
batch.draw(shader)
bgl.glDisable(bgl.GL_TEXTURE_2D)
bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')

View File

@ -0,0 +1,35 @@
"""
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
2D_FLAT_COLOR:
attributes: vec3 pos, vec4 color
uniforms: -
2D_SMOOTH_COLOR:
attributes: vec3 pos, vec4 color
uniforms: -
2D_IMAGE:
attributes: vec3 pos, vec2 texCoord
uniforms: sampler2D image
3D_UNIFORM_COLOR:
attributes: vec3 pos
uniforms: vec4 color
3D_FLAT_COLOR:
attributes: vec3 pos, vec4 color
uniforms: -
3D_SMOOTH_COLOR:
attributes: vec3 pos, vec4 color
uniforms: -

View File

@ -41,7 +41,8 @@
#include "gpu_py_api.h" /* own include */
PyDoc_STRVAR(GPU_doc,
"This module to provide functions concerning the GPU implementation in Blender."
"This module provides Python wrappers for the GPU implementation in Blender. "
"Some higher level functions can be found in the `gpu_extras` module. "
"\n\n"
"Submodules:\n"
"\n"

View File

@ -743,20 +743,6 @@ PyDoc_STRVAR(bpygpu_shader_from_builtin_doc,
"\n"
"Shaders that are embedded in the blender internal code.\n"
"They all read the uniform 'mat4 ModelViewProjectionMatrix', which can be edited by the 'gpu.matrix' module.\n"
" '2D_UNIFORM_COLOR' (attribute: 'vec3 pos'; uniform: 'vec4 color');\n"
"\n"
" '2D_FLAT_COLOR' (attribute: 'vec4 color', 'vec3 pos');\n"
"\n"
" '2D_SMOOTH_COLOR' (attribute: 'vec4 color', 'vec3 pos');\n"
"\n"
" '2D_IMAGE' (attribute: 'vec2 texCoord', 'vec2 pos');\n"
"\n"
" '3D_UNIFORM_COLOR' (attribute: 'vec3 pos'; uniform: 'vec4 color');\n"
"\n"
" '3D_FLAT_COLOR' (attribute: 'vec4 color', 'vec3 pos');\n"
"\n"
" '3D_SMOOTH_COLOR (attribute: 'vec4 color', 'vec3 pos');\n"
"\n"
"For more details, you can check the shader code with the function 'gpu.shader.code_from_builtin';\n"
"\n"
" :param shader_name: One of these builtin shader names: {\n"