2019-01-02 17:07:58 +01:00
|
|
|
"""OpenGL drawing code for the texture browser.
|
|
|
|
|
|
|
|
Requires Blender 2.80 or newer.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import typing
|
|
|
|
|
|
|
|
import bgl
|
|
|
|
import blf
|
|
|
|
import bpy
|
|
|
|
import gpu
|
|
|
|
from gpu_extras.batch import batch_for_shader
|
|
|
|
|
2019-01-04 16:25:50 +01:00
|
|
|
if bpy.app.background:
|
|
|
|
shader = None
|
|
|
|
texture_shader = None
|
|
|
|
else:
|
|
|
|
shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
|
|
|
|
texture_shader = gpu.shader.from_builtin('2D_IMAGE')
|
2019-01-02 17:07:58 +01:00
|
|
|
|
|
|
|
Float2 = typing.Tuple[float, float]
|
|
|
|
Float3 = typing.Tuple[float, float, float]
|
|
|
|
Float4 = typing.Tuple[float, float, float, float]
|
|
|
|
|
|
|
|
|
|
|
|
def text(pos2d: Float2, display_text: typing.Union[str, typing.List[str]],
|
|
|
|
rgba: Float4 = (1.0, 1.0, 1.0, 1.0),
|
|
|
|
fsize=12,
|
|
|
|
align='L'):
|
|
|
|
"""Draw text with the top-left corner at 'pos2d'."""
|
|
|
|
|
|
|
|
dpi = bpy.context.preferences.system.dpi
|
|
|
|
gap = 12
|
|
|
|
x_pos, y_pos = pos2d
|
|
|
|
font_id = 0
|
|
|
|
blf.size(font_id, fsize, dpi)
|
|
|
|
|
|
|
|
# Compute the height of one line.
|
|
|
|
mwidth, mheight = blf.dimensions(font_id, "Tp") # Use high and low letters.
|
|
|
|
mheight *= 1.5
|
|
|
|
|
|
|
|
# Split text into lines.
|
|
|
|
if isinstance(display_text, str):
|
|
|
|
mylines = display_text.split("\n")
|
|
|
|
else:
|
|
|
|
mylines = display_text
|
|
|
|
maxwidth = 0
|
|
|
|
maxheight = len(mylines) * mheight
|
|
|
|
|
|
|
|
for idx, line in enumerate(mylines):
|
|
|
|
text_width, text_height = blf.dimensions(font_id, line)
|
|
|
|
if align == 'C':
|
|
|
|
newx = x_pos - text_width / 2
|
|
|
|
elif align == 'R':
|
|
|
|
newx = x_pos - text_width - gap
|
|
|
|
else:
|
|
|
|
newx = x_pos
|
|
|
|
|
|
|
|
# Draw
|
|
|
|
blf.position(font_id, newx, y_pos - mheight * idx, 0)
|
|
|
|
blf.color(font_id, rgba[0], rgba[1], rgba[2], rgba[3])
|
|
|
|
blf.draw(font_id, " " + line)
|
|
|
|
|
|
|
|
# saves max width
|
|
|
|
if maxwidth < text_width:
|
|
|
|
maxwidth = text_width
|
|
|
|
|
|
|
|
return maxwidth, maxheight
|
|
|
|
|
|
|
|
|
|
|
|
def aabox(v1: Float2, v2: Float2, rgba: Float4):
|
|
|
|
"""Draw an axis-aligned box."""
|
|
|
|
coords = [
|
|
|
|
(v1[0], v1[1]),
|
|
|
|
(v1[0], v2[1]),
|
|
|
|
(v2[0], v2[1]),
|
|
|
|
(v2[0], v1[1]),
|
|
|
|
]
|
|
|
|
shader.bind()
|
|
|
|
shader.uniform_float("color", rgba)
|
|
|
|
|
|
|
|
batch = batch_for_shader(shader, 'TRI_FAN', {"pos": coords})
|
|
|
|
batch.draw(shader)
|
|
|
|
|
|
|
|
|
|
|
|
def aabox_with_texture(v1: Float2, v2: Float2):
|
|
|
|
"""Draw an axis-aligned box with a texture."""
|
|
|
|
coords = [
|
|
|
|
(v1[0], v1[1]),
|
|
|
|
(v1[0], v2[1]),
|
|
|
|
(v2[0], v2[1]),
|
|
|
|
(v2[0], v1[1]),
|
|
|
|
]
|
|
|
|
texture_shader.bind()
|
|
|
|
texture_shader.uniform_int("image", 0)
|
|
|
|
|
|
|
|
batch = batch_for_shader(texture_shader, 'TRI_FAN', {
|
|
|
|
"pos": coords,
|
|
|
|
"texCoord": ((0, 0), (0, 1), (1, 1), (1, 0)),
|
|
|
|
})
|
|
|
|
batch.draw(texture_shader)
|
|
|
|
|
|
|
|
|
|
|
|
def bind_texture(texture: bpy.types.Image):
|
|
|
|
"""Bind a Blender image to a GL texture slot."""
|
|
|
|
bgl.glActiveTexture(bgl.GL_TEXTURE0)
|
|
|
|
bgl.glBindTexture(bgl.GL_TEXTURE_2D, texture.bindcode)
|