OpenGLContext 3.0.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. OpenGLContext/__init__.py +151 -0
  2. OpenGLContext/arrays.py +2 -0
  3. OpenGLContext/atlas.py +300 -0
  4. OpenGLContext/audio/__init__.py +32 -0
  5. OpenGLContext/audio/scene.py +130 -0
  6. OpenGLContext/audio/settings.py +82 -0
  7. OpenGLContext/bin/__init__.py +0 -0
  8. OpenGLContext/bin/choosecontext.py +224 -0
  9. OpenGLContext/bin/choosefonts.py +209 -0
  10. OpenGLContext/bin/gltest.py +121 -0
  11. OpenGLContext/bin/gltf_demo.py +492 -0
  12. OpenGLContext/bin/gltf_regression.py +645 -0
  13. OpenGLContext/bin/gltf_view.py +30 -0
  14. OpenGLContext/bin/keyboardevents.py +93 -0
  15. OpenGLContext/bin/lorentz.py +109 -0
  16. OpenGLContext/bin/physics_cook.py +81 -0
  17. OpenGLContext/bin/profile_view.py +38 -0
  18. OpenGLContext/bin/terrain_view.py +581 -0
  19. OpenGLContext/bin/tiles_view.py +39 -0
  20. OpenGLContext/bin/ui_demo.py +228 -0
  21. OpenGLContext/bin/view.py +341 -0
  22. OpenGLContext/bin/vrml_view.py +42 -0
  23. OpenGLContext/capture.py +125 -0
  24. OpenGLContext/context.py +1253 -0
  25. OpenGLContext/contextconfig.py +177 -0
  26. OpenGLContext/contextdefinition.py +275 -0
  27. OpenGLContext/debug/__init__.py +6 -0
  28. OpenGLContext/debug/bufferimage.py +80 -0
  29. OpenGLContext/debug/leaks.py +13 -0
  30. OpenGLContext/debug/logcontext.py +9 -0
  31. OpenGLContext/debug/logs.py +15 -0
  32. OpenGLContext/debug/state.py +329 -0
  33. OpenGLContext/displaylist.py +69 -0
  34. OpenGLContext/doinchildmatrix.py +34 -0
  35. OpenGLContext/drawcube.py +58 -0
  36. OpenGLContext/events/__init__.py +10 -0
  37. OpenGLContext/events/default_config.py +29 -0
  38. OpenGLContext/events/event.py +65 -0
  39. OpenGLContext/events/eventhandlermixin.py +214 -0
  40. OpenGLContext/events/eventmanager.py +269 -0
  41. OpenGLContext/events/fxevents.py +90 -0
  42. OpenGLContext/events/glfwevents.py +424 -0
  43. OpenGLContext/events/glutevents.py +184 -0
  44. OpenGLContext/events/inputstate.py +129 -0
  45. OpenGLContext/events/internaltime.py +161 -0
  46. OpenGLContext/events/keyboardevents.py +153 -0
  47. OpenGLContext/events/mouseevents.py +473 -0
  48. OpenGLContext/events/pygameevents.py +162 -0
  49. OpenGLContext/events/systemtime.py +12 -0
  50. OpenGLContext/events/timeeventgeneratormanager.py +40 -0
  51. OpenGLContext/events/timeevents.py +143 -0
  52. OpenGLContext/events/timer.py +170 -0
  53. OpenGLContext/events/tkevents.py +172 -0
  54. OpenGLContext/events/wxevents.py +185 -0
  55. OpenGLContext/extensionmanager.py +158 -0
  56. OpenGLContext/framecounter.py +74 -0
  57. OpenGLContext/frustum.py +135 -0
  58. OpenGLContext/glfwcontext.py +395 -0
  59. OpenGLContext/glfwinteractivecontext.py +34 -0
  60. OpenGLContext/glfwvrmlcontext.py +11 -0
  61. OpenGLContext/glutcontext.py +224 -0
  62. OpenGLContext/glutinteractivecontext.py +24 -0
  63. OpenGLContext/gluttestingcontext.py +11 -0
  64. OpenGLContext/glutvrmlcontext.py +25 -0
  65. OpenGLContext/glutvrmltestingcontext.py +48 -0
  66. OpenGLContext/hud.py +404 -0
  67. OpenGLContext/interactivecontext.py +29 -0
  68. OpenGLContext/loaders/__init__.py +1 -0
  69. OpenGLContext/loaders/base.py +84 -0
  70. OpenGLContext/loaders/cc0.py +137 -0
  71. OpenGLContext/loaders/gltf/__init__.py +71 -0
  72. OpenGLContext/loaders/gltf/accessors.py +255 -0
  73. OpenGLContext/loaders/gltf/animation.py +611 -0
  74. OpenGLContext/loaders/gltf/draco.py +166 -0
  75. OpenGLContext/loaders/gltf/environment_sky.py +416 -0
  76. OpenGLContext/loaders/gltf/loader.py +80 -0
  77. OpenGLContext/loaders/gltf/materials.py +298 -0
  78. OpenGLContext/loaders/gltf/meshes.py +292 -0
  79. OpenGLContext/loaders/gltf/samples.py +162 -0
  80. OpenGLContext/loaders/gltf/scene.py +673 -0
  81. OpenGLContext/loaders/gltf/specular_glossiness.py +154 -0
  82. OpenGLContext/loaders/gltf/textures.py +155 -0
  83. OpenGLContext/loaders/gltf/transforms.py +261 -0
  84. OpenGLContext/loaders/gltf_demos.py +511 -0
  85. OpenGLContext/loaders/hdr.py +228 -0
  86. OpenGLContext/loaders/hdri.py +83 -0
  87. OpenGLContext/loaders/loader.py +255 -0
  88. OpenGLContext/loaders/obj.py +299 -0
  89. OpenGLContext/loaders/resolver.py +536 -0
  90. OpenGLContext/loaders/tiles3d/__init__.py +9 -0
  91. OpenGLContext/loaders/tiles3d/boundingvolume.py +120 -0
  92. OpenGLContext/loaders/tiles3d/dem.py +71 -0
  93. OpenGLContext/loaders/tiles3d/fetch.py +102 -0
  94. OpenGLContext/loaders/tiles3d/foliage.py +786 -0
  95. OpenGLContext/loaders/tiles3d/frustum.py +70 -0
  96. OpenGLContext/loaders/tiles3d/geomorph.py +57 -0
  97. OpenGLContext/loaders/tiles3d/gltf_uploader.py +246 -0
  98. OpenGLContext/loaders/tiles3d/loadmanager.py +121 -0
  99. OpenGLContext/loaders/tiles3d/physics_colliders.py +78 -0
  100. OpenGLContext/loaders/tiles3d/procedural.py +355 -0
  101. OpenGLContext/loaders/tiles3d/residency.py +102 -0
  102. OpenGLContext/loaders/tiles3d/runtime.py +168 -0
  103. OpenGLContext/loaders/tiles3d/sample.py +212 -0
  104. OpenGLContext/loaders/tiles3d/scatter.py +77 -0
  105. OpenGLContext/loaders/tiles3d/screenspaceerror.py +31 -0
  106. OpenGLContext/loaders/tiles3d/tileset.py +390 -0
  107. OpenGLContext/loaders/tiles3d/traversal.py +108 -0
  108. OpenGLContext/loaders/tiles3d/vegetation.py +361 -0
  109. OpenGLContext/loaders/vrml97.py +133 -0
  110. OpenGLContext/looptrace.py +307 -0
  111. OpenGLContext/move/__init__.py +0 -0
  112. OpenGLContext/move/bindingstore.py +232 -0
  113. OpenGLContext/move/direct.py +156 -0
  114. OpenGLContext/move/dragwatcher.py +42 -0
  115. OpenGLContext/move/examinemanager.py +100 -0
  116. OpenGLContext/move/followcam.py +121 -0
  117. OpenGLContext/move/modes.py +522 -0
  118. OpenGLContext/move/movementmanager.py +74 -0
  119. OpenGLContext/move/navigation.py +137 -0
  120. OpenGLContext/move/physicsplatform.py +203 -0
  121. OpenGLContext/move/physicswalk.py +469 -0
  122. OpenGLContext/move/smooth.py +68 -0
  123. OpenGLContext/move/terrainwalk.py +451 -0
  124. OpenGLContext/move/trackball.py +92 -0
  125. OpenGLContext/move/viewplatform.py +283 -0
  126. OpenGLContext/move/viewplatformmixin.py +335 -0
  127. OpenGLContext/nav/__init__.py +13 -0
  128. OpenGLContext/nav/navmesh.py +476 -0
  129. OpenGLContext/passes/__init__.py +0 -0
  130. OpenGLContext/passes/_flat.py +1317 -0
  131. OpenGLContext/passes/asyncpick.py +216 -0
  132. OpenGLContext/passes/bloom.py +257 -0
  133. OpenGLContext/passes/flatcompat.py +246 -0
  134. OpenGLContext/passes/flatcore.py +198 -0
  135. OpenGLContext/passes/flateffects.py +372 -0
  136. OpenGLContext/passes/ibl.py +711 -0
  137. OpenGLContext/passes/instancing.py +775 -0
  138. OpenGLContext/passes/pbrpass.py +829 -0
  139. OpenGLContext/passes/renderpass.py +79 -0
  140. OpenGLContext/passes/renderstats.py +55 -0
  141. OpenGLContext/passes/rendervisitor.py +60 -0
  142. OpenGLContext/passes/selection.py +450 -0
  143. OpenGLContext/passes/selectionbuffers.py +442 -0
  144. OpenGLContext/passes/shaderpass.py +1018 -0
  145. OpenGLContext/passes/shaderpass_shadow.py +197 -0
  146. OpenGLContext/passes/shadersource.py +121 -0
  147. OpenGLContext/passes/shadowcaps.py +182 -0
  148. OpenGLContext/passes/shadowmap.py +330 -0
  149. OpenGLContext/passes/shadowmath.py +290 -0
  150. OpenGLContext/passes/shadowmixin.py +906 -0
  151. OpenGLContext/passes/shadowpool.py +186 -0
  152. OpenGLContext/passes/transmission.py +124 -0
  153. OpenGLContext/physics/__init__.py +16 -0
  154. OpenGLContext/physics/debugdraw.py +370 -0
  155. OpenGLContext/physics/demo.py +157 -0
  156. OpenGLContext/physics/gltf_world.py +185 -0
  157. OpenGLContext/physics/manager.py +84 -0
  158. OpenGLContext/physics/threaded.py +93 -0
  159. OpenGLContext/plugins.py +61 -0
  160. OpenGLContext/pygamecontext.py +178 -0
  161. OpenGLContext/pygameinteractivecontext.py +36 -0
  162. OpenGLContext/pygametestingcontext.py +10 -0
  163. OpenGLContext/pygamevrmlcontext.py +13 -0
  164. OpenGLContext/quaternion.py +190 -0
  165. OpenGLContext/renderoptions.py +280 -0
  166. OpenGLContext/resources/__init__.py +36 -0
  167. OpenGLContext/resources/available_contexts.txt +4 -0
  168. OpenGLContext/resources/available_contexts_txt.py +9 -0
  169. OpenGLContext/resources/context_icon_png.py +46 -0
  170. OpenGLContext/resources/context_icon_small_png.py +21 -0
  171. OpenGLContext/resources/disk_icon_hi_png.py +14 -0
  172. OpenGLContext/resources/disk_icon_png.py +15 -0
  173. OpenGLContext/resources/environment/pimbackground_BK.jpg +0 -0
  174. OpenGLContext/resources/environment/pimbackground_DN.jpg +0 -0
  175. OpenGLContext/resources/environment/pimbackground_FR.jpg +0 -0
  176. OpenGLContext/resources/environment/pimbackground_LF.jpg +0 -0
  177. OpenGLContext/resources/environment/pimbackground_RT.jpg +0 -0
  178. OpenGLContext/resources/environment/pimbackground_UP.jpg +0 -0
  179. OpenGLContext/resources/environment/studio_BK.jpg +0 -0
  180. OpenGLContext/resources/environment/studio_DN.jpg +0 -0
  181. OpenGLContext/resources/environment/studio_FR.jpg +0 -0
  182. OpenGLContext/resources/environment/studio_LF.jpg +0 -0
  183. OpenGLContext/resources/environment/studio_RT.jpg +0 -0
  184. OpenGLContext/resources/environment/studio_UP.jpg +0 -0
  185. OpenGLContext/resources/environment/studiobright_BK.jpg +0 -0
  186. OpenGLContext/resources/environment/studiobright_DN.jpg +0 -0
  187. OpenGLContext/resources/environment/studiobright_FR.jpg +0 -0
  188. OpenGLContext/resources/environment/studiobright_LF.jpg +0 -0
  189. OpenGLContext/resources/environment/studiobright_RT.jpg +0 -0
  190. OpenGLContext/resources/environment/studiobright_UP.jpg +0 -0
  191. OpenGLContext/resources/green_arrow_right_png.py +47 -0
  192. OpenGLContext/resources/legacy_lighting.vert.txt +37 -0
  193. OpenGLContext/resources/legacy_lighting_vert_txt.py +18 -0
  194. OpenGLContext/resources/lights.vert.txt +107 -0
  195. OpenGLContext/resources/lights_vert_txt.py +23 -0
  196. OpenGLContext/resources/phongprecalc_vert.py +30 -0
  197. OpenGLContext/resources/phongweights_frag.py +47 -0
  198. OpenGLContext/resources/pygame_icon_png.py +47 -0
  199. OpenGLContext/resources/red_arrow_right_png.py +50 -0
  200. OpenGLContext/resources/simpleshader.frag.txt +3 -0
  201. OpenGLContext/resources/simpleshader.vert.txt +3 -0
  202. OpenGLContext/resources/simpleshader_frag_txt.py +9 -0
  203. OpenGLContext/resources/simpleshader_vert_txt.py +10 -0
  204. OpenGLContext/scenegraph/__init__.py +19 -0
  205. OpenGLContext/scenegraph/appearance.py +107 -0
  206. OpenGLContext/scenegraph/arraygeometry.py +238 -0
  207. OpenGLContext/scenegraph/audio.py +632 -0
  208. OpenGLContext/scenegraph/background.py +108 -0
  209. OpenGLContext/scenegraph/basenodes.py +50 -0
  210. OpenGLContext/scenegraph/billboard.py +14 -0
  211. OpenGLContext/scenegraph/boundingvolume.py +494 -0
  212. OpenGLContext/scenegraph/box.py +180 -0
  213. OpenGLContext/scenegraph/collision.py +14 -0
  214. OpenGLContext/scenegraph/coordinate.py +20 -0
  215. OpenGLContext/scenegraph/coordinatebounded.py +18 -0
  216. OpenGLContext/scenegraph/cubebackground.py +207 -0
  217. OpenGLContext/scenegraph/extrusions.py +275 -0
  218. OpenGLContext/scenegraph/fog.py +123 -0
  219. OpenGLContext/scenegraph/gear.py +323 -0
  220. OpenGLContext/scenegraph/group.py +20 -0
  221. OpenGLContext/scenegraph/grouping.py +140 -0
  222. OpenGLContext/scenegraph/hdrbackground.py +384 -0
  223. OpenGLContext/scenegraph/ifscompiler.py +633 -0
  224. OpenGLContext/scenegraph/imagetexture.py +365 -0
  225. OpenGLContext/scenegraph/indexedfaceset.py +238 -0
  226. OpenGLContext/scenegraph/indexedlineset.py +418 -0
  227. OpenGLContext/scenegraph/indexedpolygons.py +422 -0
  228. OpenGLContext/scenegraph/inline.py +79 -0
  229. OpenGLContext/scenegraph/instancedgl.py +187 -0
  230. OpenGLContext/scenegraph/interpolators.py +122 -0
  231. OpenGLContext/scenegraph/light.py +213 -0
  232. OpenGLContext/scenegraph/lod.py +22 -0
  233. OpenGLContext/scenegraph/material.py +96 -0
  234. OpenGLContext/scenegraph/material_fields.py +50 -0
  235. OpenGLContext/scenegraph/mouseover.py +43 -0
  236. OpenGLContext/scenegraph/nodepath.py +52 -0
  237. OpenGLContext/scenegraph/nurbs.py +637 -0
  238. OpenGLContext/scenegraph/nurbssampling.py +101 -0
  239. OpenGLContext/scenegraph/nurbstess.py +316 -0
  240. OpenGLContext/scenegraph/nurbstrim.py +54 -0
  241. OpenGLContext/scenegraph/particles.py +786 -0
  242. OpenGLContext/scenegraph/pbrmaterial.py +229 -0
  243. OpenGLContext/scenegraph/pbrmesh.py +558 -0
  244. OpenGLContext/scenegraph/physicsbody.py +72 -0
  245. OpenGLContext/scenegraph/pointset.py +257 -0
  246. OpenGLContext/scenegraph/polygon.py +166 -0
  247. OpenGLContext/scenegraph/polygonsort.py +119 -0
  248. OpenGLContext/scenegraph/polygontessellator.py +213 -0
  249. OpenGLContext/scenegraph/quadrics.py +494 -0
  250. OpenGLContext/scenegraph/scenegraph.py +21 -0
  251. OpenGLContext/scenegraph/shadergeometry.py +403 -0
  252. OpenGLContext/scenegraph/shaders.py +812 -0
  253. OpenGLContext/scenegraph/shape.py +243 -0
  254. OpenGLContext/scenegraph/simplebackground.py +34 -0
  255. OpenGLContext/scenegraph/spherebackground.py +462 -0
  256. OpenGLContext/scenegraph/switch.py +75 -0
  257. OpenGLContext/scenegraph/teapot.py +439 -0
  258. OpenGLContext/scenegraph/teapot_nurbs.py +291 -0
  259. OpenGLContext/scenegraph/teapot_nurbs_data.py +384 -0
  260. OpenGLContext/scenegraph/terrain/__init__.py +12 -0
  261. OpenGLContext/scenegraph/terrain/heightfield.py +172 -0
  262. OpenGLContext/scenegraph/terrain/splat.py +224 -0
  263. OpenGLContext/scenegraph/tessellationlod.py +97 -0
  264. OpenGLContext/scenegraph/text/__init__.py +1 -0
  265. OpenGLContext/scenegraph/text/_toolsfont.py +200 -0
  266. OpenGLContext/scenegraph/text/font.py +452 -0
  267. OpenGLContext/scenegraph/text/fontprovider.py +193 -0
  268. OpenGLContext/scenegraph/text/fonts/__init__.py +75 -0
  269. OpenGLContext/scenegraph/text/fonts/font_atlas_10.py +133 -0
  270. OpenGLContext/scenegraph/text/fonts/font_atlas_12.py +158 -0
  271. OpenGLContext/scenegraph/text/fonts/font_atlas_14.py +176 -0
  272. OpenGLContext/scenegraph/text/fonts/font_atlas_16.py +204 -0
  273. OpenGLContext/scenegraph/text/fonts/font_atlas_18.py +222 -0
  274. OpenGLContext/scenegraph/text/fonts/font_atlas_20.py +244 -0
  275. OpenGLContext/scenegraph/text/fonts/font_atlas_24.py +294 -0
  276. OpenGLContext/scenegraph/text/fonts/font_atlas_28.py +339 -0
  277. OpenGLContext/scenegraph/text/fonts/font_atlas_32.py +390 -0
  278. OpenGLContext/scenegraph/text/fontstyle3d.py +62 -0
  279. OpenGLContext/scenegraph/text/glutfont.py +186 -0
  280. OpenGLContext/scenegraph/text/pygamefont.py +213 -0
  281. OpenGLContext/scenegraph/text/shaderfont.py +340 -0
  282. OpenGLContext/scenegraph/text/shadertext.py +433 -0
  283. OpenGLContext/scenegraph/text/text.py +75 -0
  284. OpenGLContext/scenegraph/text/toolsfont.py +819 -0
  285. OpenGLContext/scenegraph/text/ttfregistry.py +135 -0
  286. OpenGLContext/scenegraph/text/wglfont.py +228 -0
  287. OpenGLContext/scenegraph/text/wglfontprovider.py +37 -0
  288. OpenGLContext/scenegraph/text/wxfont.py +314 -0
  289. OpenGLContext/scenegraph/texturetransform.py +66 -0
  290. OpenGLContext/scenegraph/tilesterrain.py +95 -0
  291. OpenGLContext/scenegraph/timesensor.py +51 -0
  292. OpenGLContext/scenegraph/transform.py +180 -0
  293. OpenGLContext/scenegraph/vegetation/__init__.py +20 -0
  294. OpenGLContext/scenegraph/vegetation/base.py +96 -0
  295. OpenGLContext/scenegraph/vegetation/billboards.py +145 -0
  296. OpenGLContext/scenegraph/vegetation/clumps.py +260 -0
  297. OpenGLContext/scenegraph/vegetation/grid.py +112 -0
  298. OpenGLContext/scenegraph/vegetation/nearmesh.py +185 -0
  299. OpenGLContext/scenegraph/vertex.py +54 -0
  300. OpenGLContext/scenegraph/viewpoint.py +42 -0
  301. OpenGLContext/scenegraph/winding.py +49 -0
  302. OpenGLContext/shaders/_brdf_inc.glsl +124 -0
  303. OpenGLContext/shaders/_common_inc.glsl +24 -0
  304. OpenGLContext/shaders/_cubemap_inc.glsl +26 -0
  305. OpenGLContext/shaders/_lights_inc.glsl +32 -0
  306. OpenGLContext/shaders/_objectid_inc.glsl +14 -0
  307. OpenGLContext/shaders/_shadow_inc.glsl +254 -0
  308. OpenGLContext/shaders/_vrml97_lighting_inc.glsl +78 -0
  309. OpenGLContext/shaders/hdr_background.frag +32 -0
  310. OpenGLContext/shaders/hdr_background.vert +15 -0
  311. OpenGLContext/shaders/ibl_brdf.frag +78 -0
  312. OpenGLContext/shaders/ibl_env.frag +53 -0
  313. OpenGLContext/shaders/ibl_equirect.frag +19 -0
  314. OpenGLContext/shaders/ibl_fullscreen.vert +11 -0
  315. OpenGLContext/shaders/ibl_irradiance.frag +40 -0
  316. OpenGLContext/shaders/ibl_prefilter.frag +56 -0
  317. OpenGLContext/shaders/particle.frag +42 -0
  318. OpenGLContext/shaders/particle.vert +52 -0
  319. OpenGLContext/shaders/pbr.frag +906 -0
  320. OpenGLContext/shaders/pbr.vert +70 -0
  321. OpenGLContext/shaders/shadow_depth.frag +4 -0
  322. OpenGLContext/shaders/shadow_depth.vert +18 -0
  323. OpenGLContext/shaders/terrain_splat.frag +80 -0
  324. OpenGLContext/shaders/terrain_splat.vert +16 -0
  325. OpenGLContext/shaders/veg_billboard.frag +35 -0
  326. OpenGLContext/shaders/veg_billboard.vert +17 -0
  327. OpenGLContext/shaders/veg_clump.frag +27 -0
  328. OpenGLContext/shaders/veg_mesh.frag +26 -0
  329. OpenGLContext/shaders/veg_mesh.vert +17 -0
  330. OpenGLContext/shaders/vrml97_background.frag +17 -0
  331. OpenGLContext/shaders/vrml97_background.vert +24 -0
  332. OpenGLContext/shaders/vrml97_lighting.frag +111 -0
  333. OpenGLContext/shaders/vrml97_lighting.vert +50 -0
  334. OpenGLContext/shaders/vrml97_line.frag +23 -0
  335. OpenGLContext/shaders/vrml97_line.vert +24 -0
  336. OpenGLContext/shaders/vrml97_point.frag +36 -0
  337. OpenGLContext/shaders/vrml97_point.vert +21 -0
  338. OpenGLContext/shaders/vrml97_unlit.frag +59 -0
  339. OpenGLContext/shaders/vrml97_unlit.vert +18 -0
  340. OpenGLContext/shaders/vrml97_vertex_color.frag +85 -0
  341. OpenGLContext/shaders/vrml97_vertex_color.vert +34 -0
  342. OpenGLContext/stalltrace.py +637 -0
  343. OpenGLContext/testing/__init__.py +67 -0
  344. OpenGLContext/testing/display.py +30 -0
  345. OpenGLContext/testing/event_injector.py +564 -0
  346. OpenGLContext/testing/framebuffer_comparison.py +842 -0
  347. OpenGLContext/testing/gl_env.py +39 -0
  348. OpenGLContext/testing/paths.py +23 -0
  349. OpenGLContext/testing/process_exit.py +30 -0
  350. OpenGLContext/testing/report_generator.py +594 -0
  351. OpenGLContext/testing/subprocess_runner.py +411 -0
  352. OpenGLContext/testingcontext.py +36 -0
  353. OpenGLContext/tests/test_atlas.py +62 -0
  354. OpenGLContext/tests/test_configs.py +27 -0
  355. OpenGLContext/tests/test_polygonsort.py +45 -0
  356. OpenGLContext/tests/test_utilities.py +84 -0
  357. OpenGLContext/tests/test_viewplatform.py +39 -0
  358. OpenGLContext/texture.py +449 -0
  359. OpenGLContext/texturecache.py +37 -0
  360. OpenGLContext/triangleutilities.py +89 -0
  361. OpenGLContext/ui/__init__.py +39 -0
  362. OpenGLContext/ui/bindings.py +243 -0
  363. OpenGLContext/ui/console.py +339 -0
  364. OpenGLContext/ui/debugoverlay.py +519 -0
  365. OpenGLContext/ui/dialogs.py +124 -0
  366. OpenGLContext/ui/draw.py +617 -0
  367. OpenGLContext/ui/gallery.py +425 -0
  368. OpenGLContext/ui/generate.py +195 -0
  369. OpenGLContext/ui/geometry.py +88 -0
  370. OpenGLContext/ui/hudwidgets.py +1053 -0
  371. OpenGLContext/ui/layout.py +263 -0
  372. OpenGLContext/ui/metrics.py +218 -0
  373. OpenGLContext/ui/overlay.py +412 -0
  374. OpenGLContext/ui/panel.py +459 -0
  375. OpenGLContext/ui/pictures.py +261 -0
  376. OpenGLContext/ui/screen.py +177 -0
  377. OpenGLContext/ui/scroll.py +297 -0
  378. OpenGLContext/ui/session.py +329 -0
  379. OpenGLContext/ui/settings.py +273 -0
  380. OpenGLContext/ui/skin.py +330 -0
  381. OpenGLContext/ui/widgets.py +1199 -0
  382. OpenGLContext/userpaths.py +48 -0
  383. OpenGLContext/utilities.py +94 -0
  384. OpenGLContext/vectorutilities.py +101 -0
  385. OpenGLContext/viewer/__init__.py +60 -0
  386. OpenGLContext/viewer/adapters/__init__.py +150 -0
  387. OpenGLContext/viewer/adapters/base.py +157 -0
  388. OpenGLContext/viewer/adapters/gltf.py +31 -0
  389. OpenGLContext/viewer/adapters/obj.py +20 -0
  390. OpenGLContext/viewer/adapters/scenegraph.py +71 -0
  391. OpenGLContext/viewer/adapters/tiles.py +296 -0
  392. OpenGLContext/viewer/adapters/vrml.py +25 -0
  393. OpenGLContext/viewer/asyncscene.py +117 -0
  394. OpenGLContext/viewer/caption.py +126 -0
  395. OpenGLContext/viewer/capture.py +77 -0
  396. OpenGLContext/viewer/debug.py +78 -0
  397. OpenGLContext/viewer/environment.py +131 -0
  398. OpenGLContext/viewer/framing.py +111 -0
  399. OpenGLContext/viewer/library.py +235 -0
  400. OpenGLContext/viewer/menu.py +218 -0
  401. OpenGLContext/viewer/options.py +150 -0
  402. OpenGLContext/viewer/overlay.py +63 -0
  403. OpenGLContext/viewer/sceneviewer.py +1056 -0
  404. OpenGLContext/viewer/screens.py +172 -0
  405. OpenGLContext/viewer/source.py +56 -0
  406. OpenGLContext/visitor.py +68 -0
  407. OpenGLContext/vrmlcontext.py +72 -0
  408. OpenGLContext/wxcontext.py +424 -0
  409. OpenGLContext/wxinteractivecontext.py +25 -0
  410. OpenGLContext/wxtestingcontext.py +9 -0
  411. OpenGLContext/wxvrmlcontext.py +13 -0
  412. openglcontext-3.0.0a1.dist-info/METADATA +650 -0
  413. openglcontext-3.0.0a1.dist-info/RECORD +417 -0
  414. openglcontext-3.0.0a1.dist-info/WHEEL +5 -0
  415. openglcontext-3.0.0a1.dist-info/entry_points.txt +11 -0
  416. openglcontext-3.0.0a1.dist-info/licenses/license.txt +89 -0
  417. openglcontext-3.0.0a1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,213 @@
