@@ -15,6 +15,86 @@ use pyo3::{
1515 types:: { PyDict , PyTuple } ,
1616} ;
1717
18+ #[ pyclass( name = "BlendMode" , from_py_object) ]
19+ #[ derive( Clone ) ]
20+ pub struct PyBlendMode {
21+ pub ( crate ) blend_state : Option < bevy:: render:: render_resource:: BlendState > ,
22+ name : Option < & ' static str > ,
23+ }
24+
25+ impl PyBlendMode {
26+ pub ( crate ) fn from_preset ( mode : BlendMode ) -> Self {
27+ Self {
28+ blend_state : mode. to_blend_state ( ) ,
29+ name : Some ( mode. name ( ) ) ,
30+ }
31+ }
32+ }
33+
34+ #[ pymethods]
35+ impl PyBlendMode {
36+ #[ new]
37+ #[ pyo3( signature = ( * , color_src, color_dst, color_op, alpha_src, alpha_dst, alpha_op) ) ]
38+ fn new (
39+ color_src : u8 ,
40+ color_dst : u8 ,
41+ color_op : u8 ,
42+ alpha_src : u8 ,
43+ alpha_dst : u8 ,
44+ alpha_op : u8 ,
45+ ) -> PyResult < Self > {
46+ let blend_state = custom_blend_state (
47+ color_src, color_dst, color_op, alpha_src, alpha_dst, alpha_op,
48+ )
49+ . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) ) ?;
50+ Ok ( Self {
51+ blend_state : Some ( blend_state) ,
52+ name : None ,
53+ } )
54+ }
55+
56+ fn __repr__ ( & self ) -> String {
57+ match self . name {
58+ Some ( name) => format ! ( "BlendMode.{name}" ) ,
59+ None => "BlendMode(custom)" . to_string ( ) ,
60+ }
61+ }
62+
63+ #[ classattr]
64+ const ZERO : u8 = 0 ;
65+ #[ classattr]
66+ const ONE : u8 = 1 ;
67+ #[ classattr]
68+ const SRC_COLOR : u8 = 2 ;
69+ #[ classattr]
70+ const ONE_MINUS_SRC_COLOR : u8 = 3 ;
71+ #[ classattr]
72+ const SRC_ALPHA : u8 = 4 ;
73+ #[ classattr]
74+ const ONE_MINUS_SRC_ALPHA : u8 = 5 ;
75+ #[ classattr]
76+ const DST_COLOR : u8 = 6 ;
77+ #[ classattr]
78+ const ONE_MINUS_DST_COLOR : u8 = 7 ;
79+ #[ classattr]
80+ const DST_ALPHA : u8 = 8 ;
81+ #[ classattr]
82+ const ONE_MINUS_DST_ALPHA : u8 = 9 ;
83+ #[ classattr]
84+ const SRC_ALPHA_SATURATED : u8 = 10 ;
85+
86+ #[ classattr]
87+ const OP_ADD : u8 = 0 ;
88+ #[ classattr]
89+ const OP_SUBTRACT : u8 = 1 ;
90+ #[ classattr]
91+ const OP_REVERSE_SUBTRACT : u8 = 2 ;
92+ #[ classattr]
93+ const OP_MIN : u8 = 3 ;
94+ #[ classattr]
95+ const OP_MAX : u8 = 4 ;
96+ }
97+
1898#[ pyclass( unsendable) ]
1999pub struct Surface {
20100 pub ( crate ) entity : Entity ,
@@ -149,6 +229,12 @@ impl Geometry {
149229 geometry_vertex ( self . entity , v) . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) )
150230 }
151231
232+ #[ pyo3( signature = ( * args) ) ]
233+ pub fn uv ( & self , args : & Bound < ' _ , PyTuple > ) -> PyResult < ( ) > {
234+ let v = extract_vec2 ( args) ?;
235+ geometry_uv ( self . entity , v. x , v. y ) . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) )
236+ }
237+
152238 pub fn index ( & self , i : u32 ) -> PyResult < ( ) > {
153239 geometry_index ( self . entity , i) . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) )
154240 }
@@ -158,6 +244,10 @@ impl Geometry {
158244 let v = extract_vec3 ( args) ?;
159245 geometry_set_vertex ( self . entity , i, v) . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) )
160246 }
247+
248+ pub fn vertex_count ( & self ) -> PyResult < u32 > {
249+ geometry_vertex_count ( self . entity ) . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) )
250+ }
161251}
162252
163253#[ pyclass( unsendable) ]
@@ -837,6 +927,11 @@ impl Graphics {
837927 . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) )
838928 }
839929
930+ pub fn blend_mode ( & self , mode : & PyBlendMode ) -> PyResult < ( ) > {
931+ graphics_record_command ( self . entity , DrawCommand :: BlendMode ( mode. blend_state ) )
932+ . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) )
933+ }
934+
840935 pub fn set_material ( & self , material : & crate :: material:: Material ) -> PyResult < ( ) > {
841936 graphics_record_command ( self . entity , DrawCommand :: Material ( material. entity ) )
842937 . map_err ( |e| PyRuntimeError :: new_err ( format ! ( "{e}" ) ) )
0 commit comments