绘图-API¶
DPG有一个低级的绘图API,非常适合于原始绘图、自定义窗口小部件甚至动态绘图。
绘图命令可以添加到DrawList、VIEPORT_DrawList或窗口等容器中。
通过调用以下方法创建一个绘图列表项 add_drawlist
然后,可以通过调用它们各自的绘制命令来添加项。图形的原点位于左上角,y轴指向下方。
坐标系是右手坐标系,x轴指向左侧,y轴指向下方,z轴指向屏幕。
Code
import dearpygui.dearpygui as dpg
dpg.create_context()
with dpg.window(label="Tutorial"):
with dpg.drawlist(width=300, height=300): # or you could use dpg.add_drawlist and set parents manually
dpg.draw_line((10, 10), (100, 100), color=(255, 0, 0, 255), thickness=1)
dpg.draw_text((0, 0), "Origin", color=(250, 250, 250, 255), size=15)
dpg.draw_arrow((50, 70), (100, 65), color=(0, 200, 255), thickness=1, size=10)
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Results
图层¶
图纸列表也可以包含层。层是对图形项进行分组以更好地控制隐藏、Z排序等的有效方法。
1.1中的新功能 。层可用于辅助执行某些3D操作。请参阅下面的“3D操作”部分。
Code
import dearpygui.dearpygui as dpg
dpg.create_context()
def toggle_layer2(sender):
show_value = dpg.get_value(sender)
dpg.configure_item("layer2", show=show_value)
with dpg.window(label="Tutorial"):
dpg.add_checkbox(label="show layer", callback=toggle_layer2, default_value=True)
with dpg.drawlist(width=300, height=300):
with dpg.draw_layer():
dpg.draw_line((10, 10), (100, 100), color=(255, 0, 0, 255), thickness=1)
dpg.draw_text((0, 0), "Origin", color=(250, 250, 250, 255), size=15)
dpg.draw_arrow((50, 70), (100, 65), color=(0, 200, 255), thickness=1, size=10)
with dpg.draw_layer(tag="layer2"):
dpg.draw_line((10, 60), (100, 160), color=(255, 0, 0, 255), thickness=1)
dpg.draw_arrow((50, 120), (100, 115), color=(0, 200, 255), thickness=1, size=10)
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
图像¶
绘图列表可以显示PNG、JPEG或BMP类型的图像(请参见 纹理和图像 以了解更多详细信息)。使用DRAW_IMAGE添加图像。
使用关键字 pmin 和 pmax 我们可以定义矩形的左上角和右下角区域,图像将绘制到画布上。图像将缩放以适合指定区域。
使用关键字 uv_min 和 uv_max 我们可以指定规格化的纹理坐标,以仅使用图像上区域的一部分。默认为uv_min= [0,0] 和UV_max= [1,1] 将在UV_MIN=时显示整个图像 [0,0] UV_max= [0.5,0.5] 将仅显示绘图的第一个四分之一。
为了能够演示这些功能,您必须将目录更新为计算机上的映像目录,例如 SpriteMapExample.png 。
Code
import dearpygui.dearpygui as dpg
dpg.create_context()
width, height, channels, data = dpg.load_image('SpriteMapExample.png') # 0: width, 1: height, 2: channels, 3: data
with dpg.texture_registry():
dpg.add_static_texture(width, height, data, tag="image_id")
with dpg.window(label="Tutorial"):
with dpg.drawlist(width=700, height=700):
dpg.draw_image("image_id", (0, 400), (200, 600), uv_min=(0, 0), uv_max=(1, 1))
dpg.draw_image("image_id", (400, 300), (600, 500), uv_min=(0, 0), uv_max=(0.5, 0.5))
dpg.draw_image("image_id", (0, 0), (300, 300), uv_min=(0, 0), uv_max=(2.5, 2.5))
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Results
视窗和视窗¶
还可以将所有相同的DRAW_*绘图命令与作为父窗口的窗口一起使用。同样,您可以使用viewport_Drawlist绘制到视区前景或背景。
Code
import dearpygui.dearpygui as dpg
dpg.create_context()
# creating font and back viewport drawlists
with dpg.viewport_drawlist():
dpg.draw_circle((100, 100), 25, color=(255, 255, 255, 255))
dpg.add_viewport_drawlist(front=False, tag="viewport_back")
dpg.draw_circle((200, 200), 25, color=(255, 255, 255, 255), parent="viewport_back")
with dpg.window(label="Tutorial", width=300, height=300):
dpg.add_text("Move the window over the drawings to see the effects.", wrap=300)
dpg.draw_circle((100, 100), 25, color=(255, 255, 255, 255))
dpg.create_viewport(title='Custom Title', width=800, height=600)
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Results
场景图¶
1.1中的新功能 。对于更复杂的绘图,您可以使用 draw_node 项目。绘制节点用于将变换矩阵与一组绘制项相关联。您可以使用 apply_transform 若要将变换矩阵应用于节点,请执行以下操作。这个矩阵将被用来乘以每个子绘图项目的点数。如果一个子节点是另一个绘制节点,则矩阵将连接在一起。
Code
import dearpygui.dearpygui as dpg
import math
dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()
with dpg.window(label="tutorial", width=550, height=550):
with dpg.drawlist(width=500, height=500):
with dpg.draw_node(tag="root node"):
dpg.draw_circle([0, 0], 150, color=[0, 255, 0]) # inner planet orbit
dpg.draw_circle([0, 0], 200, color=[0, 255, 255]) # outer planet orbit
dpg.draw_circle([0, 0], 15, color=[255, 255, 0], fill=[255, 255, 0]) # sun
with dpg.draw_node(tag="planet node 1"):
dpg.draw_circle([0, 0], 10, color=[0, 255, 0], fill=[0, 255, 0]) # inner planet
dpg.draw_circle([0, 0], 25, color=[255, 0, 255]) # moon orbit path
with dpg.draw_node(tag="planet 1, moon node"):
dpg.draw_circle([0, 0], 5, color=[255, 0, 255], fill=[255, 0, 255]) # moon
with dpg.draw_node(tag="planet node 2"):
dpg.draw_circle([0, 0], 10, color=[0, 255, 255], fill=[0, 255, 255]) # outer planet
dpg.draw_circle([0, 0], 25, color=[255, 0, 255]) # moon 1 orbit path
dpg.draw_circle([0, 0], 45, color=[255, 255, 255]) # moon 2 orbit path
with dpg.draw_node(tag="planet 2, moon 1 node"):
dpg.draw_circle([0, 0], 5, color=[255, 0, 255], fill=[255, 0, 255]) # moon 1
with dpg.draw_node(tag="planet 2, moon 2 node"):
dpg.draw_circle([0, 0], 5, color=[255, 255, 255], fill=[255, 255, 255]) # moon 2
planet1_distance = 150
planet1_angle = 45.0
planet1_moondistance = 25
planet1_moonangle = 45
planet2_distance = 200
planet2_angle = 0.0
planet2_moon1distance = 25
planet2_moon1angle = 45
planet2_moon2distance = 45
planet2_moon2angle = 120
dpg.apply_transform("root node", dpg.create_translation_matrix([250, 250]))
dpg.apply_transform("planet node 1", dpg.create_rotation_matrix(math.pi*planet1_angle/180.0 , [0, 0, -1])*dpg.create_translation_matrix([planet1_distance, 0]))
dpg.apply_transform("planet 1, moon node", dpg.create_rotation_matrix(math.pi*planet1_moonangle/180.0 , [0, 0, -1])*dpg.create_translation_matrix([planet1_moondistance, 0]))
dpg.apply_transform("planet node 2", dpg.create_rotation_matrix(math.pi*planet2_angle/180.0 , [0, 0, -1])*dpg.create_translation_matrix([planet2_distance, 0]))
dpg.apply_transform("planet 2, moon 1 node", dpg.create_rotation_matrix(math.pi*planet2_moon1distance/180.0 , [0, 0, -1])*dpg.create_translation_matrix([planet2_moon1distance, 0]))
dpg.apply_transform("planet 2, moon 2 node", dpg.create_rotation_matrix(math.pi*planet2_moon2angle/180.0 , [0, 0, -1])*dpg.create_translation_matrix([planet2_moon2distance, 0]))
dpg.show_viewport()
while dpg.is_dearpygui_running():
dpg.render_dearpygui_frame()
dpg.destroy_context()
3D操作¶
1.1中的新功能 。版本 1.1 向层添加了3个新选项, perspective_divide , depth_clipping ,以及 cull_mode 。
当透视分割设置为 True ,每个点的x、y和z分量除以变换后的w分量。
当深度剪裁设置为 True ,当点在使用以下设置的剪辑空间集之外时将被剪裁 set_clip_space 。设置剪辑空间将缩放和变换点。缩放基于规格化坐标(使用透视矩阵或地形图矩阵)。
消隐模式用于激活正面/背面消隐。
矩阵是列主数。后乘法用于缩放,然后旋转,然后使用变换:Transform=Translate 旋转 比例。
提供以下矩阵帮助器函数: create_rotation_matrix - create_translation_matrix - create_scale_matrix - create_lookat_matrix - create_perspective_matrix - create_orthographic_matrix - create_fps_matrix
Code
import dearpygui.dearpygui as dpg
import math
dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()
size = 5
verticies = [
[-size, -size, -size], # 0 near side
[ size, -size, -size], # 1
[-size, size, -size], # 2
[ size, size, -size], # 3
[-size, -size, size], # 4 far side
[ size, -size, size], # 5
[-size, size, size], # 6
[ size, size, size], # 7
[-size, -size, -size], # 8 left side
[-size, size, -size], # 9
[-size, -size, size], # 10
[-size, size, size], # 11
[ size, -size, -size], # 12 right side
[ size, size, -size], # 13
[ size, -size, size], # 14
[ size, size, size], # 15
[-size, -size, -size], # 16 bottom side
[ size, -size, -size], # 17
[-size, -size, size], # 18
[ size, -size, size], # 19
[-size, size, -size], # 20 top side
[ size, size, -size], # 21
[-size, size, size], # 22
[ size, size, size], # 23
]
colors = [
[255, 0, 0, 150],
[255, 255, 0, 150],
[255, 255, 255, 150],
[255, 0, 255, 150],
[ 0, 255, 0, 150],
[ 0, 255, 255, 150],
[ 0, 0, 255, 150],
[ 0, 125, 0, 150],
[128, 0, 0, 150],
[128, 70, 0, 150],
[128, 255, 255, 150],
[128, 0, 128, 150]
]
with dpg.window(label="tutorial", width=550, height=550):
with dpg.drawlist(width=500, height=500):
with dpg.draw_layer(tag="main pass", depth_clipping=True, perspective_divide=True, cull_mode=dpg.mvCullMode_Back):
with dpg.draw_node(tag="cube"):
dpg.draw_triangle(verticies[1], verticies[2], verticies[0], color=[0,0,0.0], fill=colors[0])
dpg.draw_triangle(verticies[1], verticies[3], verticies[2], color=[0,0,0.0], fill=colors[1])
dpg.draw_triangle(verticies[7], verticies[5], verticies[4], color=[0,0,0.0], fill=colors[2])
dpg.draw_triangle(verticies[6], verticies[7], verticies[4], color=[0,0,0.0], fill=colors[3])
dpg.draw_triangle(verticies[9], verticies[10], verticies[8], color=[0,0,0.0], fill=colors[4])
dpg.draw_triangle(verticies[9], verticies[11], verticies[10], color=[0,0,0.0], fill=colors[5])
dpg.draw_triangle(verticies[15], verticies[13], verticies[12], color=[0,0,0.0], fill=colors[6])
dpg.draw_triangle(verticies[14], verticies[15], verticies[12], color=[0,0,0.0], fill=colors[7])
dpg.draw_triangle(verticies[18], verticies[17], verticies[16], color=[0,0,0.0], fill=colors[8])
dpg.draw_triangle(verticies[19], verticies[17], verticies[18], color=[0,0,0.0], fill=colors[9])
dpg.draw_triangle(verticies[21], verticies[23], verticies[20], color=[0,0,0.0], fill=colors[10])
dpg.draw_triangle(verticies[23], verticies[22], verticies[20], color=[0,0,0.0], fill=colors[11])
x_rot = 10
y_rot = 45
z_rot = 0
view = dpg.create_fps_matrix([0, 0, 50], 0.0, 0.0)
proj = dpg.create_perspective_matrix(math.pi*45.0/180.0, 1.0, 0.1, 100)
model = dpg.create_rotation_matrix(math.pi*x_rot/180.0 , [1, 0, 0])*\
dpg.create_rotation_matrix(math.pi*y_rot/180.0 , [0, 1, 0])*\
dpg.create_rotation_matrix(math.pi*z_rot/180.0 , [0, 0, 1])
dpg.set_clip_space("main pass", 0, 0, 500, 500, -1.0, 1.0)
dpg.apply_transform("cube", proj*view*model)
dpg.show_viewport()
while dpg.is_dearpygui_running():
dpg.render_dearpygui_frame()
dpg.destroy_context()
3D操作限制¶
1.1中的新功能 。绘图API 3D操作不是硬件加速的(这将在DearPy3D中引入)。这个API是针对‘light’3D操作的。在使用绘图API执行3D操作时,可能会遇到一些问题。
问题1:Z订购
在当前的API中,用户需要负责正确的Z排序。解决这个问题的推荐方法是使用“画家算法”。基本上,只需按适当的深度顺序对物品进行排序即可。
总的来说,这不是最好的解决方案。我们更喜欢使用适当的深度缓冲,但这需要像素级别的控制,这在此API中是不实用的。
第2期:透视纹理校正
使用DRAW_IMAGE_QUAD时,以锐角查看图像将使图像变形。这是因为纹理坐标在规格化设备坐标空间中线性内插。
目前还没有实际的解决方案,但可以尝试将四合院分成几个较小的四合院。实际的解决方案需要像素级控制,这在此API中是不实用的。
问题3:剔除
目前,仅为三角形设置消隐。
亲爱的Py3D和软件渲染器
上述所有问题都将在 亲爱的Py3D 。在此之前 亲爱的Py3D ,我们还将介绍一个软件渲染器, 亲爱的皮吉 这将解决上述问题。