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,151 @@
1
+ '''Rendering contexts for various GUI libraries, scene graph
2
+ geometry objects, and PyOpenGL testing code
3
+
4
+ The OpenGLContext project provides a simplified environment
5
+ for writing OpenGL code with PyOpenGL. This simplified
6
+ environment abstracts the GUI library interfaces for a
7
+ large number of GUI libraries to allow the easy creation of
8
+ cross platform and cross-GUI-OpenGL programs.
9
+
10
+ The project also provides simplified geometry display
11
+ primitives to allow new developers to concentrate on the
12
+ particular task in which they are interested rather than
13
+ forcing them to re-implement basic geometry display
14
+ mechanisms.
15
+
16
+ Taking advantage of this simplified environment, we have
17
+ provided a number of testing modules. These testing
18
+ modules should operate under any of the fully functional
19
+ GUI contexts (note that there are unfinished contexts).
20
+ '''
21
+
22
+ __version__ = "3.0.0a1"
23
+ __author__ = "Michael Colin Fletcher"
24
+ __license__ = "BSD-Style, see license.txt for details and exceptions"
25
+
26
+ from OpenGLContext.plugins import Context,InteractiveContext,VRMLContext,Loader,Node,Adapter
27
+
28
+ Context( 'pygame', 'OpenGLContext.pygamecontext.PyGameContext' )
29
+ Context( 'wx', 'OpenGLContext.wxcontext.wxContext' )
30
+ Context( 'glut', 'OpenGLContext.glutcontext.GLUTContext' )
31
+ Context( 'glfw', 'OpenGLContext.glfwcontext.GLFWContext' )
32
+ InteractiveContext( 'pygame', 'OpenGLContext.pygameinteractivecontext.PygameInteractiveContext' )
33
+ InteractiveContext( 'wx', 'OpenGLContext.wxinteractivecontext.wxInteractiveContext' )
34
+ InteractiveContext( 'glut', 'OpenGLContext.glutinteractivecontext.GLUTInteractiveContext' )
35
+ InteractiveContext( 'glfw', 'OpenGLContext.glfwinteractivecontext.GLFWInteractiveContext' )
36
+ VRMLContext( 'pygame', 'OpenGLContext.pygamevrmlcontext.VRMLContext' )
37
+ VRMLContext( 'wx', 'OpenGLContext.wxvrmlcontext.VRMLContext' )
38
+ VRMLContext( 'glut', 'OpenGLContext.glutvrmlcontext.VRMLContext' )
39
+ VRMLContext( 'glfw', 'OpenGLContext.glfwvrmlcontext.VRMLContext' )
40
+
41
+ try:
42
+ import OpenGLContext_qt
43
+ except ImportError as err:
44
+ pass
45
+
46
+ Loader( 'vrml97', 'OpenGLContext.loaders.vrml97.defaultHandler', ['.wrl','.wrz','.vrml','model/vrml','x-world/x-vrml','.wrl.gz'] )
47
+ Loader( 'obj', 'OpenGLContext.loaders.obj.defaultHandler', ['.obj'] )
48
+
49
+ # What `oglc-view` can open, keyed by file suffix and content type. One viewer
50
+ # serves every format; the adapter is chosen from the source itself.
51
+ Adapter( 'gltf', 'OpenGLContext.viewer.adapters.gltf.GLTFAdapter', ['.gltf','.glb','model/gltf+json','model/gltf-binary'] )
52
+ Adapter( 'vrml97', 'OpenGLContext.viewer.adapters.vrml.VRMLAdapter', ['.wrl','.wrz','.vrml','.wrl.gz','model/vrml','x-world/x-vrml'] )
53
+ Adapter( 'obj', 'OpenGLContext.viewer.adapters.obj.OBJAdapter', ['.obj','.obj.gz','model/obj'] )
54
+ # A tileset is any .json, so the registry only claims the conventional name; a
55
+ # document under another name is recognised by its content (adapters._sniff).
56
+ Adapter( 'tiles3d', 'OpenGLContext.viewer.adapters.tiles.TilesAdapter', ['tileset.json'] )
57
+
58
+ Node( 'Anchor', 'vrml.vrml97.basenodes.Anchor' )
59
+ Node( 'Appearance', 'OpenGLContext.scenegraph.appearance.Appearance' )
60
+ Node( 'AudioEmitter', 'OpenGLContext.scenegraph.audio.AudioEmitter' )
61
+ Node( 'AudioSource', 'OpenGLContext.scenegraph.audio.AudioSource' )
62
+ Node( 'AudioClip', 'vrml.vrml97.basenodes.AudioClip' )
63
+ Node( 'Background', 'OpenGLContext.scenegraph.background.Background' )
64
+ Node( 'Billboard', 'OpenGLContext.scenegraph.billboard.Billboard' )
65
+ Node( 'Box', 'OpenGLContext.scenegraph.box.Box' )
66
+ Node( 'Collision', 'OpenGLContext.scenegraph.collision.Collision' )
67
+ Node( 'Color', 'vrml.vrml97.basenodes.Color' )
68
+ Node( 'ColorInterpolator', 'OpenGLContext.scenegraph.interpolators.ColorInterpolator' )
69
+ Node( 'Cone', 'OpenGLContext.scenegraph.quadrics.Cone' )
70
+ Node( 'Coordinate', 'OpenGLContext.scenegraph.coordinate.Coordinate' )
71
+ Node( 'CoordinateInterpolator', 'OpenGLContext.scenegraph.interpolators.CoordinateInterpolator' )
72
+ Node( 'Cylinder', 'OpenGLContext.scenegraph.quadrics.Cylinder' )
73
+ Node( 'CylinderSensor', 'vrml.vrml97.basenodes.CylinderSensor' )
74
+ Node( 'DirectionalLight', 'OpenGLContext.scenegraph.light.DirectionalLight' )
75
+ Node( 'ElevationGrid', 'vrml.vrml97.basenodes.ElevationGrid' )
76
+ Node( 'Extrusion', 'vrml.vrml97.basenodes.Extrusion' )
77
+ Node( 'Fog', 'OpenGLContext.scenegraph.fog.Fog' )
78
+ Node( 'FontStyle', 'OpenGLContext.scenegraph.text.fontstyle3d.FontStyle' )
79
+ Node( 'Gear', 'OpenGLContext.scenegraph.gear.Gear' )
80
+ Node( 'Group', 'OpenGLContext.scenegraph.group.Group' )
81
+ Node( 'ImageTexture', 'OpenGLContext.scenegraph.imagetexture.ImageTexture' )
82
+ Node( 'IndexedFaceSet', 'OpenGLContext.scenegraph.indexedfaceset.IndexedFaceSet' )
83
+ Node( 'IndexedLineSet', 'OpenGLContext.scenegraph.indexedlineset.IndexedLineSet' )
84
+ Node( 'Inline', 'OpenGLContext.scenegraph.inline.Inline' )
85
+ Node( 'LOD', 'OpenGLContext.scenegraph.lod.LOD' )
86
+ Node( 'Material', 'OpenGLContext.scenegraph.material.Material' )
87
+ Node( 'MouseOver', 'OpenGLContext.scenegraph.mouseover.MouseOver' )
88
+ Node( 'MovieTexture', 'vrml.vrml97.basenodes.MovieTexture' )
89
+ Node( 'NavigationInfo', 'vrml.vrml97.basenodes.NavigationInfo' )
90
+ Node( 'Normal', 'vrml.vrml97.basenodes.Normal' )
91
+ Node( 'NormalInterpolator', 'vrml.vrml97.basenodes.NormalInterpolator' )
92
+ Node( 'OrientationInterpolator', 'OpenGLContext.scenegraph.interpolators.OrientationInterpolator' )
93
+ Node( 'PixelTexture', 'OpenGLContext.scenegraph.imagetexture.PixelTexture' )
94
+ Node( 'PlaneSensor', 'vrml.vrml97.basenodes.PlaneSensor' )
95
+ Node( 'PointLight', 'OpenGLContext.scenegraph.light.PointLight' )
96
+ Node( 'ParticleEmitter', 'OpenGLContext.scenegraph.particles.ParticleEmitter' )
97
+ Node( 'PointSet', 'OpenGLContext.scenegraph.pointset.PointSet' )
98
+ Node( 'PositionInterpolator', 'OpenGLContext.scenegraph.interpolators.PositionInterpolator' )
99
+ Node( 'ProximitySensor', 'vrml.vrml97.basenodes.ProximitySensor' )
100
+ Node( 'ScalarInterpolator', 'OpenGLContext.scenegraph.interpolators.ScalarInterpolator' )
101
+ Node( 'Shape', 'OpenGLContext.scenegraph.shape.Shape' )
102
+ Node( 'Sound', 'OpenGLContext.scenegraph.audio.Sound' )
103
+ Node( 'Sphere', 'OpenGLContext.scenegraph.quadrics.Sphere' )
104
+ Node( 'SphereSensor', 'vrml.vrml97.basenodes.SphereSensor' )
105
+ Node( 'SpotLight', 'OpenGLContext.scenegraph.light.SpotLight' )
106
+ Node( 'Switch', 'OpenGLContext.scenegraph.switch.Switch' )
107
+ Node( 'Teapot', 'OpenGLContext.scenegraph.teapot.Teapot' )
108
+ Node( 'Text', 'OpenGLContext.scenegraph.text.text.Text' )
109
+ Node( 'TextureCoordinate', 'vrml.vrml97.basenodes.TextureCoordinate' )
110
+ Node( 'TextureTransform', 'OpenGLContext.scenegraph.texturetransform.TextureTransform' )
111
+ Node( 'TimeSensor', 'OpenGLContext.scenegraph.timesensor.TimeSensor' )
112
+ Node( 'TouchSensor', 'vrml.vrml97.basenodes.TouchSensor' )
113
+ Node( 'Transform', 'OpenGLContext.scenegraph.transform.Transform' )
114
+ Node( 'Viewpoint', 'OpenGLContext.scenegraph.viewpoint.Viewpoint' )
115
+ Node( 'VisibilitySensor', 'vrml.vrml97.basenodes.VisibilitySensor' )
116
+ Node( 'WorldInfo', 'vrml.vrml97.basenodes.WorldInfo' )
117
+ Node( 'sceneGraph', 'OpenGLContext.scenegraph.scenegraph.SceneGraph' )
118
+ Node( 'IndexedPolygons', 'OpenGLContext.scenegraph.indexedpolygons.IndexedPolygons' )
119
+ Node( 'FontStyle3D', 'OpenGLContext.scenegraph.text.fontstyle3d.FontStyle3D' )
120
+ Node( 'SimpleBackground', 'OpenGLContext.scenegraph.simplebackground.SimpleBackground' )
121
+ Node( 'CubeBackground', 'OpenGLContext.scenegraph.cubebackground.CubeBackground' )
122
+ Node( 'SphereBackground', 'OpenGLContext.scenegraph.spherebackground.SphereBackground' )
123
+ Node( 'MMImageTexture', 'OpenGLContext.scenegraph.imagetexture.MMImageTexture' )
124
+ Node( 'Contour2D', 'OpenGLContext.scenegraph.nurbs.Contour2D' )
125
+ Node( 'NurbsCurve', 'OpenGLContext.scenegraph.nurbs.NurbsCurve' )
126
+ Node( 'NurbsCurve2D', 'OpenGLContext.scenegraph.nurbs.NurbsCurve2D' )
127
+ Node( 'NurbsDomainDistanceSample', 'OpenGLContext.scenegraph.nurbs.NurbsDomainDistanceSample' )
128
+ Node( 'NurbsSurface', 'OpenGLContext.scenegraph.nurbs.NurbsSurface' )
129
+ Node( 'NurbsToleranceSample', 'OpenGLContext.scenegraph.nurbs.NurbsToleranceSample' )
130
+ Node( 'Polyline2D', 'OpenGLContext.scenegraph.nurbs.Polyline2D' )
131
+ Node( 'TrimmedSurface', 'OpenGLContext.scenegraph.nurbs.TrimmedSurface' )
132
+
133
+ for suffix in ('1f','2f','3f','4f','m2','m3','m4','m2x3','m3x2','m2x4','m4x2','m3x4','m4x3'):
134
+ Node( 'FloatUniform'+suffix,'OpenGLContext.scenegraph.shaders.FloatUniform'+suffix )
135
+ for suffix in ('1i','2i','3i','4i'):
136
+ Node( 'IntUniform'+suffix,'OpenGLContext.scenegraph.shaders.IntUniform'+suffix )
137
+ Node( 'TextureUniform','OpenGLContext.scenegraph.shaders.TextureUniform' )
138
+ Node( 'TextureBufferUniform','OpenGLContext.scenegraph.shaders.TextureBufferUniform' )
139
+ Node( 'GLSLShader','OpenGLContext.scenegraph.shaders.GLSLShader' )
140
+ Node( 'GLSLObject','OpenGLContext.scenegraph.shaders.GLSLObject' )
141
+ Node( 'GLSLImport','OpenGLContext.scenegraph.shaders.GLSLImport' )
142
+
143
+ Node( 'ShaderAttribute','OpenGLContext.scenegraph.shaders.ShaderAttribute' )
144
+ Node( 'ShaderBuffer','OpenGLContext.scenegraph.shaders.ShaderBuffer' )
145
+ Node( 'ShaderIndexBuffer','OpenGLContext.scenegraph.shaders.ShaderIndexBuffer' )
146
+ Node( 'ShaderSlice','OpenGLContext.scenegraph.shaders.ShaderSlice' )
147
+ Node( 'ShaderGeometry','OpenGLContext.scenegraph.shaders.ShaderGeometry' )
148
+
149
+ Node( 'Shader','OpenGLContext.scenegraph.shaders.Shader' )
150
+ Node( 'ROUTE','vrml.route.ROUTE' )
151
+ Node( 'IS','vrml.route.IS' )
@@ -0,0 +1,2 @@
1
+ """Abstraction point allowing OpenGLContext to be used with numpy or Numeric"""
2
+ from vrml.arrays import *
OpenGLContext/atlas.py ADDED
@@ -0,0 +1,300 @@
1
+ """Texture atlas implementation"""
2
+ import math, weakref, logging
3
+ from OpenGL.GL import *
4
+ from OpenGLContext.arrays import zeros, array, dot, ArrayType
5
+ from OpenGLContext import texture
6
+ from vrml.vrml97 import transformmatrix
7
+
8
+ log = logging.getLogger( __name__ )
9
+
10
+ class _Strip( object ):
11
+ """Strip within the atlas which takes particular set of images"""
12
+ def __init__( self, atlas, height, yoffset ):
13
+ """Sets up the strip to receive images"""
14
+ self.atlas = atlas
15
+ self.height = height
16
+ self.width = 0
17
+ self.yoffset = yoffset
18
+ self.maps = []
19
+ def start_coord( self, x ):
20
+ """Do we have an empty space sufficient to fit image of width x?
21
+
22
+ return starting coordinate or -1 if not enough space...
23
+ """
24
+ last = 0
25
+ for map in self.maps:
26
+ referenced = map()
27
+ if referenced is not None:
28
+ if referenced.offset[0]-last >= x:
29
+ return last
30
+ else:
31
+ last = referenced.offset[0]+referenced.size[0]
32
+ if self.atlas.max_size-last >= x:
33
+ return last
34
+ return -1
35
+ def add( self, image, start=None ):
36
+ """Add the given PIL image to our atlas' image"""
37
+ x,y = image.size
38
+ if start is None:
39
+ start = self.start_coord( x )
40
+ offset = (start,self.yoffset)
41
+ map = Map( self.atlas, offset, (x,y), image )
42
+ self.maps.append( weakref.ref( map, self._remover( offset )) )
43
+ self.atlas.need_updates.append( weakref.ref(map) )
44
+ return map
45
+ def _remover( self, offset ):
46
+ def remover( *args ):
47
+ self.onRemove( )
48
+ return remover
49
+ def onRemove( self, *args, **named ):
50
+ """Remove map by offset (normally a weakref-release callback)"""
51
+ update = False
52
+ for mapRef in self.maps:
53
+ referenced = mapRef()
54
+ if referenced is None:
55
+ try:
56
+ self.maps.remove( mapRef )
57
+ except ValueError as err:
58
+ pass
59
+ update = True
60
+
61
+ class AtlasError( Exception ):
62
+ """Raised when we can't/shouldn't append to this atlas"""
63
+
64
+ class Atlas( object ):
65
+ """Collection of textures packed into a single texture
66
+
67
+ Texture atlases allow the rendering engine to reduce the
68
+ number of state-changes which occur during the rendering
69
+ process. They pack a large number of small textures into
70
+ a single large texture, producing offset/scale matrices to
71
+ use for modifying texture coordinates to map from the
72
+ original to the packed coordinates.
73
+ """
74
+ _local = None
75
+ _size = None
76
+ def __init__( self, components=4, dataType='B', max_size=4096 ):
77
+ self.components = components
78
+ self.dataType = dataType
79
+ self.strips = []
80
+ self.max_size = max_size
81
+ self.need_updates = []
82
+ self.texture = None
83
+ log.info(
84
+ 'Allocating a %s-component texture atlas of size %sx%s',
85
+ components,
86
+ max_size,max_size,
87
+ )
88
+
89
+ def add( self, image ):
90
+ """Insert a PIL image of values as a sub-texture
91
+
92
+ Has to find a place within the atlas to insert the
93
+ sub-texture and then return the offset/scale factors...
94
+ """
95
+ max_x = max_y = self.max_size
96
+ x,y = image.size
97
+ strip,start = self.choose_strip( max_x, max_y, x, y )
98
+ return strip.add( image, start=start )
99
+ def choose_strip( self, max_x,max_y, x,y ):
100
+ """Find the strip to which we should be added"""
101
+ candidates = [
102
+ s
103
+ for s in self.strips
104
+ if (
105
+ s.height >= y
106
+ )
107
+ ]
108
+ for strip in candidates:
109
+ if strip.height == y:
110
+ start = strip.start_coord( x )
111
+ if start > -1:
112
+ return strip, start
113
+ for strip in candidates:
114
+ strip_mag = math.floor(math.log( strip.height, 2 ))
115
+ img_mag = math.floor(math.log( y, 2 ))
116
+ if strip_mag == img_mag:
117
+ start = strip.start_coord( x )
118
+ if start > -1:
119
+ return strip, start
120
+ if self.strips:
121
+ last = self.strips[-1]
122
+ current_height = last.yoffset + last.height
123
+ else:
124
+ current_height = 0
125
+ if current_height + y > max_y:
126
+ raise AtlasError( """Insufficient space to store in this atlas""" )
127
+ strip = _Strip( self, height=y, yoffset= current_height )
128
+ self.strips.append( strip )
129
+ start = strip.start_coord( x )
130
+ return strip, start
131
+
132
+ def size( self ):
133
+ if self._size is None:
134
+ x = y = self.max_size
135
+ self._size = (x,y,self.components)
136
+ return self._size
137
+
138
+ def render( self ):
139
+ """Render this texture to the context"""
140
+ if self.texture is None:
141
+ format = [0, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA ][self.components]
142
+ self.texture = texture.Texture(format=format)
143
+ x,y,d = self.size()
144
+ self.texture.store(
145
+ d,
146
+ format,
147
+ x,y,
148
+ None
149
+ )
150
+ self.texture()
151
+ needs = self.need_updates[:]
152
+ del self.need_updates[:len(needs)]
153
+ for need in needs:
154
+ need = need()
155
+ if need is not None:
156
+ need.update( self.texture )
157
+ return self.texture
158
+ def cached( self, mode ):
159
+ """Get cached version of this texture
160
+
161
+ Note: currently we do *not* properly use mode-level caching
162
+ for the texture object
163
+ """
164
+ return self.render()
165
+ def debugImageTexture( self, mode ):
166
+ """Create a debugging image texture for this texture atlas
167
+ """
168
+ from OpenGLContext.scenegraph.imagetexture import ImageTexture,Image
169
+ from OpenGLContext.texture import NumpyAdapter
170
+ from vrml import protofunctions
171
+ format = NumpyAdapter.shapeToMode( self.components )
172
+ instance = ImageTexture(
173
+ image = Image.new(format, (1,1), '#ffff00'),
174
+ )
175
+ holder = mode.cache.holder(instance, self.texture)
176
+ return instance
177
+
178
+ class Map( object ):
179
+ """Object representing a sub-texture within a texture atlas
180
+
181
+ A Map object is a dependent version of an OpenGLContext.texture.Texture
182
+ object, i.e. it tries to offer the same API, but with support for
183
+ Atlas-based maps instead of stand-alone ones.
184
+ """
185
+ _matrix = None
186
+ _coords = None
187
+ _uploaded = False
188
+ def __init__( self, atlas, offset, size, image ):
189
+ self.atlas = atlas
190
+ self.offset = offset
191
+ self.size = size
192
+ self.image = image
193
+ self.components = self.atlas.components
194
+ def matrix( self ):
195
+ """Calculate a 4x4 transform matrix for texcoords
196
+
197
+ To manipulate texture coordinates with this matrix
198
+ they need to be in homogenous coordinates, i.e. a
199
+ "regular" 2d coordinate of (x,y) becomes (x,y,0.0,1.0)
200
+ so that it can pick up the translations.
201
+
202
+ dot( coord, matrix ) produces the transformed
203
+ coordinate for processing.
204
+
205
+ returns 4x4 translation matrix
206
+ """
207
+ if self._matrix is None:
208
+ # translate by self.offset/atlas.size
209
+ # scale by self.size/atlas.size
210
+ tx,ty,d = self.atlas.size()
211
+ tx,ty = float(tx),float(ty)
212
+ x,y = self.offset
213
+ sx,sy = self.size
214
+ self._matrix = transformmatrix.transformMatrix (
215
+ translation = (x/tx,y/ty,0),
216
+ scale = (sx/tx,sy/ty,1),
217
+ )
218
+ return self._matrix
219
+ def coords( self ):
220
+ """Return our bottom-left and top-right coordinate pairs"""
221
+ if self._coords is None:
222
+ tx,ty,d = self.atlas.size()
223
+ tx,ty = float(tx),float(ty)
224
+ x,y = self.offset
225
+ sx,sy = self.size
226
+ self._coords = array( ((x/tx,y/ty),((x+sx)/tx,(y+sy)/ty)), 'f')
227
+ return self._coords
228
+
229
+ def replace( self, image ):
230
+ """Replace our current image with given (PIL) image"""
231
+ self._uploaded = False
232
+ self.image = image
233
+ self.atlas.need_updates.append( weakref.ref(self) )
234
+ def update( self, texture ):
235
+ """Update texture with (new) data in self.image
236
+
237
+ This just calls texture.update with our metadata
238
+ in order to do the actual copy of the data-pointer.
239
+ """
240
+ texture.update(
241
+ self.offset, self.size,
242
+ texture.pilAsString( self.image),
243
+ )
244
+ self._uploaded = True
245
+ @property
246
+ def texture( self ):
247
+ """Retrieve our texture"""
248
+ return self.atlas.cached( None )
249
+ def __call__( self ):
250
+ """Enable/call our texture"""
251
+ self.atlas.render()
252
+ # should also load our texture-transform matrix.
253
+ glMatrixMode( GL_TEXTURE )
254
+ glLoadMatrixd( self.matrix() )
255
+ glMatrixMode( GL_MODELVIEW )
256
+
257
+ class AtlasManager( object ):
258
+ """Collection of atlases within the renderer"""
259
+ def __init__( self, max_size=4096, max_child_size=128 ):
260
+ self.components = {}
261
+ self.max_size = max_size
262
+ self.max_child_size = max_child_size
263
+ FORMAT_MAPPING = {
264
+ 'L':(1,GL_LUMINANCE),
265
+ 'LA':(2,GL_LUMINANCE_ALPHA),
266
+ 'RGB':(3,GL_RGB),
267
+ 'RGBA':(4,GL_RGBA),
268
+ }
269
+ def formatToComponents( self, format ):
270
+ """Convert PIL format to component count"""
271
+ return self.FORMAT_MAPPING[ format ][0]
272
+ def add( self, image ):
273
+ """Add the given image to the texture atlas"""
274
+ if isinstance( image, ArrayType ):
275
+ image = texture.NumpyAdapter( image )
276
+ x,y = image.size
277
+ if x > self.max_child_size:
278
+ raise AtlasError( """X size (%s) > %s"""%( x,self.max_child_size ) )
279
+ if y > self.max_child_size:
280
+ raise AtlasError( """Y size (%s) > %s"""%( y,self.max_child_size ) )
281
+ d = self.formatToComponents( image.mode )
282
+ atlases = self.components.setdefault( d, [])
283
+ for atlas in atlases:
284
+ try:
285
+ return atlas.add( image )
286
+ except AtlasError as err:
287
+ pass
288
+ atlas = Atlas( d, max_size=self.max_size or self.calculate_max_size() )
289
+ atlases.append( atlas )
290
+ return atlas.add( image )
291
+ _MAX_MAX_SIZE = 4096
292
+ def calculate_max_size( self ):
293
+ """Calculate the maximum size of a texture
294
+
295
+ Note that this might, for instance, assume a
296
+ single-component texture or some similarly inappropriate
297
+ value...
298
+ """
299
+ self.max_size = min( (glGetIntegerv(GL_MAX_TEXTURE_SIZE), self._MAX_MAX_SIZE) )
300
+ return self.max_size
@@ -0,0 +1,32 @@
1
+ """Giving an OpenGLContext context an ear.
2
+
3
+ The sound itself is :mod:`omi_audio`: the ``KHR_audio_emitter`` data model,
4
+ every gain curve, the clip cache, the numpy mixer, the device seam and the
5
+ engine that ties them together. None of that knows what a scenegraph is, and
6
+ none of it belongs here.
7
+
8
+ What is here is the two seams between that engine and a context:
9
+
10
+ ========================= ====================================================
11
+ :mod:`~.scene` One engine per context, opened on the first frame
12
+ that has something audible in it, and driven once a
13
+ frame from the camera and the render pass's
14
+ ``Auditory`` node paths.
15
+ :mod:`~.settings` :class:`~.settings.AudioSettings`, the player's own
16
+ switch, volume and voice budget, declared as a node
17
+ on the :class:`~OpenGLContext.contextdefinition.ContextDefinition`
18
+ so it validates, serialises and generates its own
19
+ settings page like every other field group.
20
+ ========================= ====================================================
21
+
22
+ The nodes that put a sound *in* a scene are
23
+ :mod:`OpenGLContext.scenegraph.audio` -- ``AudioEmitter``, ``AudioSource`` and
24
+ VRML97's ``Sound`` -- and the glTF loader reads ``KHR_audio_emitter`` blocks
25
+ into them through :mod:`OpenGLContext.loaders.gltf.scene`.
26
+
27
+ Sound is **optional and never fatal**. ``miniaudio`` may be absent and a device
28
+ may fail to open; both end in one warning and a silent run, so a machine with no
29
+ sound card is simply a machine with no sound.
30
+
31
+ See ``docs/audio.html`` for the data-flow diagrams and a worked example.
32
+ """
@@ -0,0 +1,130 @@
1
+ """Giving a context an ear, and driving the scene's sounds once a frame.
2
+
3
+ This is the whole of the seam between the render loop and :mod:`omi_audio`. The
4
+ render pass already collects every :class:`~vrml.vrml97.nodetypes.Auditory` node
5
+ path and already knows where the camera is; :func:`update` turns those two facts
6
+ into sound.
7
+
8
+ **Silence costs nothing.** A context gets no engine, and therefore opens no
9
+ device and starts no audio thread, until a frame is drawn with something audible
10
+ in it. A scene with no sounds -- which is most test scenes and every existing
11
+ OpenGLContext demo -- is untouched by any of this.
12
+
13
+ The engine hangs off the context rather than being a global, because two windows
14
+ are two listeners, and it is held weakly so closing a window does not leak a
15
+ device.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import logging
21
+ import time
22
+ import weakref
23
+ from typing import Any, Dict, Optional, Sequence
24
+
25
+ from omi_audio.device import open_device
26
+ from omi_audio.engine import AudioEngine
27
+
28
+ from OpenGLContext.audio.settings import settings_for
29
+ from OpenGLContext.scenegraph.audio import stop_scene_audio, update_scene_audio
30
+
31
+ log = logging.getLogger(__name__)
32
+
33
+ #: Engines by context. Weak, so a closed window's device goes with it; keyed by
34
+ #: the context itself rather than stored on it so a context class needs to know
35
+ #: nothing about audio to have some.
36
+ _engines: "weakref.WeakKeyDictionary[Any, AudioEngine]" = weakref.WeakKeyDictionary()
37
+
38
+
39
+ def existing_engine(context: Any) -> Optional[AudioEngine]:
40
+ """The engine ``context`` already has, or None. Never makes one."""
41
+ return _engines.get(context)
42
+
43
+
44
+ def enabled(context: Any) -> bool:
45
+ """Whether this context's settings allow sound at all."""
46
+ return bool(settings_for(context).enabled)
47
+
48
+
49
+ def engine_for(context: Any) -> Optional[AudioEngine]:
50
+ """The engine for ``context``, opened on first ask.
51
+
52
+ Returns None where the context's definition has audio switched off, which is
53
+ the one case a caller has to handle -- and handling it is doing nothing.
54
+ """
55
+ if not enabled(context):
56
+ return None
57
+ engine = _engines.get(context)
58
+ if engine is None:
59
+ settings = settings_for(context)
60
+ engine = AudioEngine(device=open_device(), voices=int(settings.voices))
61
+ engine.volume = settings.volume
62
+ _engines[context] = engine
63
+ return engine
64
+
65
+
66
+ def close(context: Any) -> None:
67
+ """Release ``context``'s engine and its device. Safe if it had none."""
68
+ engine = _engines.pop(context, None)
69
+ if engine is not None:
70
+ engine.close()
71
+
72
+
73
+ def update(context: Any, paths: Sequence[Any], now: Optional[float] = None) -> int:
74
+ """Keep ``context``'s sounds in step with its camera, for one frame.
75
+
76
+ ``paths`` are the render pass's collected ``Auditory`` node paths. An empty
77
+ sequence returns immediately **without opening a device**, which is what
78
+ makes sound free for a scene that has none.
79
+
80
+ ``now`` is absolute seconds, because VRML97's ``startTime`` and ``stopTime``
81
+ are absolute; it is taken from the wall clock when not given.
82
+
83
+ Returns how many nodes were driven, for a debug overlay.
84
+ """
85
+ if not paths or not enabled(context):
86
+ return 0
87
+ engine = engine_for(context)
88
+ if engine is None:
89
+ return 0
90
+ # The *player's* volume, read every frame: the settings screen writes the
91
+ # field, and a volume slider that only takes effect on the next launch is a
92
+ # volume slider nobody uses. The application's own `master_gain` is left
93
+ # alone -- writing over it here would make an application's mix level last
94
+ # exactly one frame.
95
+ engine.volume = settings_for(context).volume
96
+ platform = _view_platform(context)
97
+ if platform is not None:
98
+ engine.listen(platform)
99
+ return update_scene_audio(engine, paths,
100
+ time.time() if now is None else now)
101
+
102
+
103
+ def stop(context: Any, paths: Sequence[Any]) -> None:
104
+ """Silence every sound in a scene that is going away."""
105
+ stop_scene_audio(paths)
106
+ engine = _engines.get(context)
107
+ if engine is not None:
108
+ engine.stop_all()
109
+
110
+
111
+ def _view_platform(context: Any) -> Any:
112
+ """The context's camera, however it exposes one."""
113
+ getter = getattr(context, 'getViewPlatform', None)
114
+ if getter is not None:
115
+ return getter()
116
+ return getattr(context, 'platform', None)
117
+
118
+
119
+ def describe(context: Any) -> Dict[str, Any]:
120
+ """What this context's audio is doing, for a debug overlay."""
121
+ engine = _engines.get(context)
122
+ if engine is None:
123
+ return {'audio': 'off' if not enabled(context) else 'idle'}
124
+ return {
125
+ 'audio': 'silent' if engine.silent else '%d Hz' % (engine.sample_rate,),
126
+ 'voices': engine.active_voices,
127
+ 'volume': round(engine.volume, 2),
128
+ 'mix': round(engine.master_gain, 2),
129
+ 'muffle': round(engine.muffle, 2),
130
+ }