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 */ #include "gpu_py_api.h" /* own include */
PyDoc_STRVAR(GPU_doc, 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" "\n\n"
"Submodules:\n" "Submodules:\n"
"\n" "\n"

View File

@@ -743,20 +743,6 @@ PyDoc_STRVAR(bpygpu_shader_from_builtin_doc,
"\n" "\n"
"Shaders that are embedded in the blender internal code.\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" "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" "For more details, you can check the shader code with the function 'gpu.shader.code_from_builtin';\n"
"\n" "\n"
" :param shader_name: One of these builtin shader names: {\n" " :param shader_name: One of these builtin shader names: {\n"