1+ import os
2+ from pathlib import Path
3+
4+ # core
5+ import pilotlight .pilotlight as pl
6+ from pilotlight .pilotlight import *
7+ from pilotlight .imgui import *
8+ from pilotlight .enums import *
9+ from pilotlight .types import *
10+
11+ class App :
12+ """
13+ Simple Pilot Light Python example showing how to:
14+ - create a window
15+ - initialize the starter/shader systems
16+ - draw basic 2D primitives every frame
17+ - organize drawing code in a readable way
18+ """
19+
20+ def __init__ (self ):
21+ self .ptWindow = None
22+ self .ptFont = None
23+
24+ # -------------------------------------------------------------------------
25+ # Application lifetime
26+ # -------------------------------------------------------------------------
27+
28+ def pl_app_load (self ):
29+ """
30+ Called once when the app starts.
31+ Set up virtual file system mounts, create a window, and initialize
32+ the Pilot Light systems we want to use.
33+ """
34+
35+ # Mount directories used by the shader system.
36+ # /shaders points at the Python package shader folder.
37+ # /shader-temp is where compiled/intermediate shader output can go.
38+ plVfsI .mount_directory ("/cache" , str (Path .cwd ()) + "/../cache" )
39+ plVfsI .mount_directory ("/shaders" , os .path .dirname (os .path .abspath (pl .__file__ )) + "/shaders" )
40+ plVfsI .mount_directory ("/shader-temp" , str (Path .cwd ()) + "/../shader-temp" )
41+ plVfsI .mount_directory ("/assets" , str (Path .cwd ()) + "/../../pilotlight/assets" )
42+
43+ # Create and show the OS window.
44+ window_desc = plWindowDesc ()
45+ window_desc .pcTitle = "Pilot Light Python - Basic Example 0"
46+ window_desc .iXPos = 100
47+ window_desc .iYPos = 100
48+ window_desc .uWidth = 1280
49+ window_desc .uHeight = 720
50+ _ , self .ptWindow = plWindowI .create (window_desc )
51+ plWindowI .show (self .ptWindow )
52+
53+ # Initialize the starter extension.
54+ # We explicitly disable the shader ext from the starter flags because
55+ # we are going to initialize the shader system ourselves below.
56+ starter_flags = plStarterFlag .PL_STARTER_FLAGS_ALL_EXTENSIONS
57+ starter_flags &= ~ plStarterFlag .PL_STARTER_FLAGS_SHADER_EXT
58+ starter_flags |= plStarterFlag .PL_STARTER_FLAGS_MSAA
59+
60+ plStarterI .initialize (self .ptWindow , starter_flags )
61+
62+ # Initialize shader system.
63+ # This is required even for simple drawing examples because the
64+ # rendering path may still rely on shader compilation/setup.
65+ shader_options = plShaderOptions ()
66+ shader_options .pcCacheOutputDirectory = "/shader-temp/"
67+ shader_options .apcDirectories = ["/shaders/" ]
68+ shader_options .apcIncludeDirectories = ["/shaders/" ]
69+ shader_options .tFlags = (
70+ plShaderFlags .PL_SHADER_FLAGS_AUTO_OUTPUT
71+ | plShaderFlags .PL_SHADER_FLAGS_INCLUDE_DEBUG
72+ | plShaderFlags .PL_SHADER_FLAGS_ALWAYS_COMPILE
73+ )
74+
75+ plShaderI .initialize (shader_options )
76+
77+ # Complete starter initialization after custom systems are ready.
78+ plStarterI .finalize ()
79+
80+ ptFontAtlas = plDrawI .get_current_font_atlas ()
81+ self .ptFont = plDrawI .get_first_font (ptFontAtlas )
82+
83+ self .ptDevice = plStarterI .get_device ()
84+ resourceManagerInit = plResourceManagerInit ()
85+ resourceManagerInit .ptDevice = self .ptDevice
86+ plResourceI .initialize (resourceManagerInit )
87+
88+ self .texture_resource = plResourceI .load ("/assets/core/textures/sprite_map.png" , 0 )
89+ self .texture_handle = plResourceI .get_texture (self .texture_resource )
90+ self .texture_bg = plDrawI .create_bind_group_for_texture (self .texture_handle )
91+
92+ def pl_app_shutdown (self ):
93+ """
94+ Called once when the app exits.
95+ Flush GPU work, clean up engine systems, then destroy the window.
96+ """
97+
98+ plGraphicsI .flush_device (plStarterI .get_device ())
99+ plResourceI .cleanup ()
100+ plStarterI .cleanup ()
101+
102+ plWindowI .destroy (self .ptWindow )
103+
104+ def pl_app_resize (self ):
105+ """
106+ Called when the window changes size.
107+ Let the starter extension rebuild any size-dependent resources.
108+ """
109+ plStarterI .resize ()
110+
111+ # -------------------------------------------------------------------------
112+ # Per-frame update
113+ # -------------------------------------------------------------------------
114+
115+ def pl_app_update (self ):
116+ """
117+ Called once per frame.
118+ This is where all drawing for the frame happens.
119+ """
120+
121+ # Begin the frame. If it returns False, skip rendering this frame.
122+ if not plStarterI .begin_frame ():
123+ return
124+
125+ plResourceI .new_frame ()
126+
127+ # Foreground fgLayer is a convenient draw list for 2D overlay-style
128+ # rendering.
129+ fgLayer = plStarterI .get_foreground_layer ()
130+
131+ plDrawI .add_bezier_quad (
132+ fgLayer ,
133+ [120.0 , 420.0 ], # start
134+ [260.0 , 320.0 ], # control
135+ [420.0 , 450.0 ], # end
136+ 0 , # segment count (0 = automatic/default)
137+ plDrawLineOptions (PL_COLOR_32_BLUE )
138+ )
139+
140+ # Cubic bezier with thicker line
141+ plDrawI .add_bezier_cubic (
142+ fgLayer ,
143+ [120.0 , 560.0 ], # start
144+ [220.0 , 460.0 ], # control 1
145+ [360.0 , 660.0 ], # control 2
146+ [460.0 , 540.0 ], # end
147+ 0 , # segment count
148+ plDrawLineOptions (PL_COLOR_32_RED , 3.0 )
149+ )
150+
151+ plDrawI .add_image (fgLayer , self .texture_bg , [0 , 0 ], [500 , 500 ])
152+
153+ # Submit/present the frame.
154+ plStarterI .end_frame ()
155+
156+
157+ # Run the application.
158+ pl_run (App ())
0 commit comments