1
+ """PyGame bitmap and texmap fonts"""
2
+ from OpenGLContext.scenegraph.text import fontprovider, font
3
+ from OpenGL.GL import *
4
+ from pygame import font as pygame_font
5
+ from pygame import image, surfarray, transform
6
+ import pygame, traceback, os
7
+ from OpenGLContext.arrays import transpose, shape, zeros, contiguous
8
+ import logging
9
+ log = logging.getLogger( __name__ )
10
+
11
+ pygame_font.init()
12
+ pygame.init()
13
+
14
+
15
+ class PyGameBitmapFont( font.NoDepthBufferMixIn, font.BitmapFontMixIn, font.Font ):
16
+ """A PyGame-provided Bitmap Font
17
+ """
18
+ format = "bitmap"
19
+ def __init__(
20
+ self,
21
+ fontStyle = None,
22
+ filename = None,
23
+ size = None,
24
+ ):
25
+ self._displayLists = {}
26
+ self.fontStyle = fontStyle or None
27
+ if filename is None or size is None:
28
+ fontFile, weight, italics, size = PyGameFontProvider.match( fontStyle )
29
+ self.font = pygame_font.Font( fontFile, int(size))
30
+ self.filename = filename
31
+ self.size = size
32
+ if __debug__:
33
+ log.info( """Created font %s""", self)
34
+
35
+ def createChar( self, char, mode=None ):
36
+ """Create the single-character display list
37
+ """
38
+ dataArray, metrics = self.createCharTexture( char, mode=mode )
39
+ if dataArray is not None:
40
+ ## XXX should store dataArray in global cache...
41
+ list = self.textureToList( dataArray, metrics, mode=mode )
42
+ ## XXX list should be stored in a context-specific cache...
43
+ return list, metrics
44
+ return None, metrics
45
+
46
+ def textureToList( self, array, metrics, mode=None ):
47
+ """Compile Numeric Python array to a display-list
48
+
49
+ XXX:
50
+ use a single texture and coordinates for texmap
51
+ version
52
+
53
+ special case ' ' so that it's not rendered as
54
+ an image...
55
+ """
56
+ if shape(array)[-1] == 2:
57
+ mode = GL_LUMINANCE_ALPHA
58
+ elif shape(array)[-1] == 4:
59
+ mode = GL_RGBA
60
+ else:
61
+ raise ValueError( """Unsupported array dimension for textureToList, require 2 or 4 items/pixel, got %s"""%(shape(array)[-1],))
62
+ list = glGenLists (1)
63
+ glNewList( list, GL_COMPILE )
64
+ try:
65
+ try:
66
+ if metrics.char != ' ':
67
+ glPixelStorei(GL_UNPACK_ALIGNMENT,1)
68
+ glPixelStorei(GL_PACK_ALIGNMENT, 1)
69
+ glDrawPixelsub(
70
+ mode,
71
+ array,
72
+ )
73
+ glBitmap( 0,0,0,0, metrics.width,0, None )
74
+ except Exception:
75
+ glDeleteLists( list, 1 )
76
+ raise
77
+ finally:
78
+ glEndList()
79
+ return list
80
+
81
+ def createCharTexture( self, char, mode=None ):
82
+ """Create character's texture/bitmap as a Numeric array w/ width and height
83
+
84
+ This uses PyGame and Numeric to attempt to create
85
+ an anti-aliased luminance texture-map of the given
86
+ character and return it as (data, width, height).
87
+ """
88
+ try:
89
+ letter_render = self.font.render(
90
+ char,
91
+ 1,
92
+ (255,255,255)
93
+ )
94
+ except Exception:
95
+ traceback.print_exc()
96
+ return None, font.CharacterMetrics(char,0,0)
97
+ else:
98
+ # XXX Figure out why this rotate appears to be required :(
99
+ letter_render = transform.rotate( letter_render, -90.0)
100
+ colour = surfarray.array3d( letter_render )
101
+ alpha = surfarray.array_alpha( letter_render )
102
+ colour[:,:,1] = alpha
103
+ colour = colour[:,:,:2]
104
+ colour = contiguous( colour ).astype( 'B' )
105
+ # This produces what looks like garbage, but displays correctly
106
+ colour.shape = (colour.shape[1],colour.shape[0],)+colour.shape[2:]
107
+ return colour, font.CharacterMetrics(
108
+ char,
109
+ colour.shape[0],
110
+ colour.shape[1],
111
+ )
112
+
113
+ def lists( self, value, mode=None ):
114
+ """Get a sequence of display-list integers for value
115
+
116
+ Basically, this does a bit of trickery to do
117
+ as-required compilation of display-lists, so
118
+ that only those characters actually required
119
+ by the displayed text are compiled.
120
+
121
+ NOTE: Must be called from within the rendering
122
+ thread and within the rendering pass!
123
+ """
124
+ if __debug__:
125
+ log.info( """lists %s(%s)""", self, repr(value))
126
+ lists = []
127
+ font = self.font
128
+ for char in value:
129
+ list, metrics = self.getChar( char, mode=mode )
130
+ if list is not None:
131
+ lists.append( list )
132
+ if __debug__:
133
+ log.info( """lists %s(%s)->%s""", self, repr(value), lists)
134
+ return lists
135
+ def lineHeight(self, mode=None ):
136
+ """Retrieve normal line-height for this font
137
+ """
138
+ return self.font.get_linesize()
139
+
140
+ class _PyGameFontProvider (fontprovider.TTFFontProvider):
141
+ """Singleton for creating new PyGameBitmapFonts
142
+ """
143
+ format = "bitmap"
144
+ scale = 12
145
+ def __init__( self ):
146
+ super( _PyGameFontProvider, self).__init__()
147
+ self.nameToFile = {}
148
+
149
+ def create( self, fontStyle, mode=None ):
150
+ """Create a new font for the given fontStyle and mode"""
151
+ fontFile, weight, italics, size = key = self.match(fontStyle, mode)
152
+ # do we already have this filename + size established?
153
+ if key in self.fonts:
154
+ return self.fonts.get( key )
155
+ bitmapFont = PyGameBitmapFont( fontStyle, filename = fontFile )
156
+ self.addFont( fontStyle, bitmapFont )
157
+ self.fonts[key] = bitmapFont
158
+ return bitmapFont
159
+ def key( self, fontStyle, mode=None ):
160
+ """Calculate the key for the fontStyle"""
161
+ if not fontStyle:
162
+ return None
163
+ attributes = ('family','style','size',)
164
+ result = []
165
+ for a in attributes:
166
+ if hasattr( fontStyle, a):
167
+ item = getattr( fontStyle, a)
168
+ if isinstance( item, list ):
169
+ item = tuple( item )
170
+ result.append( item )
171
+ else:
172
+ result.append( None )
173
+ return tuple( result )
174
+
175
+ def match( self, fontStyle, mode=None ):
176
+ """Attempt to find matching font-file for our fontstyle
177
+
178
+ Should match any name passed into addFontFile,
179
+ as well as the short filename for the font.
180
+ """
181
+ registry = self.getTTFRegistry()
182
+ if registry:
183
+ fontName = registry.fontNameFromStyle( fontStyle, mode=mode )
184
+ weight, italics = registry.modifiersFromStyle( fontStyle, mode=mode )
185
+ specificFonts = registry.fontMembers( fontName, weight, italics )
186
+ if not specificFonts:
187
+ # broaden to any weight
188
+ specificFonts = registry.fontMembers( fontName, None, italics )
189
+ if not specificFonts:
190
+ # broaden to every sub-font...
191
+ specificFonts = registry.fontMembers( fontName )
192
+ if not specificFonts:
193
+ raise RuntimeError( """No concrete fonts found for general font %r (somehow)"""%( fontName, ))
194
+ # okay, just arbitrarily choose the first item, normally will only be one anyway
195
+ specificFont = specificFonts[0]
196
+ fontFile = registry.fontFile( specificFont )
197
+ size = self.scale
198
+ if fontStyle:
199
+ size = self.scale * fontStyle.size
200
+ return fontFile, weight, italics, size
201
+
202
+ def enumerate(self, mode = None):
203
+ """Iterate through all available font-keys (whether instantiated or not)
204
+
205
+ This uses the wxFontEnumerator class to provide a list of
206
+ font names from the wxPython system, (with all names
207
+ lowercased).
208
+ """
209
+ return self.nameToFile.keys()
210
+
211
+
212
+ PyGameFontProvider = _PyGameFontProvider()
213
+ PyGameFontProvider.registerProvider( PyGameFontProvider )
@@ -0,0 +1,340 @@
1
+ """Shader-based bitmap fonts using texture atlas.
2
+
3
+ This module provides a font provider that uses pre-rendered texture atlases
4
+ for text rendering, compatible with OpenGL core profile where GLUT bitmap
5
+ fonts and display lists are not available.
6
+
7
+ This serves as a fallback when glutfont is not available (non-GLUT contexts).
8
+ """
9
+ from OpenGL.GL import *
10
+ from OpenGLContext.scenegraph.text import fontprovider, font
11
+ from OpenGLContext.arrays import array
12
+ import numpy as np
13
+ import logging
14
+ import io
15
+
16
+ log = logging.getLogger(__name__)
17
+
18
+
19
+ class ShaderBitmapFont(font.NoDepthBufferMixIn, font.Font):
20
+ """Shader-based bitmap font using texture atlas.
21
+
22
+ This font renders text using textured quads with a pre-rendered
23
+ font atlas, compatible with OpenGL core profile.
24
+ """
25
+
26
+ def __init__(self, fontStyle=None, size=16):
27
+ """Initialize the shader bitmap font.
28
+
29
+ Args:
30
+ fontStyle: VRML FontStyle node (optional)
31
+ size: Font size in pixels
32
+ """
33
+ self.fontStyle = fontStyle
34
+ self._size = size
35
+ self._displayLists = {} # Cache for character metrics
36
+ self._initialized = False
37
+ self._texture = None
38
+ self._atlas_module = None
39
+
40
+ # Atlas parameters (will be set from module)
41
+ self._char_width = 0
42
+ self._char_height = 0
43
+ self._atlas_width = 0
44
+ self._atlas_height = 0
45
+ self._first_char = 32
46
+ self._last_char = 126
47
+ self._chars_per_row = 16
48
+
49
+ def _ensure_initialized(self):
50
+ """Lazily initialize the font texture."""
51
+ if self._initialized:
52
+ return True
53
+
54
+ try:
55
+ from OpenGLContext.scenegraph.text import fonts
56
+ actual_size, module = fonts.get_closest_atlas(self._size)
57
+ if module is None:
58
+ log.error("No font atlas available")
59
+ return False
60
+
61
+ self._atlas_module = module
62
+ self._char_width = module.char_width
63
+ self._char_height = module.char_height
64
+ self._atlas_width = module.atlas_width
65
+ self._atlas_height = module.atlas_height
66
+ self._first_char = module.first_char
67
+ self._last_char = module.last_char
68
+ self._chars_per_row = module.chars_per_row
69
+
70
+ # Create texture
71
+ png_data = module.get_png_data()
72
+ from PIL import Image
73
+ img = Image.open(io.BytesIO(png_data))
74
+ img = img.convert('RGBA')
75
+ texture_data = np.array(img, dtype=np.uint8)
76
+
77
+ self._texture = glGenTextures(1)
78
+ glBindTexture(GL_TEXTURE_2D, self._texture)
79
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
80
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
81
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
82
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
83
+ glTexImage2D(
84
+ GL_TEXTURE_2D, 0, GL_RGBA,
85
+ self._atlas_width, self._atlas_height, 0,
86
+ GL_RGBA, GL_UNSIGNED_BYTE,
87
+ texture_data.tobytes()
88
+ )
89
+ glBindTexture(GL_TEXTURE_2D, 0)
90
+
91
+ self._initialized = True
92
+ return True
93
+ except Exception as e:
94
+ log.error("Failed to initialize shader font: %s", e)
95
+ return False
96
+
97
+ def createChar(self, char, mode=None):
98
+ """Create metrics for a character.
99
+
100
+ Note: Unlike GLUT fonts, we don't use display lists.
101
+ We just store the metrics for width calculation.
102
+ """
103
+ self._ensure_initialized()
104
+ metrics = font.CharacterMetrics(
105
+ char,
106
+ self._char_width,
107
+ self._char_height
108
+ )
109
+ # Return None for display list (we don't use them) and metrics
110
+ return None, metrics
111
+
112
+ def lists(self, value, mode=None):
113
+ """Get display lists for value.
114
+
115
+ For shader fonts, we don't use display lists.
116
+ Return empty list - actual rendering is done differently.
117
+ """
118
+ return []
119
+
120
+ def lineHeight(self, mode=None):
121
+ """Get the line height for this font."""
122
+ self._ensure_initialized()
123
+ return int(self._char_height * 1.2)
124
+
125
+ def render(self, lines, fontStyle=None, mode=None):
126
+ """Render text lines.
127
+
128
+ For shader-based rendering, we need to use the shader pipeline.
129
+ """
130
+ if not self._ensure_initialized():
131
+ return
132
+
133
+ if isinstance(lines, (bytes, str)):
134
+ lines = self.toLines(lines, mode=mode)
135
+
136
+ if fontStyle is None:
137
+ fontStyle = self.fontStyle
138
+
139
+ # Check if we're in shader mode
140
+ shader_mode = getattr(mode, 'shader_mode', False)
141
+ shader_program = getattr(mode, 'shader_program', None)
142
+
143
+ if shader_mode and shader_program:
144
+ self._render_shader(lines, fontStyle, mode, shader_program)
145
+ else:
146
+ # Legacy fallback - try to use glRasterPos/glBitmap style
147
+ self._render_legacy(lines, fontStyle, mode)
148
+
149
+ def _render_shader(self, lines, fontStyle, mode, shader_program):
150
+ """Render using shader pipeline."""
151
+ from OpenGLContext.scenegraph.text.shadertext import get_text_renderer
152
+
153
+ # Get viewport for coordinate conversion
154
+ viewport = getattr(mode, 'viewport', None)
155
+ if viewport is None:
156
+ return
157
+
158
+ viewport_width = viewport[2]
159
+ viewport_height = viewport[3]
160
+
161
+ # Calculate text position - we need to convert from model space
162
+ # For now, render at a fixed screen position
163
+ # TODO: proper model-to-screen coordinate conversion
164
+
165
+ text = '\n'.join(line.base for line in lines)
166
+ renderer = get_text_renderer(self._char_height)
167
+
168
+ # Render at bottom-left with some margin
169
+ renderer.render_text(
170
+ text, 10, 30, shader_program,
171
+ viewport_width, viewport_height,
172
+ color=(1.0, 1.0, 1.0, 1.0)
173
+ )
174
+
175
+ def _render_legacy(self, lines, fontStyle, mode):
176
+ """Render using legacy OpenGL (compatibility mode).
177
+
178
+ This uses glRasterPos and textured quads for each character.
179
+ """
180
+ if not self._texture:
181
+ return
182
+
183
+ glEnable(GL_BLEND)
184
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
185
+ glEnable(GL_TEXTURE_2D)
186
+ glBindTexture(GL_TEXTURE_2D, self._texture)
187
+ # Modulate so the glyph alpha drives blending. Scene geometry (e.g.
188
+ # textured Shapes) may leave the env mode as GL_DECAL, which discards
189
+ # the texture alpha and renders solid opaque cells instead of glyphs.
190
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
191
+
192
+ try:
193
+ spacing = self.getSpacing(fontStyle=fontStyle, mode=mode)
194
+ adjust = self.verticalAdjust(spacing, lines, fontStyle=fontStyle, mode=mode)
195
+
196
+ glPushMatrix()
197
+ glTranslatef(0, adjust, 0)
198
+
199
+ for line in lines:
200
+ height = line.height * spacing if fontStyle else line.height
201
+
202
+ glPushMatrix()
203
+ for char in line.base:
204
+ self._draw_char_quad(char)
205
+ glPopMatrix()
206
+
207
+ glTranslatef(0, -height, 0)
208
+
209
+ glPopMatrix()
210
+ finally:
211
+ glBindTexture(GL_TEXTURE_2D, 0)
212
+ glDisable(GL_TEXTURE_2D)
213
+ glDisable(GL_BLEND)
214
+
215
+ def _draw_char_quad(self, char):
216
+ """Draw a single character as a textured quad."""
217
+ char_code = ord(char)
218
+ if char_code < self._first_char or char_code > self._last_char:
219
+ char_code = ord('?')
220
+
221
+ char_idx = char_code - self._first_char
222
+ col = char_idx % self._chars_per_row
223
+ row = char_idx // self._chars_per_row
224
+
225
+ # Texture coordinates
226
+ u0 = col * self._char_width / self._atlas_width
227
+ u1 = (col + 1) * self._char_width / self._atlas_width
228
+ v0 = row * self._char_height / self._atlas_height
229
+ v1 = (row + 1) * self._char_height / self._atlas_height
230
+
231
+ # Draw quad
232
+ w = self._char_width
233
+ h = self._char_height
234
+
235
+ glBegin(GL_QUADS)
236
+ glTexCoord2f(u0, v1); glVertex2f(0, 0)
237
+ glTexCoord2f(u1, v1); glVertex2f(w, 0)
238
+ glTexCoord2f(u1, v0); glVertex2f(w, h)
239
+ glTexCoord2f(u0, v0); glVertex2f(0, h)
240
+ glEnd()
241
+
242
+ glTranslatef(w, 0, 0)
243
+
244
+ def leftJustify(self, lines, fontStyle, mode=None):
245
+ """Left-justify text."""
246
+ self.render(lines, fontStyle, mode)
247
+
248
+ def centerJustify(self, lines, fontStyle, mode=None):
249
+ """Center-justify text."""
250
+ # TODO: proper center justification
251
+ self.render(lines, fontStyle, mode)
252
+
253
+ def rightJustify(self, lines, fontStyle, mode=None):
254
+ """Right-justify text."""
255
+ # TODO: proper right justification
256
+ self.render(lines, fontStyle, mode)
257
+
258
+
259
+ class _ShaderFontProvider(fontprovider.FontProvider):
260
+ """Font provider using shader-based texture atlas fonts.
261
+
262
+ This provider creates ShaderBitmapFont instances as a fallback
263
+ when GLUT fonts are not available, and is required for core profile
264
+ contexts where legacy GL functions are not available.
265
+ """
266
+ format = "bitmap"
267
+ shader_compatible = True # Mark as compatible with core profile/shader mode
268
+ scale = 12 # Points to pixels
269
+
270
+ # Available sizes from font atlas
271
+ available_sizes = [12, 16, 24, 32, 48]
272
+
273
+ def create(self, fontStyle, mode=None):
274
+ """Create a new font for the given fontStyle and mode."""
275
+ size = self._get_size(fontStyle)
276
+
277
+ # Check for existing font
278
+ fontHash = ('shader', size)
279
+ if fontHash in self.fonts:
280
+ current = self.fonts.get(fontHash)
281
+ self.addFont(fontStyle, current)
282
+ return current
283
+
284
+ # Create new font
285
+ shaderFont = ShaderBitmapFont(fontStyle, size=size)
286
+ self.addFont(fontStyle, shaderFont)
287
+ self.fonts[fontHash] = shaderFont
288
+ return shaderFont
289
+
290
+ def _get_size(self, fontStyle):
291
+ """Get appropriate font size for fontStyle."""
292
+ if fontStyle and hasattr(fontStyle, 'size'):
293
+ target = int(fontStyle.size * self.scale)
294
+ else:
295
+ target = 12
296
+
297
+ # Find closest available size
298
+ diffs = [abs(target - s) for s in self.available_sizes]
299
+ best_idx = diffs.index(min(diffs))
300
+ return self.available_sizes[best_idx]
301
+
302
+ def key(self, fontStyle=None):
303
+ """Calculate font key for caching."""
304
+ if not fontStyle:
305
+ return None
306
+ return (
307
+ tuple(fontStyle.family) if fontStyle.family else (),
308
+ fontStyle.size,
309
+ )
310
+
311
+ def enumerate(self, mode=None):
312
+ """Enumerate available fonts."""
313
+ return ['SANS', 'SERIF', 'TYPEWRITER']
314
+
315
+
316
+ # Create singleton provider
317
+ ShaderFontProvider = _ShaderFontProvider()
318
+
319
+
320
+ def register():
321
+ """Register the shader font provider.
322
+
323
+ Call this to make shader fonts available as a bitmap font provider.
324
+ """
325
+ ShaderFontProvider.registerProvider(ShaderFontProvider)
326
+
327
+
328
+ def is_available():
329
+ """Check if shader fonts are available (font atlas exists)."""
330
+ try:
331
+ from OpenGLContext.scenegraph.text import fonts
332
+ _, module = fonts.get_closest_atlas(16)
333
+ return module is not None
334
+ except ImportError:
335
+ return False
336
+
337
+
338
+ # Auto-register if font atlases are available
339
+ if is_available():
340
+ register()