Compare commits

..

677 Commits

Author SHA1 Message Date
3bee97a560 Update leenkx/blender/lnx/material/cycles.py 2025-11-14 17:41:39 +00:00
4f4f28d62f Merge pull request 'main' (#111) from Onek8/LNXSDK:main into main
Reviewed-on: #111
2025-11-06 16:32:50 +00:00
7076fb6b7e Update leenkx/blender/lnx/material/cycles.py 2025-11-06 16:29:46 +00:00
b72a22b5e9 Update leenkx/blender/lnx/props_ui.py 2025-11-06 16:17:18 +00:00
b265ab863c Update leenkx/blender/lnx/props.py 2025-11-06 16:13:39 +00:00
48f5575e4e Update leenkx/Sources/leenkx/logicnode/OnContactNode.hx 2025-10-03 07:56:12 +00:00
f2c4be6336 Update leenkx/Sources/leenkx/logicnode/HasContactNode.hx 2025-10-03 07:55:46 +00:00
2ddc938db8 Update leenkx/Sources/leenkx/logicnode/AnyContactNode.hx 2025-10-03 07:55:14 +00:00
5eb735ada2 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-10-03 07:52:01 +00:00
9894cc20f2 Update leenkx/Sources/leenkx/trait/physics/PhysicsWorld.hx 2025-10-03 07:51:32 +00:00
dbe6d0829a Add leenkx/Sources/leenkx/trait/physics/PhysicsCache.hx 2025-10-03 07:51:07 +00:00
6f383e2ab2 Update leenkx/Sources/leenkx/trait/physics/PhysicsWorld.hx 2025-10-03 05:38:54 +00:00
5c2d29d7ce Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-10-03 05:37:50 +00:00
28579e14d7 Update leenkx/Sources/leenkx/logicnode/AnyContactNode.hx 2025-10-03 05:37:06 +00:00
2ec6f43cc5 Update leenkx/Sources/leenkx/logicnode/OnContactNode.hx 2025-10-03 05:36:14 +00:00
027021815a Update leenkx/Sources/leenkx/logicnode/HasContactNode.hx 2025-10-03 05:35:48 +00:00
b9b387803f Add leenkx/blender/lnx/logicnode/physics/LN_any_contact.py 2025-10-03 05:06:23 +00:00
e05d9d0237 Update leenkx/Sources/leenkx/logicnode/HasContactNode.hx 2025-10-03 05:04:48 +00:00
c908e6cad2 Update leenkx/Sources/leenkx/logicnode/OnContactNode.hx 2025-10-03 05:04:18 +00:00
506a0a0245 Add leenkx/Sources/leenkx/logicnode/AnyContactNode.hx 2025-10-03 05:03:29 +00:00
5cf33724e4 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-10-03 05:02:28 +00:00
ac5aa3d19c Merge pull request 'Hashlink fix' (#110) from Onek8/LNXSDK:main into main
Reviewed-on: #110
2025-10-03 03:21:56 +00:00
0c534ee632 Update leenkx/Sources/iron/object/ParticleSystem.hx 2025-10-01 01:42:51 +00:00
e3e7855d26 Merge pull request 'main' (#109) from Onek8/LNXSDK:main into main
Reviewed-on: #109
2025-09-30 05:59:23 +00:00
f7917974f8 Update leenkx/Sources/iron/object/ObjectAnimation.hx 2025-09-30 05:52:44 +00:00
fa2d8f05d5 Update leenkx/Sources/iron/object/ObjectAnimation.hx 2025-09-30 05:35:50 +00:00
73fcb55acc Update leenkx/blender/lnx/props_traits.py 2025-09-29 05:28:13 +00:00
c24baa3364 Update leenkx/blender/lnx/props_traits_props.py 2025-09-29 05:27:43 +00:00
4517c4863f Merge pull request 'Downward support to 2.8 LTS!!' (#108) from Onek8/LNXSDK:main into main
Reviewed-on: #108
2025-09-28 20:02:58 +00:00
1299306e09 Update leenkx.py 2025-09-28 20:01:00 +00:00
f97d8fd846 Blender 2.8 - 4.5 Support 2025-09-28 12:44:04 -07:00
8f8d4b1376 Update leenkx/blender/lnx/props_traits.py 2025-09-28 00:09:57 +00:00
a926fa8dbb Update leenkx/blender/lnx/nodes_logic.py 2025-09-27 03:03:08 +00:00
6c3efa6c83 Update leenkx/blender/lnx/props_ui.py 2025-09-24 01:54:38 +00:00
21afad6d09 Update leenkx/blender/lnx/exporter.py 2025-09-24 01:53:43 +00:00
04c6983a09 Update leenkx/Sources/iron/data/SceneFormat.hx 2025-09-24 01:52:47 +00:00
45966ef0bb Update leenkx/blender/lnx/props.py 2025-09-24 01:51:11 +00:00
a72edc6203 Update leenkx/Sources/iron/object/ParticleSystem.hx 2025-09-24 01:50:03 +00:00
6af1ef2df1 Update leenkx/blender/lnx/props_ui.py 2025-09-24 01:33:47 +00:00
46e3047877 Update leenkx/blender/lnx/props.py 2025-09-23 19:57:53 +00:00
de74af215a Merge pull request 'main' (#107) from Onek8/LNXSDK:main into main
Reviewed-on: #107
2025-09-23 17:54:11 +00:00
b6e96553c2 Update leenkx/blender/lnx/lightmapper/utility/build.py 2025-09-19 22:52:01 +00:00
58e009f709 Terrain Generation fix 2025-09-19 21:17:58 +00:00
e88f101ca6 t3du - Particle info random 2025-09-19 19:40:49 +00:00
d28d59b9e6 t3du - Particle info random 2025-09-19 19:38:12 +00:00
a4398c7279 t3du - Particle info random 2025-09-19 19:31:45 +00:00
abedfd799e t3du - Fix World Errors 2025-09-19 19:28:54 +00:00
4520422f6b t3du - Fix World Errors 2025-09-19 19:27:02 +00:00
88418c06c3 t3du - Fix World Errors 2025-09-19 19:25:30 +00:00
aedc2783ab t3du - Labels for finding nodes 2025-09-19 19:22:45 +00:00
1505414c4c t3du - Labels for finding nodes 2025-09-19 19:19:25 +00:00
fa818602c4 t3du - Labels for finding nodes 2025-09-19 19:18:05 +00:00
79dc458671 t3du - Labels for finding nodes 2025-09-19 19:15:41 +00:00
8e635fb1e9 t3du - Labels for finding nodes 2025-09-19 19:11:47 +00:00
4c2e6ab26a t3du - Probabilistic Index Node 2025-09-19 19:09:18 +00:00
2371e3777e t3du - Probabilistic Index Node 2025-09-19 19:08:03 +00:00
b458b77e5c moisesjpelaez - Include external blend files on build 2025-09-19 19:04:43 +00:00
9b76f8cca9 moisesjpelaez - Include external blend files on build 2025-09-19 19:03:22 +00:00
5f2acb209e moisesjpelaez - Include external blend files on build 2025-09-19 19:00:50 +00:00
6fc446e7a9 moisesjpelaez - General Fixes 2025-09-19 18:54:44 +00:00
71e57026e1 moisesjpelaez - General Fixes 2025-09-19 18:53:25 +00:00
5288a98440 moisesjpelaez - General Fixes 2025-09-19 18:49:09 +00:00
35e346be39 moisesjpelaez - General Fixes 2025-09-19 18:39:54 +00:00
843ef0b058 moisesjpelaez - General Fixes 2025-09-19 18:39:14 +00:00
177890bf39 moisesjpelaez - General Fixes 2025-09-19 18:37:01 +00:00
9ac37e6dc7 moisesjpelaez - General Fixes 2025-09-19 18:34:42 +00:00
e697437778 moisesjpelaez - General Fixes 2025-09-19 18:33:44 +00:00
c94fc0fd97 moisesjpelaez - General Fixes 2025-09-19 18:29:52 +00:00
cd0a6f6788 Update leenkx/Sources/iron/data/SceneFormat.hx 2025-09-19 18:28:19 +00:00
4400e0e9c8 moisesjpelaez - General Fixes 2025-09-19 18:27:22 +00:00
20cf07cfc3 moisesjpelaez - General Fixes 2025-09-19 18:25:54 +00:00
1939f19c05 moisesjpelaez - General Fixes 2025-09-19 18:24:19 +00:00
0d2b152ccb moisesjpelaez - General Fixes 2025-09-19 18:15:23 +00:00
7f58e0fc85 moisesjpelaez - General Fixes 2025-09-19 18:13:00 +00:00
0e4a6575c7 moisesjpelaez - General Material Updates 2025-09-19 18:09:04 +00:00
024676f43a moisesjpelaez - General Material Updates 2025-09-19 17:43:54 +00:00
8fe758862c moisesjpelaez - General Material Updates 2025-09-19 17:35:59 +00:00
1f3d1b47ae moisesjpelaez - General Material Updates 2025-09-19 17:34:27 +00:00
f659a3c2be moisesjpelaez - General Material Updates 2025-09-19 17:32:38 +00:00
6eeb9017d4 moisesjpelaez - General Material Updates 2025-09-19 17:30:42 +00:00
afe89c3834 Update leenkx/Sources/iron/data/ShaderData.hx 2025-09-19 17:27:14 +00:00
8b695f72bb moisesjpelaez - General Material Updates 2025-09-19 17:25:03 +00:00
3d99fa60c0 moisesjpelaez - General Material Updates 2025-09-19 17:23:42 +00:00
43be7729ba moisesjpelaez - Tween var 2025-09-19 17:17:41 +00:00
de0b1075c2 moisesjpelaez - Time Fix 2025-09-19 17:13:16 +00:00
c7aba23fa4 t3du - Fix DOF condition 2025-09-19 17:08:21 +00:00
881f3267cc t3du - Fix DOF condition 2025-09-19 17:06:10 +00:00
19b79d61c7 ObiNoWanKenobi - FirstPersonController Changes 2025-09-19 17:03:20 +00:00
fcbab54a0c moisesjpelaez - General Fixes 2025-09-19 16:57:49 +00:00
8fd05d5514 Update leenkx/Sources/leenkx/renderpath/RenderPathForward.hx 2025-08-28 19:21:48 +00:00
ad4013ed75 Update leenkx/Sources/leenkx/renderpath/RenderPathForward.hx 2025-08-28 19:11:31 +00:00
8ac567b57b Merge pull request 'Update leenkx/Shaders/std/conetrace.glsl' (#104) from Onek8/LNXSDK:main into main
Reviewed-on: #104
2025-08-14 23:01:04 +00:00
43b7ae7060 Update leenkx/Shaders/std/conetrace.glsl 2025-08-14 22:58:57 +00:00
29e9e71a6a Merge pull request 'main' (#103) from Onek8/LNXSDK:main into main
Reviewed-on: #103
2025-08-14 21:29:54 +00:00
bfb85b0a3b Update leenkx/Sources/iron/Scene.hx 2025-08-14 20:29:28 +00:00
ef99b800e0 Update leenkx/Sources/iron/App.hx 2025-08-14 20:27:20 +00:00
7cca955fc5 Update leenkx/Sources/iron/App.hx 2025-08-14 20:26:33 +00:00
7e7bbd5eae merge upstream 2025-08-14 20:24:23 +00:00
c31b2a18ad Update leenkx/blender/lnx/logicnode/draw/LN_draw_string.py 2025-08-14 19:03:28 +00:00
fb47bf2564 Update leenkx/blender/lnx/logicnode/draw/LN_draw_Text_Area_string.py 2025-08-14 19:01:59 +00:00
7ae6750620 Update leenkx/blender/lnx/logicnode/camera/LN_set_camera_start_end.py 2025-08-14 19:00:58 +00:00
5b87010f76 Update leenkx/Sources/leenkx/trait/internal/DebugConsole.hx 2025-08-14 18:58:52 +00:00
97e952fc15 Update leenkx/Sources/leenkx/logicnode/DrawStringNode.hx 2025-08-14 18:57:13 +00:00
b440539d65 Merge pull request 'main' (#102) from Onek8/LNXSDK:main into main
Reviewed-on: #102
2025-07-23 17:34:02 +00:00
60a9db6459 Update api/api.hxml 2025-07-22 21:54:56 +00:00
3b5a93c92a Update leenkx/Sources/leenkx/trait/PhysicsBreak.hx 2025-07-22 21:51:25 +00:00
4af990796e t3du - Add TSceneFormat as Trait property type 2025-07-21 23:27:34 +00:00
9fb4916c3c t3du - Add TSceneFormat as Trait property type 2025-07-21 23:24:30 +00:00
f61d5833bb Update leenkx/blender/lnx/exporter.py 2025-07-21 23:15:59 +00:00
40b52be713 t3du - Add TSceneFormat as Trait property type 2025-07-21 23:12:43 +00:00
07d8422f22 Merge pull request 'Update leenkx/Sources/iron/system/Time.hx' (#101) from Onek8/LNXSDK:main into main
Reviewed-on: #101
2025-07-19 20:23:46 +00:00
7179d42b27 Update leenkx/Sources/iron/system/Time.hx 2025-07-19 20:07:08 +00:00
99a5d7d445 Merge pull request 'Update leenkx/Sources/leenkx/logicnode/SetObjectDelayedLocationNode.hx' (#100) from Onek8/LNXSDK:main into main
Reviewed-on: #100
2025-07-17 15:58:08 +00:00
5e0acd3d5d Update leenkx/Sources/leenkx/logicnode/SetObjectDelayedLocationNode.hx 2025-07-16 22:18:14 +00:00
f4077e461b Merge pull request 'Tangazo - Once Node + Set Object Delayed Location Node [ Additional Clean Handler ]' (#99) from Onek8/LNXSDK:main into main
Reviewed-on: #99
2025-07-16 05:23:34 +00:00
28943f1522 Add leenkx/Sources/leenkx/logicnode/SetObjectDelayedLocationNode.hx 2025-07-16 05:15:59 +00:00
df4feac132 Add leenkx/blender/lnx/logicnode/object/LN_set_object_delayed_location.py 2025-07-16 05:14:28 +00:00
82412dbf81 Add leenkx/Sources/leenkx/logicnode/OnceNode.hx 2025-07-15 22:07:02 +00:00
6afc209db7 Add leenkx/blender/lnx/logicnode/logic/LN_once.py 2025-07-15 22:06:11 +00:00
e9aae53be9 t3du - Fix attribute error rp_gi 2025-07-15 19:05:14 +00:00
a65675ef75 Update leenkx/blender/lnx/handlers.py 2025-07-15 17:57:38 +00:00
8f073c5ae1 merge upstream 2025-07-15 17:56:41 +00:00
08d08e42d9 Merge pull request 'improved mouse look node and added missing rigid body settings in Properties > physics > leenkx Props' (#98) from wuaieyo/LNXSDK:main into main
Reviewed-on: #98
2025-07-15 02:59:53 +00:00
a1ee335c68 removed the translation daping and rotation dampign because they would override the alreayd existedt under Dynamics panel 2025-07-13 04:23:51 +02:00
de6bf8a08a added last needed important rigid body settings in the blender RB leenkx settings for game engine ? like min max velocity,damping and lock translation and rotationboolean settings 2025-07-11 19:21:01 +02:00
b9848cd2dc revert e922cc38e6
revert Update leenkx/Shaders/std/shadows.glsl
2025-07-09 23:20:46 +00:00
e922cc38e6 Update leenkx/Shaders/std/shadows.glsl 2025-07-09 23:17:55 +00:00
57f0e937d0 fixed properties numbering, comments and LNXfactor to LNXFloat 2025-07-08 22:48:16 +02:00
e234c8615c merge upstream 2025-07-08 20:01:27 +00:00
e594518e57 Merge pull request 'main' (#96) from Onek8/LNXSDK:main into main
Reviewed-on: #96
2025-07-06 17:29:11 +00:00
a41be0f436 Update leenkx/blender/lnx/material/cycles_nodes/nodes_input.py 2025-07-06 17:23:04 +00:00
1306033b36 Update leenkx/Sources/leenkx/logicnode/SetParticleDataNode.hx 2025-07-05 22:03:54 +00:00
eee0011cdd Update leenkx/Sources/leenkx/logicnode/GetWorldOrientationNode.hx 2025-07-05 21:52:57 +00:00
315ac0bd16 Update lib/aura/Sources/aura/dsp/panner/StereoPanner.hx 2025-07-05 21:49:10 +00:00
f289e6f89c merge upstream 2025-07-03 07:46:23 +00:00
700d236bf1 Merge pull request 'main' (#94) from Onek8/LNXSDK:main into main
Reviewed-on: #94
2025-07-03 04:12:51 +00:00
f228eab8d3 Add leenkx/Sources/leenkx/logicnode/SetAudioPositionNode.hx 2025-07-03 03:55:23 +00:00
863d884b76 Add leenkx/Sources/leenkx/logicnode/GetAudioPositionNode.hx 2025-07-03 03:54:54 +00:00
34e0f5a282 Add leenkx/blender/lnx/logicnode/custom/LN_set_audio_position.py 2025-07-03 03:53:59 +00:00
45e2e52008 Add leenkx/blender/lnx/logicnode/custom/LN_get_audio_position.py 2025-07-03 03:52:39 +00:00
444a215e63 made default resolution adaptive sensiticity because makes more sense, removed other things since no difference and dunno 2025-07-03 05:27:24 +02:00
fb2d2a1a7c Add leenkx/Sources/leenkx/logicnode/SetPositionSpeakerNode.hx 2025-07-03 01:23:13 +00:00
f88c04abea Add leenkx/Sources/leenkx/logicnode/GetPositionSpeakerNode.hx 2025-07-03 01:22:44 +00:00
6fdd4b3f70 Add leenkx/blender/lnx/logicnode/sound/LN_get_position_speaker.py 2025-07-03 01:21:37 +00:00
a389c27d75 Add leenkx/blender/lnx/logicnode/sound/LN_set_position_speaker.py 2025-07-03 01:20:22 +00:00
1909c3da9f Update leenkx/blender/lnx/material/cycles.py 2025-07-02 15:29:05 +00:00
5824bd91aa Merge pull request 't3du [ Repe ] - VR Code' (#93) from Onek8/LNXSDK:main into main
Reviewed-on: #93
2025-07-02 05:19:25 +00:00
43fe559eef t3du - Restore VR code 2025-07-02 05:16:53 +00:00
12c09545ce t3du - Restore VR code 2025-07-02 05:15:34 +00:00
0e60951ec9 t3du - Restore VR code 2025-07-02 05:14:05 +00:00
ccb8b358d3 t3du - Restore VR code 2025-07-02 05:11:23 +00:00
1a8586777b Merge pull request 'main' (#91) from Onek8/LNXSDK:main into main
Reviewed-on: #91
2025-06-30 21:01:50 +00:00
3721c774a1 Update leenkx/blender/lnx/material/node_meta.py 2025-06-30 20:59:56 +00:00
a58fba408d Update leenkx/blender/lnx/material/cycles.py 2025-06-30 20:58:56 +00:00
268fba6cd5 Merge pull request 'main' (#90) from Onek8/LNXSDK:main into main
Reviewed-on: #90
2025-06-30 20:39:41 +00:00
4ab14ce6c8 merge upstream 2025-06-30 20:39:14 +00:00
9023e8d1da Merge pull request 'added Mouse Look node for FSP style movement of object like camera...' (#89) from wuaieyo/LNXSDK:main into main
Reviewed-on: #89
2025-06-30 20:37:10 +00:00
b58c7a9632 Update leenkx/blender/lnx/material/cycles.py 2025-06-30 20:33:04 +00:00
99b70622f5 Update leenkx/blender/lnx/material/node_meta.py 2025-06-30 20:31:50 +00:00
647b73b746 added Mouse Look node for FSP style movement of object like camera... 2025-06-30 06:35:06 +02:00
935c30ec08 Merge pull request 'main' (#88) from wuaieyo/LNXSDK:main into main
Reviewed-on: #88
2025-06-27 22:39:32 +00:00
0b0d597f89 merge upstream 2025-06-27 22:31:19 +00:00
d5878afb30 Merge pull request 't3du [ Repe ] + Moisesjpelaez Fixes' (#87) from Onek8/LNXSDK:main into main
Reviewed-on: #87
2025-06-27 22:28:35 +00:00
96b55a1a56 t3du - Add SetLightShadowNode for controlling light shadows 2025-06-27 18:03:37 +00:00
91b3072305 t3du - Add SetLightShadowNode for controlling light shadows 2025-06-27 17:57:26 +00:00
1d0b338d92 t3du - Particle export: add support for linked particle info 2025-06-27 17:52:19 +00:00
8e83c0d0d0 moisesjpelaez - Fix linked particle's render object vertex shader export 2025-06-27 17:49:35 +00:00
927baec4df t3du - Show world name in debug console 2025-06-27 17:46:36 +00:00
f5c9e70d1a 1. added local rotation so that if the source object is child then it would still align to the target object. 2. removed rotation output socket since is not really needed. 2025-06-26 03:05:11 +02:00
0423a735fc Update leenkx/Sources/leenkx/logicnode/PlayAnimationTreeNode.hx 2025-06-24 18:43:30 +00:00
bd413917fc Merge pull request 'main' (#84) from Onek8/LNXSDK:main into main
Reviewed-on: #84
2025-06-24 18:18:27 +00:00
852377f60d merge upstream 2025-06-24 18:07:23 +00:00
e17e9a8e35 Merge pull request 'added new set look at rotation node' (#83) from wuaieyo/LNXSDK:main into main
Reviewed-on: #83
2025-06-24 18:06:48 +00:00
4055c979a1 add new Set Look At Rotation Node for making logic nodes great again 2025-06-24 19:47:03 +02:00
06b003ecdb revert 14cf5cebed
revert add new node called Set Look at Rotation
2025-06-24 17:38:18 +00:00
fd7f215bb2 .gitattributes 2025-06-24 17:31:59 +00:00
6a1df9ec46 merge upstream 2025-06-24 17:31:29 +00:00
deccac3c46 Merge pull request '.gitignore' (#81) from Onek8/LNXSDK:main into main
Reviewed-on: #81
2025-06-24 17:21:28 +00:00
432b0210b2 .gitignore 2025-06-24 17:13:27 +00:00
14cf5cebed add new node called Set Look at Rotation 2025-06-24 18:39:16 +02:00
2307e1504f Merge pull request 't3du [ Repe ] - Fix particle export' (#78) from Onek8/LNXSDK:main into main
Reviewed-on: #78
2025-06-22 20:25:21 +00:00
1ebfecb644 Update leenkx/blender/lnx/exporter.py 2025-06-22 20:13:33 +00:00
175b575b23 Update leenkx/blender/lnx/exporter.py 2025-06-22 20:12:43 +00:00
63943a9cbf Merge pull request 'Remove pycache folders' (#77) from Onek8/LNXSDK:main into main
Reviewed-on: #77
2025-06-20 20:51:03 +00:00
224d9be76f Remove cache folders 2025-06-20 13:47:02 -07:00
62d3c8757b Update leenkx/blender/lnx/exporter.py 2025-06-20 16:06:08 +00:00
3785f93573 Merge pull request 'main' (#75) from Onek8/LNXSDK:main into main
Reviewed-on: #75
2025-06-20 15:59:18 +00:00
ffb276745f Update leenkx/blender/lnx/exporter.py 2025-06-20 15:55:56 +00:00
d1c9258da5 Update leenkx/blender/lnx/exporter.py 2025-06-20 15:55:29 +00:00
3e0cd2be35 Update leenkx/blender/lnx/props_traits.py 2025-06-20 15:50:09 +00:00
1fd1973470 Update leenkx/blender/lnx/material/make_mesh.py 2025-06-18 17:12:53 +00:00
a01c72ef76 Merge pull request 'Update leenkx/blender/lnx/exporter.py' (#74) from Onek8/LNXSDK:main into main
Reviewed-on: #74
2025-06-17 16:38:21 +00:00
4b01a562c9 Update leenkx/blender/lnx/exporter.py 2025-06-16 02:34:28 +00:00
6972d9abc4 Merge pull request 't3du [ Repe ] - Camera Render Filter' (#73) from Onek8/LNXSDK:main into main
Reviewed-on: #73
2025-06-13 15:14:13 +00:00
63c6b9d98b t3du - Camera Render Filter 2025-06-12 22:38:30 +00:00
313d24bbc8 t3du - Camera Render Filter 2025-06-12 22:35:21 +00:00
6d2812306d t3du - Camera Render Filter 2025-06-12 22:23:33 +00:00
e84d6ada84 t3du - Camera Render Filter 2025-06-12 22:21:24 +00:00
5057f2b946 t3du - Camera Render Filter 2025-06-12 22:16:22 +00:00
2715fe3398 t3du - Camera Render Filter 2025-06-12 22:14:08 +00:00
7cb8b8a2d2 t3du - Camera Render Filter 2025-06-12 22:11:59 +00:00
cd606009e0 t3du - Camera Render Filter 2025-06-12 22:10:19 +00:00
965162b101 t3du - Camera Render Filter 2025-06-12 22:08:21 +00:00
c61a57bfb3 t3du - Camera Render Filter 2025-06-12 22:07:16 +00:00
cdc425fbcb Update leenkx/Sources/leenkx/logicnode/GetWorldNode.hx 2025-06-10 20:26:59 +00:00
846bb28c86 Merge pull request 't3du [ Repe ] - World Nodes | Resolution PP | Texture Filtering' (#71) from Onek8/LNXSDK:main into main
Reviewed-on: #71
2025-06-10 20:23:04 +00:00
7fabd77ef8 t3du - Resolution post process 2025-06-10 20:12:18 +00:00
fb1a5c88bf t3du - Resolution post process 2025-06-10 20:11:05 +00:00
e05c83a8bb t3du - Resolution post process 2025-06-10 20:08:54 +00:00
ee4f62e881 t3du - Resolution post process 2025-06-10 20:06:49 +00:00
59f8dff22f t3du - Resolution post process 2025-06-10 20:04:37 +00:00
5572226ac5 t3du - Resolution post process 2025-06-10 20:02:59 +00:00
d04874e0b3 t3du - Set / Get World Nodes 2025-06-10 18:55:35 +00:00
ef8b3a99ab t3du - Set / Get World Nodes 2025-06-10 18:52:53 +00:00
1d3254a237 t3du - Set / Get World Nodes 2025-06-10 18:52:26 +00:00
188af4a50f t3du - Set / Get World Nodes 2025-06-10 18:47:00 +00:00
c45baaf396 t3du - Set / Get World Nodes 2025-06-10 18:44:30 +00:00
4b1da08819 t3du - Set / Get World Nodes 2025-06-10 18:42:12 +00:00
aeb353fb20 t3du - Set / Get World Nodes 2025-06-10 18:40:21 +00:00
65961b1593 t3du - Set / Get World Nodes 2025-06-10 18:38:25 +00:00
1c472155e2 t3du - Add material texture filter node 2025-06-10 18:34:09 +00:00
4238f0b2a0 t3du - Add material texture filter node 2025-06-10 18:32:15 +00:00
b40aadf76c t3du - Add material texture filter node 2025-06-10 18:30:27 +00:00
7277987335 Merge pull request 't3du [ Repe ] - Particle Export Option + Dof reference changes' (#68) from Onek8/LNXSDK:main into main
Reviewed-on: #68
2025-06-07 21:15:56 +00:00
a48ec4d034 t3du - Fix DoF references and small changes 2025-06-07 21:12:31 +00:00
7f0153f816 t3du - Fix DoF references and small changes 2025-06-07 21:07:45 +00:00
40d893e139 t3du - Fix DoF references and small changes 2025-06-07 21:06:35 +00:00
9b9289d27d t3du - Fix DoF references and small changes 2025-06-07 20:42:31 +00:00
8786798edd t3du - Fix DoF references and small changes 2025-06-07 20:39:01 +00:00
fa425a98a5 t3du - Add export option for particles 2025-06-07 20:35:01 +00:00
5165769088 Merge pull request 'main' (#67) from Onek8/LNXSDK:main into main
Reviewed-on: #67
2025-06-06 08:22:34 +00:00
feabf446db Update leenkx/Shaders/std/tonemap.glsl 2025-06-06 07:23:55 +00:00
e770120f7d Update leenkx/blender/lnx/write_data.py 2025-06-06 06:46:55 +00:00
7c1b1f2dd9 Merge pull request 't3du [ Repe ] + Moises - Tonemaps / Debugdrawer / Compositor Fixes' (#64) from Onek8/LNXSDK:main into main
Reviewed-on: #64
2025-06-05 17:41:28 +00:00
88a4f0e76a t3du - Clean Compositor 2025-06-05 17:20:09 +00:00
d9e613b3eb moisesjpelaez - Tonemap Fixes 2025-06-05 17:07:50 +00:00
a0c84dc807 moisesjpelaez - CA Fixes 2025-06-05 17:05:08 +00:00
5a92920b1f moisesjpelaez - Tonemap Fixes 2025-06-05 17:03:38 +00:00
30a624c857 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-06-05 00:54:20 +00:00
8153d67eac Update leenkx/Sources/leenkx/trait/physics/bullet/DebugDrawHelper.hx 2025-06-05 00:52:55 +00:00
9963a42c76 Merge pull request 'Shader Fix + moisesjpelaez Aura Fix' (#62) from Onek8/LNXSDK:main into main
Reviewed-on: #62
2025-06-04 19:18:13 +00:00
885385d7cb Update lib/aura/Sources/aura/Time.hx 2025-06-04 19:14:36 +00:00
c433a7f09e Update lib/aura/Sources/aura/threading/Message.hx 2025-06-04 19:13:12 +00:00
c7e2c7d452 Update lib/aura/Sources/aura/dsp/panner/StereoPanner.hx 2025-06-04 19:11:55 +00:00
2a1235b3d8 Update lib/aura/Sources/aura/channels/Html5StreamChannel.hx 2025-06-04 19:10:07 +00:00
074962d158 Update leenkx/blender/lnx/material/cycles_nodes/nodes_shader.py 2025-06-04 19:02:57 +00:00
3ea0d7da9d Merge pull request 't3du [ Repe ] - Post process updates - New nodes - Physics - Chromatic AB' (#60) from Onek8/LNXSDK:main into main
Reviewed-on: #60
2025-06-02 20:07:26 +00:00
00b580a4fa Update leenkx/blender/lnx/logicnode/postprocess/LN_get_auto_exposure_settings.py 2025-06-02 20:06:50 +00:00
f779462f36 t3du - Post Process Updates 2025-06-02 19:51:11 +00:00
2c7343aa31 t3du - Post Process Updates 2025-06-02 19:47:15 +00:00
85912d84fb Add leenkx/blender/lnx/logicnode/postprocess/LN_set_volumetric_light_settings.py 2025-06-02 19:45:39 +00:00
ad0d750dd0 Add leenkx/blender/lnx/logicnode/postprocess/LN_set_volumetric_fog_settings.py 2025-06-02 19:43:52 +00:00
9914d53045 Add leenkx/blender/lnx/logicnode/postprocess/LN_set_sharpen_settings.py 2025-06-02 19:42:36 +00:00
9daf6c15ab Update leenkx/blender/lnx/logicnode/postprocess/LN_set_auto_exposure_settings.py 2025-06-02 19:40:33 +00:00
9ac3de67aa Update leenkx/blender/lnx/logicnode/postprocess/LN_get_volumetric_light_settings.py 2025-06-02 19:40:05 +00:00
fd02f6bca3 Add leenkx/blender/lnx/logicnode/LN_set_auto_exposure_settings.py 2025-06-02 19:39:13 +00:00
2cc0d3db3b Add leenkx/blender/lnx/logicnode/LN_get_volumetric_light_settings.py 2025-06-02 19:38:01 +00:00
fe730a65ee Add leenkx/blender/lnx/logicnode/postprocess/LN_get_volumetric_fog_settings.py 2025-06-02 19:35:27 +00:00
18ec9712fd Add leenkx/blender/lnx/logicnode/postprocess/LN_get_sharpen_settings.py 2025-06-02 19:25:19 +00:00
0d80f3fb6d Add leenkx/blender/lnx/logicnode/postprocess/LN_get_auto_exposure_settings.py 2025-06-02 19:21:53 +00:00
be06b222cb t3du - Post Process Updates 2025-06-02 19:14:54 +00:00
3f0984e227 Update leenkx/blender/lnx/props_ui.py 2025-06-02 19:13:12 +00:00
15a10ea3aa t3du - Post Process Updates 2025-06-02 19:12:33 +00:00
012abfeaf6 t3du - Post Process Updates 2025-06-02 19:11:02 +00:00
dd6cd16661 t3du - Post Process Updates 2025-06-02 19:01:21 +00:00
d8b37efe1b Add leenkx/Sources/leenkx/logicnode/VolumetricLightSetNode.hx 2025-06-02 18:57:18 +00:00
a40a035c03 Add leenkx/Sources/leenkx/logicnode/VolumetricLightGetNode.hx 2025-06-02 18:56:31 +00:00
a318758cbf Add leenkx/Sources/leenkx/logicnode/VolumetricFogSetNode.hx 2025-06-02 18:36:55 +00:00
7c13a25caf Add leenkx/Sources/leenkx/logicnode/VolumetricFogGetNode.hx 2025-06-02 18:36:11 +00:00
141567467f Add leenkx/Sources/leenkx/logicnode/SharpenSetNode.hx 2025-06-02 18:35:24 +00:00
047983a280 Add leenkx/Sources/leenkx/logicnode/SharpenGetNode.hx 2025-06-02 18:34:24 +00:00
48ad4322cf t3du - Post Process Updates 2025-06-02 18:33:21 +00:00
eaa34308d0 Add leenkx/Sources/leenkx/logicnode/AutoExposureSetNode.hx 2025-06-02 18:28:33 +00:00
741a12de78 Add leenkx/Sources/leenkx/logicnode/AutoExposureGetNode.hx 2025-06-02 18:27:31 +00:00
9749467cd7 t3du - Post Process Updates 2025-06-02 18:25:19 +00:00
91ae053346 t3du - Post Process Updates 2025-06-02 18:21:47 +00:00
b7b7edb5e2 t3du - Post Process Updates 2025-06-02 18:19:16 +00:00
dfa99fcb14 t3du - Post Process Updates 2025-06-02 18:18:36 +00:00
bc0bf41b91 t3du - Post Process Updates 2025-06-02 18:17:17 +00:00
535e69dcd0 t3du - Post Process Updates 2025-06-02 18:15:45 +00:00
2eaf83d89c t3du - Post Process Updates 2025-06-02 18:09:31 +00:00
6e62917819 t3du - Post Process Updates 2025-06-02 18:08:41 +00:00
03106eff02 t3du - Particle nodes Update 2025-06-02 18:01:58 +00:00
0c5d71ecd2 t3du - Particle nodes Update 2025-06-02 18:00:15 +00:00
d6a7b7e305 t3du - Particle nodes Update 2025-06-02 17:58:15 +00:00
3d91f2f1e7 t3du - Particle nodes Update 2025-06-02 17:54:31 +00:00
d76c295786 t3du - Krom path condition 2025-06-02 17:48:09 +00:00
79422337ae t3du - CA Updates 2025-06-02 17:35:46 +00:00
b0e624ef75 t3du - CA Updates 2025-06-02 17:34:59 +00:00
9d78aabf35 t3du - CA Updates 2025-06-02 17:33:15 +00:00
a3930d7761 t3du - CA Updates 2025-06-02 17:31:13 +00:00
c958113c94 Update leenkx/blender/lnx/logicnode/postprocess/LN_set_ca_settings.py 2025-06-02 17:27:27 +00:00
385c683fe3 t3du - CA Updates 2025-06-02 17:25:33 +00:00
1050337751 t3du - CA Updates 2025-06-02 17:20:59 +00:00
114bf7544a t3du - CA Updates 2025-06-02 17:14:44 +00:00
0199ee9877 t3du - CA Updates 2025-06-02 17:09:28 +00:00
6e02aeee53 t3du - CA Updates 2025-06-02 17:06:56 +00:00
6c3d71c4c9 t3du - CA Updates 2025-06-02 17:05:30 +00:00
78592b245f t3du - CA Updates 2025-06-02 17:04:55 +00:00
80d4422c90 t3du - CA Updates 2025-06-02 17:03:41 +00:00
32df55d636 t3du - CA Updates 2025-06-02 17:00:57 +00:00
eede86e278 Update leenkx/blender/lnx/props_ui.py 2025-06-02 16:47:43 +00:00
1b855f953f t3du - Ies Texture and Cloud Texture: improvements 2025-06-02 16:46:01 +00:00
59df400b0d t3du - Ies Texture and Cloud Texture: improvements 2025-06-02 16:44:08 +00:00
4af244e3e2 Merge pull request 'moisesjpelaez - Fix pausing and resuming updates' (#59) from Onek8/LNXSDK:main into main
Reviewed-on: #59
2025-06-02 16:35:35 +00:00
ae91f8801f moisesjpelaez - Fix pausing and resuming updates 2025-06-02 16:32:28 +00:00
7f5786d47c moisesjpelaez - Fix pausing and resuming updates 2025-06-02 16:24:22 +00:00
ea12d5b951 moisesjpelaez - Fix pausing and resuming updates 2025-06-02 16:21:25 +00:00
d37468a6ab Merge pull request 'moisesjpelaez - FixedUpdate - Physics Improvements - Private Fields' (#58) from Onek8/LNXSDK:main into main
Reviewed-on: #58
2025-06-02 16:01:44 +00:00
d0b3dc2ff8 moisesjpelaez - Physics Improvements 2025-06-02 07:24:53 +00:00
85bbc10d06 moisesjpelaez - Physics Improvements 2025-06-02 06:31:14 +00:00
2fca73aebd moisesjpelaez - Physics Improvements 2025-06-02 06:26:11 +00:00
8b187940ee moisesjpelaez - Physics Improvements 2025-06-02 06:22:23 +00:00
00369aa90b moisesjpelaez - Physics Improvements 2025-06-02 04:18:44 +00:00
26a10020ac moisesjpelaez - Physics Improvements 2025-06-02 04:12:58 +00:00
421463a642 moisesjpelaez - Physics Improvements 2025-06-02 04:11:02 +00:00
8d9f248d2f moisesjpelaez - Physics Improvements 2025-06-02 04:06:31 +00:00
ed72206a26 moisesjpelaez - Physics Improvements 2025-06-01 23:52:22 +00:00
6b7460dd4c moisesjpelaez - Add particles random size
* Revert
2025-06-01 23:46:05 +00:00
447af740be moisesjpelaez - Framerate and delta fixes 2025-06-01 23:33:30 +00:00
3ff6c32ac9 moisesjpelaez - Framerate and delta fixes 2025-06-01 23:31:49 +00:00
b752d70109 moisesjpelaez - Framerate and delta fixes 2025-06-01 23:29:57 +00:00
a6f83e2d37 moisesjpelaez - Framerate and delta fixes 2025-06-01 23:29:09 +00:00
016e223fb8 moisesjpelaez - Add fixedUpdate for Physics 2025-06-01 23:18:35 +00:00
502601e684 moisesjpelaez - Add fixedUpdate for Physics 2025-06-01 23:17:23 +00:00
29a4bb6803 moisesjpelaez - Add fixedUpdate for Physics 2025-06-01 23:14:43 +00:00
cfbe7c83cb moisesjpelaez - Add fixedUpdate for Physics 2025-06-01 23:09:47 +00:00
a6d9cb9201 moisesjpelaez - Physics Private Fields 2025-06-01 23:02:50 +00:00
32cdbd8c54 moisesjpelaez - Physics Private Fields 2025-06-01 22:57:47 +00:00
1a17b646e4 moisesjpelaez - Physics Private Fields 2025-06-01 22:56:48 +00:00
cdf79de36b moisesjpelaez - Physics Private Fields 2025-06-01 22:55:55 +00:00
2aa6be6496 moisesjpelaez - Physics Private Fields 2025-06-01 22:52:16 +00:00
25c391d244 moisesjpelaez - Physics Improvements 2025-06-01 22:17:30 +00:00
a3c2be4e79 moisesjpelaez - Physics Improvements 2025-06-01 22:16:29 +00:00
3413e10134 moisesjpelaez - Physics Improvements 2025-06-01 22:11:11 +00:00
fa91348428 moisesjpelaez - Physics Improvements 2025-06-01 21:58:58 +00:00
d40d3eb96e moisesjpelaez - Physics Improvements 2025-06-01 21:56:06 +00:00
16e019be26 moisesjpelaez - Physics Improvements 2025-06-01 21:53:31 +00:00
2e77f67683 moisesjpelaez - Physics Improvements 2025-06-01 21:51:09 +00:00
9824dc5a44 moisesjpelaez - General Fixes 2025-06-01 20:52:08 +00:00
1c20e03e0c Update leenkx/blender/lnx/material/cycles_nodes/nodes_converter.py 2025-05-31 06:07:19 +00:00
98f334c883 Merge pull request 'Update get_scene function call' (#57) from Onek8/LNXSDK:main into main
Reviewed-on: #57
2025-05-30 21:43:15 +00:00
8ac8a780e1 Update leenkx/blender/lnx/write_data.py 2025-05-30 21:38:01 +00:00
25e5700084 Update leenkx/blender/lnx/make_renderpath.py 2025-05-30 21:34:37 +00:00
28d60a652b Merge pull request 't3du [ Repe ] - New features + Fixes' (#56) from Onek8/LNXSDK:main into main
Reviewed-on: #56
2025-05-28 23:33:34 +00:00
778be03472 t3du - Fix scene exposure setting 2025-05-28 23:04:39 +00:00
fff8b5c29e t3du - Fix scene exposure setting 2025-05-28 23:02:14 +00:00
a70d0bd601 t3du - New Image nodes: Draw Sub Image and Write Image 2025-05-28 22:37:36 +00:00
8fc14ac793 t3du - New Image nodes: Draw Sub Image and Write Image 2025-05-28 22:35:28 +00:00
13add8f60b t3du - New Image nodes: Draw Sub Image and Write Image 2025-05-28 22:32:37 +00:00
2c1605c855 t3du - New Image nodes: Draw Sub Image and Write Image 2025-05-28 22:31:56 +00:00
3524676fcc t3du - New Image nodes: Draw Sub Image and Write Image 2025-05-28 22:30:42 +00:00
a577d57263 t3du - New Image nodes: Draw Sub Image and Write Image 2025-05-28 22:29:07 +00:00
58440bb347 t3du - New Image nodes: Draw Sub Image and Write Image 2025-05-28 22:26:33 +00:00
f3808c4251 t3du - New Image nodes: Draw Sub Image and Write Image 2025-05-28 22:24:50 +00:00
95c08e3424 t3du - Fix draw camera texture node 2025-05-28 22:15:48 +00:00
ce762b3cfa t3du - Fix draw camera texture node 2025-05-28 22:11:50 +00:00
15bcf4a374 t3du - Fix Desc 2025-05-28 22:08:06 +00:00
634aaa0b6a t3du - Fix Desc 2025-05-28 22:07:49 +00:00
69fc090f55 t3du - Conditional Shader Nodes 4.0 + 2025-05-28 21:44:06 +00:00
f42041ccb6 t3du - Delete Traces 2025-05-28 21:35:44 +00:00
a8787bd315 t3du - Delete Traces 2025-05-28 21:34:42 +00:00
b5e77aeef8 t3du - Add Brick Texture 2025-05-28 21:30:38 +00:00
f379685fdd t3du - Add Brick Texture 2025-05-28 21:25:25 +00:00
32ff286691 Merge pull request 't3du [ Repe ] - Lightmapper fix: update ShaderNodeMixRGB to ShaderNodeMix and 4. above support' (#55) from Onek8/LNXSDK:main into main
Reviewed-on: #55
2025-05-28 02:46:47 +00:00
38ab682978 Update leenkx/blender/lnx/lightmapper/utility/utility.py 2025-05-28 02:32:27 +00:00
8efe115698 Update leenkx/blender/lnx/lightmapper/utility/gui/Viewport.py 2025-05-28 02:21:24 +00:00
38f72101eb Update leenkx/blender/lnx/lightmapper/utility/cycles/prepare.py 2025-05-28 02:06:48 +00:00
f6d03b060c Update leenkx/blender/lnx/lightmapper/utility/cycles/nodes.py 2025-05-28 02:05:04 +00:00
f450c00ff1 Merge pull request 't3du (Repe) - New Particle Nodes!' (#54) from Onek8/LNXSDK:main into main
Reviewed-on: #54
2025-05-28 01:54:21 +00:00
751f960b82 Update leenkx/blender/lnx/logicnode/__init__.py 2025-05-22 22:06:41 +00:00
9558ded5c4 Update leenkx/Sources/iron/object/ParticleSystem.hx 2025-05-22 22:03:44 +00:00
8066756605 Update leenkx/Sources/iron/object/ParticleSystem.hx 2025-05-22 22:02:56 +00:00
ac2507e0ae Update leenkx/Sources/iron/object/MeshObject.hx 2025-05-22 22:00:56 +00:00
205d4ccc41 Update leenkx/Sources/iron/Scene.hx 2025-05-22 21:52:06 +00:00
7565818d0e Upload files to "leenkx/Sources/leenkx/logicnode" 2025-05-22 21:47:32 +00:00
fc093eca3e Upload files to "leenkx/Sources/leenkx/logicnode" 2025-05-22 21:46:21 +00:00
61b8f21037 Update leenkx/Sources/leenkx/logicnode/SetParticleSpeedNode.hx 2025-05-22 21:42:53 +00:00
d988ce8c99 Delete leenkx/blender/lnx/logicnode/animation/LN_set_particle_speed.py 2025-05-22 21:39:32 +00:00
727d82f268 Upload files to "leenkx/blender/lnx/logicnode/particle" 2025-05-22 21:39:10 +00:00
c3c89c320b Upload files to "leenkx/blender/lnx/logicnode/particle" 2025-05-22 21:36:22 +00:00
0b5bb877fb Add leenkx/blender/lnx/logicnode/particle/__init__.py 2025-05-22 21:35:22 +00:00
9d7613be8f Update Binaries 2025-05-18 22:12:06 +00:00
c989f3254f Delete Krom/Krom.exe 2025-05-18 22:00:02 +00:00
f8d76929ae Delete Krom/Krom_opengl.exe 2025-05-18 21:59:54 +00:00
a51c28b607 Delete Krom/Krom 2025-05-18 21:59:44 +00:00
9142371f88 Merge pull request 'Update shader data and custom particles' (#53) from Onek8/LNXSDK:main into main
Reviewed-on: #53
2025-05-17 08:45:06 +00:00
35f92341fa Update leenkx/blender/lnx/nodes_logic.py 2025-05-17 08:05:49 +00:00
a8d1eebdaf Merge branch 'main' into main 2025-05-17 03:21:14 +00:00
87922c9389 Upload files to "leenkx/blender/data" 2025-05-17 03:19:57 +00:00
38287f56b0 Delete leenkx/blender/data/lnx_data.blend 2025-05-17 03:18:52 +00:00
42ad5b01c1 Merge pull request 't3du - Fix NoiseTexture fac output for FBM and include params: detail and distortion' (#51) from Onek8/LNXSDK:main into main
Reviewed-on: #51
2025-05-13 20:57:19 +00:00
2b46d6ebca Update leenkx/blender/lnx/material/cycles_nodes/nodes_texture.py 2025-05-13 20:55:03 +00:00
953ad8391c Update leenkx/blender/lnx/material/cycles_nodes/nodes_texture.py 2025-05-13 20:51:26 +00:00
1458ecd84f Update leenkx/blender/lnx/material/cycles_functions.py 2025-05-13 20:49:49 +00:00
288b085d0c Merge pull request 'moisesjpelaez - Add particles random size' (#50) from Onek8/LNXSDK:main into main
Reviewed-on: #50
2025-05-13 20:03:56 +00:00
aa0b2b1b7e Update Kha/Backends/Krom/kha/audio2/Audio.hx 2025-05-13 19:53:49 +00:00
acede01167 Update Kha/Backends/Krom/kha/audio2/Audio.hx 2025-05-13 19:52:40 +00:00
92a2b0305e Update Kha/Backends/Krom/kha/SystemImpl.hx 2025-05-13 19:50:08 +00:00
4886953722 Update Kha/Backends/Krom/Krom.hx 2025-05-13 19:46:24 +00:00
601860b242 Update Kha/Sources/kha/Scheduler.hx 2025-05-13 19:41:30 +00:00
f00cef2e21 Update Kha/Sources/kha/Scheduler.hx 2025-05-13 19:40:30 +00:00
e733dca053 Update Kha/Backends/Krom/kha/krom/Graphics.hx 2025-05-13 19:37:45 +00:00
387be05826 Update Kha/Backends/Krom/kha/SystemImpl.hx 2025-05-13 19:35:50 +00:00
c5b21a9bb3 Update Kha/Backends/Krom/kha/Display.hx 2025-05-13 19:34:29 +00:00
5b2c7bfc84 Update Kha/Backends/Krom/Krom.hx 2025-05-13 19:33:41 +00:00
47d913ab64 moisesjpelaez - Add particles random size 2025-05-13 18:00:51 +00:00
878ce14254 moisesjpelaez - Add particles random size 2025-05-13 17:59:36 +00:00
9075931c51 moisesjpelaez - Add particles random size 2025-05-13 17:58:05 +00:00
39ab42f2da Merge pull request 'moisesjpelaez and T3du - Oimo Physics, Bloom condition, array index list, camera spawn fix' (#48) from Onek8/LNXSDK:main into main
Reviewed-on: #48
2025-05-13 16:59:59 +00:00
30cab4d79b Update leenkx/Sources/leenkx/trait/physics/bullet/DebugDrawHelper.hx 2025-05-13 16:55:45 +00:00
8ee2aaa70a Update leenkx/Sources/leenkx/trait/physics/bullet/DebugDrawHelper.hx 2025-05-12 07:39:22 +00:00
2f9694632d Update leenkx/Sources/leenkx/trait/physics/bullet/DebugDrawHelper.hx 2025-05-12 07:31:37 +00:00
7b8d73cd84 Update leenkx/Sources/leenkx/trait/physics/bullet/DebugDrawHelper.hx 2025-05-12 07:29:05 +00:00
3d8bd77c59 Update leenkx/Sources/leenkx/trait/physics/bullet/DebugDrawHelper.hx 2025-05-12 04:08:17 +00:00
290289f413 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-05-11 20:37:34 +00:00
2732210fc9 moisesjpelaez - Oimo Physics 2025-05-11 19:46:28 +00:00
68900fb992 moisesjpelaez - Fix Bloom condition 2025-05-11 19:43:09 +00:00
ef724ae323 moisesjpelaez - Oimo Physics 2025-05-11 19:41:09 +00:00
6d4c1a680b moisesjpelaez - Oimo Physics 2025-05-11 19:37:04 +00:00
8aeaa0368e moisesjpelaez - Oimo Physics 2025-05-11 17:50:43 +00:00
7969286fdc moisesjpelaez - Oimo Physics 2025-05-11 17:49:43 +00:00
cde2bead97 moisesjpelaez - Oimo Physics 2025-05-11 17:47:56 +00:00
c42e4c09a8 moisesjpelaez - Oimo Physics 2025-05-11 17:46:49 +00:00
b8c8ccad9d moisesjpelaez - Oimo Physics 2025-05-11 17:46:28 +00:00
335f3541f1 moisesjpelaez - Oimo Physics 2025-05-11 17:44:49 +00:00
808dcef817 moisesjpelaez - Oimo Physics 2025-05-11 17:41:38 +00:00
6ac06cc504 moisesjpelaez - Oimo Physics 2025-05-11 17:40:38 +00:00
86de9617f3 moisesjpelaez - Oimo Physics 2025-05-11 17:39:01 +00:00
29761ec9e6 moisesjpelaez - Oimo Physics 2025-05-11 17:38:02 +00:00
ea7cf849b8 t3du - Add ArrayIndexListNode.hx 2025-05-11 17:14:38 +00:00
5d559734b9 t3du - Add LN_array_index_list.py 2025-05-11 17:13:05 +00:00
939346c896 moisesjpelaez - Fix camera spawn position in Blender 4.2.x 2025-05-11 17:03:13 +00:00
f2dcfc0ffa Merge pull request 'main' (#47) from Onek8/LNXSDK:main into main
Reviewed-on: #47
2025-05-10 16:32:31 +00:00
e78bd17d93 Update leenkx/blender/lnx/utils.py 2025-05-10 16:30:16 +00:00
f9a02f03cb Update leenkx.py 2025-05-10 16:27:51 +00:00
21a4ee0af7 Update leenkx.py 2025-05-10 16:25:06 +00:00
06319131fd Update leenkx/blender/lnx/handlers.py 2025-04-11 21:16:04 +00:00
c08e1d3835 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-04-11 21:04:00 +00:00
27bd360317 Update lib/haxebullet/hl/bullet.cpp 2025-04-11 16:28:33 +00:00
82a53a868a Merge pull request 'Debug Raycast Drawing' (#45) from Onek8/LNXSDK:main into main
Reviewed-on: #45
2025-04-11 08:37:13 +00:00
94eaba7319 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-04-11 08:22:17 +00:00
8d1c2c51bd Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-04-11 08:18:30 +00:00
07d98639f2 Update leenkx/Sources/leenkx/trait/physics/bullet/DebugDrawHelper.hx 2025-04-11 08:17:40 +00:00
1944fc97b8 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-04-10 22:22:46 +00:00
d69e3438ff Update leenkx/Sources/leenkx/trait/physics/bullet/DebugDrawHelper.hx 2025-04-10 21:55:56 +00:00
62e52a7316 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-04-10 21:45:24 +00:00
c4b48c2d87 Update leenkx/blender/lnx/exporter.py 2025-04-10 21:29:34 +00:00
96f69a7cfe Update leenkx/blender/lnx/props_ui.py 2025-04-10 21:23:53 +00:00
90950970f0 Update leenkx/blender/lnx/props.py 2025-04-10 21:21:21 +00:00
e71b0849b3 Merge pull request 'HashLeenkx Updates!' (#44) from Onek8/LNXSDK:main into main
Reviewed-on: #44
2025-04-10 15:56:16 +00:00
e079c94832 Update leenkx/blender/lnx/make.py 2025-04-10 15:54:53 +00:00
5572494f3d Upload files to "Kha/Kinc/Tools/freebsd_x64" 2025-04-10 11:02:33 +00:00
8f03927391 Delete Kha/Kinc/Tools/freebsd_x64/icon.png 2025-04-10 11:02:20 +00:00
6586d90177 Upload files to "Kha/Kinc/Tools/linux_arm" 2025-04-10 11:02:04 +00:00
952cee36a3 Delete Kha/Kinc/Tools/linux_arm/icon.png 2025-04-10 11:01:52 +00:00
35bfdf3715 Upload files to "Kha/Kinc/Tools/linux_arm64" 2025-04-10 11:01:37 +00:00
135aaa0669 Delete Kha/Kinc/Tools/linux_arm64/icon.png 2025-04-10 11:01:22 +00:00
c6b776a329 Upload files to "Kha/Kinc/Tools/macos" 2025-04-10 11:01:09 +00:00
67c7443985 Delete Kha/Kinc/Tools/macos/icon.png 2025-04-10 11:00:57 +00:00
42273470c3 Upload files to "Kha/Kinc/Tools/linux_x64" 2025-04-10 11:00:38 +00:00
4dfc6be702 Delete Kha/Kinc/Tools/linux_x64/icon.png 2025-04-10 11:00:25 +00:00
92e1abcfdc Upload files to "Kha/Kinc/Tools/windows_x64" 2025-04-10 11:00:11 +00:00
764eefeb06 Delete Kha/Kinc/Tools/windows_x64/icon.png 2025-04-10 10:59:52 +00:00
979dfc605d Update leenkx/blender/lnx/make.py 2025-04-10 10:12:22 +00:00
55fb300901 Update Kha/Backends/Kinc-HL/kha/graphics4/FragmentShader.hx 2025-04-10 08:47:21 +00:00
c59e6a66d4 merge upstream 2025-04-10 07:48:11 +00:00
659802b888 Update Kha/Backends/Kinc-HL/kha/graphics4/FragmentShader.hx 2025-04-10 07:36:58 +00:00
33f6fcaaaf Merge pull request 'HashLeenkx' (#43) from Onek8/LNXSDK:main into main
Reviewed-on: #43
2025-04-09 22:15:26 +00:00
d37b41b181 Update leenkx/Sources/iron/system/LnxPack.hx 2025-04-09 22:14:24 +00:00
70742b823f Update Kha/Backends/Kinc-HL/kinc-bridge/kinc.c.h 2025-04-09 22:09:15 +00:00
da8f9d23e4 Update lib/aura/Sources/aura/Aura.hx 2025-04-09 22:07:36 +00:00
ff886e6d46 Update Kha/Backends/Kinc-HL/kfile.js 2025-04-09 22:05:14 +00:00
70a603cf7a Update Kha/Backends/Kinc-HL/kinc-bridge/compute.c.h 2025-04-09 21:25:07 +00:00
bfc4c2644f Update leenkx/blender/lnx/props.py 2025-04-09 20:59:05 +00:00
f101124d24 Update leenkx/blender/lnx/utils.py 2025-04-09 20:44:54 +00:00
c6f672bd61 Update leenkx/blender/lnx/props.py 2025-04-09 20:35:42 +00:00
7f38b15fe7 Update leenkx/blender/lnx/make.py 2025-04-09 20:33:24 +00:00
5628493493 Merge pull request 'Transforms_and_Rotations' (#42) from Onek8/LNXSDK:Transforms_and_Rotations into main
Reviewed-on: #42
2025-04-09 17:12:32 +00:00
f8a08a41b1 Update leenkx/Sources/iron/math/Quat.hx 2025-04-09 15:02:07 +00:00
2cd91f598c Update leenkx/blender/lnx/logicnode/lnx_sockets.py 2025-04-08 21:50:49 +00:00
a20d6b581c Update leenkx/blender/lnx/nodes_logic.py 2025-04-08 17:24:50 +00:00
e34ed0794f Update leenkx/Sources/leenkx/logicnode/RotationNode.hx 2025-04-08 17:20:50 +00:00
bdcf4c980b Update leenkx/blender/lnx/logicnode/lnx_sockets.py 2025-04-08 17:19:06 +00:00
30e5acf9bf Update leenkx/blender/lnx/make_renderpath.py 2025-04-07 21:20:53 +00:00
c3435b9533 Update leenkx/blender/lnx/write_data.py 2025-04-07 21:19:28 +00:00
8765e894f5 Update leenkx/blender/lnx/props_ui.py 2025-04-07 21:17:23 +00:00
2c5c8d0e4f Update leenkx/blender/lnx/props_renderpath.py 2025-04-07 21:16:29 +00:00
4805dd06a7 Update leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl 2025-04-07 21:14:52 +00:00
2bc2ab43a1 Update leenkx/Shaders/std/tonemap.glsl 2025-04-07 21:12:11 +00:00
c798f122d0 Merge pull request 'Transforms and rotations math' (#41) from Onek8/LNXSDK:main into main
Reviewed-on: #41
2025-04-06 15:48:46 +00:00
d1edb1464e Update leenkx/Sources/iron/math/Quat.hx 2025-04-06 15:27:05 +00:00
ee8d3314b5 Update leenkx/Sources/leenkx/logicnode/TransformNode.hx 2025-04-06 15:25:39 +00:00
c6139282ed Update leenkx/blender/lnx/logicnode/lnx_sockets.py 2025-04-06 14:34:19 +00:00
559a3b8b39 Update leenkx/Sources/iron/math/Quat.hx 2025-04-06 14:30:52 +00:00
8d072ae481 Update leenkx/blender/lnx/logicnode/math/LN_rotation_math.py 2025-04-06 10:28:18 +00:00
293a612e9c Update leenkx/blender/lnx/logicnode/network/LN_network_event.py 2025-04-06 10:25:39 +00:00
8020599513 Update leenkx/blender/lnx/logicnode/native/LN_get_date_time.py 2025-04-06 10:25:01 +00:00
4fbc1aba7f Update leenkx/blender/lnx/logicnode/native/LN_call_haxe_static.py 2025-04-06 10:24:11 +00:00
1380585297 Update leenkx/blender/lnx/logicnode/miscellaneous/LN_group_output.py 2025-04-06 10:23:47 +00:00
beee036a3d Update leenkx/blender/lnx/logicnode/miscellaneous/LN_group_input.py 2025-04-06 10:23:01 +00:00
76b2ba8f80 Update leenkx/blender/lnx/logicnode/miscellaneous/LN_call_group.py 2025-04-06 10:22:41 +00:00
e7143cc740 Update leenkx/blender/lnx/logicnode/math/LN_vector_math.py 2025-04-06 10:22:15 +00:00
bd0886b1d7 Update leenkx/blender/lnx/logicnode/math/LN_quaternion_math.py 2025-04-06 10:20:29 +00:00
8eb8c0bd98 Update leenkx/blender/lnx/logicnode/math/LN_math_term.py 2025-04-06 10:19:19 +00:00
dd06e490a7 Update leenkx/blender/lnx/logicnode/math/LN_math_expression.py 2025-04-06 10:18:20 +00:00
5e4ac6dd0b Update leenkx/blender/lnx/logicnode/math/LN_math.py 2025-04-06 10:16:57 +00:00
be0a9149ad Update leenkx/blender/lnx/logicnode/math/LN_compare.py 2025-04-06 10:14:40 +00:00
7ab3398941 Update leenkx/blender/lnx/logicnode/map/LN_string_map.py 2025-04-06 10:14:02 +00:00
c10e988d2d Update leenkx/blender/lnx/logicnode/logic/LN_wait_for.py 2025-04-06 10:13:28 +00:00
caafeea2f1 Update leenkx/blender/lnx/logicnode/logic/LN_switch_output.py 2025-04-06 10:12:43 +00:00
2edee3fe68 Update leenkx/blender/lnx/logicnode/logic/LN_select.py 2025-04-06 10:11:19 +00:00
af147c9c63 Update leenkx/blender/lnx/logicnode/array/LN_array_remove_by_value.py 2025-04-06 10:10:23 +00:00
8e4c20647b Update leenkx/blender/lnx/lightmapper/utility/log.py 2025-04-06 10:09:42 +00:00
594cbeffbe Update leenkx/blender/lnx/logicnode/random/LN_random_output.py 2025-04-06 10:06:39 +00:00
e1d48e4289 Update leenkx/blender/lnx/logicnode/random/LN_probabilistic_output.py 2025-04-06 10:06:04 +00:00
7960ca94a6 Update leenkx/blender/lnx/logicnode/physics/LN_physics_constraint.py 2025-04-06 10:02:08 +00:00
72f14f59bf Update leenkx/blender/lnx/logicnode/physics/LN_add_physics_constraint.py 2025-04-06 10:01:08 +00:00
d994d040ef Update leenkx/blender/lnx/logicnode/network/LN_network_send_message.py 2025-04-06 09:54:19 +00:00
1e18795d29 Update leenkx/blender/lnx/logicnode/string/LN_concatenate_string.py 2025-04-06 09:40:14 +00:00
9557b82970 Update leenkx/blender/lnx/props_renderpath.py 2025-04-05 13:27:30 +00:00
88949c63c5 Update leenkx/Shaders/std/tonemap.glsl 2025-04-05 13:11:56 +00:00
7cab325397 Update leenkx/blender/lnx/props_renderpath.py 2025-04-05 13:10:44 +00:00
8792ef5cee Update leenkx/blender/lnx/props_renderpath.py 2025-04-05 10:54:48 +00:00
761b1832ad Update leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl 2025-04-05 10:47:18 +00:00
074a51866f Update leenkx/blender/lnx/props_renderpath.py 2025-04-05 10:24:00 +00:00
c382460355 Update leenkx/blender/lnx/props_renderpath.py 2025-04-05 09:02:03 +00:00
4a3544b5d8 Update leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl 2025-04-05 08:59:31 +00:00
7cebe8340f Update leenkx/blender/lnx/props_renderpath.py 2025-04-05 08:57:20 +00:00
ecaea8ad9d Merge pull request 'AgX color space' (#40) from Onek8/LNXSDK:main into main
Reviewed-on: #40
2025-04-05 08:27:30 +00:00
cae7963b21 Update leenkx/Shaders/compositor_pass/compositor_pass.frag.glsl 2025-04-05 08:25:54 +00:00
7a2976ced1 Update leenkx/blender/lnx/props_renderpath.py 2025-04-05 08:18:32 +00:00
aae64aa8f8 Update leenkx/Shaders/std/tonemap.glsl 2025-04-05 08:12:43 +00:00
ef25d15aed Merge pull request 'Update leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl' (#35) from Onek8/LNXSDK:main into main
Reviewed-on: #35
2025-04-04 20:47:40 +00:00
01bcf029f9 Update leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl 2025-04-04 20:42:41 +00:00
2b9baef712 Merge pull request 'Update' (#24) from Onek8/LNXSDK:main into main
Reviewed-on: #24
2025-04-03 20:57:15 +00:00
489057018e Update leenkx/blender/lnx/material/cycles_nodes/nodes_shader.py 2025-04-03 16:59:29 +00:00
501a064d25 Update leenkx/Shaders/voxel_resolve_specular/voxel_resolve_specular.comp.glsl 2025-04-03 16:20:12 +00:00
9478e4e957 Merge pull request 'Audio flag to prevent crashing when audio is disabled' (#22) from Onek8/LNXSDK:main into main
Reviewed-on: #22
2025-04-03 12:38:38 +00:00
32c6535f8a Update leenkx/Sources/leenkx/logicnode/StopSoundNode.hx 2025-04-03 12:36:33 +00:00
21c2abe67c Update leenkx/Sources/leenkx/logicnode/SetVolumeSoundNode.hx 2025-04-03 12:35:51 +00:00
2b1b56bc0a Update leenkx/Sources/leenkx/logicnode/SetSoundNode.hx 2025-04-03 12:35:02 +00:00
9e47c1db6d Update leenkx/Sources/leenkx/logicnode/PlaySoundRawNode.hx 2025-04-03 12:34:08 +00:00
6be977da7e Update leenkx/Sources/leenkx/logicnode/PlaySoundNode.hx 2025-04-03 12:30:45 +00:00
693fa36ee1 Update leenkx/Sources/leenkx/logicnode/PauseSoundNode.hx 2025-04-03 12:30:03 +00:00
6ec480930a Merge pull request 'More 4.4 updates' (#17) from Onek8/LNXSDK:main into main
Reviewed-on: #17
2025-04-03 10:06:05 +00:00
a627a52d46 Update leenkx/blender/lnx/logicnode/logic/LN_output_sequence.py 2025-04-03 10:04:43 +00:00
be63323c09 Update leenkx/blender/lnx/logicnode/logic/LN_merge.py 2025-04-03 10:04:15 +00:00
38595db46b Update leenkx/blender/lnx/logicnode/logic/LN_gate.py 2025-04-03 10:03:25 +00:00
48d28f6873 Update leenkx/blender/lnx/logicnode/logic/LN_function.py 2025-04-03 10:02:33 +00:00
eb033149a0 Update leenkx/blender/lnx/logicnode/logic/LN_case_index.py 2025-04-03 10:01:30 +00:00
db1c3bdf4c Update leenkx/blender/lnx/logicnode/logic/LN_call_function.py 2025-04-03 09:59:20 +00:00
2b16b565a8 Update leenkx/blender/lnx/logicnode/logic/LN_alternate_output.py 2025-04-03 09:57:33 +00:00
8c758bf51f Update leenkx/blender/lnx/logicnode/input/LN_on_swipe.py 2025-04-03 09:46:41 +00:00
1764081740 Update leenkx/blender/lnx/logicnode/draw/LN_draw_polygon.py 2025-04-03 09:45:19 +00:00
c90bde8719 Update leenkx/blender/lnx/logicnode/draw/LN_draw_camera.py 2025-04-03 09:44:34 +00:00
bfb11275df Update leenkx/blender/lnx/logicnode/custom/LN_touch_pad.py 2025-04-03 09:43:48 +00:00
3185f61f39 Update leenkx/blender/lnx/logicnode/custom/LN_set_element_data.py 2025-04-03 09:43:13 +00:00
fb00ca88ff Update leenkx/blender/lnx/logicnode/custom/LN_seed_torrent.py 2025-04-03 09:42:15 +00:00
78109cfee2 Update leenkx/blender/lnx/logicnode/custom/LN_leenkx_send_message.py 2025-04-03 09:41:20 +00:00
fa65c02e8a Update leenkx/blender/lnx/logicnode/custom/LN_leenkx_event.py 2025-04-03 09:37:54 +00:00
cb93ede7d7 Update leenkx/blender/lnx/logicnode/custom/LN_create_torrent.py 2025-04-03 09:37:04 +00:00
2a3f8db0bc Update leenkx/blender/lnx/logicnode/custom/LN_create_style.py 2025-04-03 09:36:23 +00:00
3ab9123000 Update leenkx/blender/lnx/logicnode/custom/LN_call_wasm.py 2025-04-03 09:34:57 +00:00
d6b4b6eeea Update leenkx/blender/lnx/logicnode/custom/LN_add_torrent.py 2025-04-03 09:34:21 +00:00
2f1e6783a4 Update leenkx/blender/lnx/logicnode/array/LN_array_vector.py 2025-04-03 09:33:39 +00:00
603a976adf Update leenkx/blender/lnx/logicnode/array/LN_array_string.py 2025-04-03 09:32:59 +00:00
1e0d32a88d Update leenkx/blender/lnx/logicnode/array/LN_array_object.py 2025-04-03 09:32:27 +00:00
82a7075308 Update leenkx/blender/lnx/logicnode/array/LN_array_integer.py 2025-04-03 09:31:30 +00:00
de8f7d08ed Update leenkx/blender/lnx/logicnode/array/LN_array_float.py 2025-04-03 09:30:57 +00:00
caf95e2611 Update leenkx/blender/lnx/logicnode/array/LN_array_color.py 2025-04-03 09:30:04 +00:00
b639f06aba Update leenkx/blender/lnx/logicnode/array/LN_array_boolean.py 2025-04-03 09:29:40 +00:00
de41800e1c Update leenkx/blender/lnx/logicnode/array/LN_array_add.py 2025-04-03 09:28:34 +00:00
d2746fb087 Update leenkx/blender/lnx/logicnode/array/LN_array.py 2025-04-03 09:27:55 +00:00
62d3e65796 Update leenkx/blender/lnx/logicnode/animation/LN_switch_action_multi.py 2025-04-03 09:27:03 +00:00
74473087b5 Update leenkx/blender/lnx/logicnode/animation/LN_one_shot_action_multi.py 2025-04-03 09:26:00 +00:00
392da64d1f Update leenkx/blender/lnx/logicnode/animation/LN_blend_space_gpu.py 2025-04-03 09:24:45 +00:00
30748390ca Update Kha/Kinc/Backends/System/Linux/Sources/kinc/backend/sound.c.h 2025-04-03 06:41:21 +00:00
f9d463ca1d Update leenkx/blender/lnx/exporter.py 2025-03-31 21:06:33 +00:00
b8771e9d81 Update leenkx/blender/lnx/props.py 2025-03-31 20:17:15 +00:00
1f52eed66c Update leenkx/blender/lnx/material/cycles_nodes/nodes_shader.py 2025-03-31 16:18:28 +00:00
e562b626cb Merge pull request 'main' (#10) from Onek8/LNXSDK:main into main
Reviewed-on: #10
2025-03-31 13:54:10 +00:00
ccb554ba16 Update leenkx/blender/lnx/utils.py 2025-03-31 13:51:58 +00:00
972775b432 Upload files to "Krom" 2025-03-31 11:28:16 +00:00
ee984c332e Update leenkx/Shaders/std/shadows.glsl 2025-03-31 10:07:41 +00:00
038e5123c9 Merge pull request 'Update leenkx/Sources/leenkx/logicnode/ApplyForceNode.hx' (#9) from Onek8/LNXSDK:main into main
Reviewed-on: #9
2025-03-28 18:13:48 +00:00
b5575e5a48 Update leenkx/Sources/leenkx/logicnode/ApplyForceNode.hx 2025-03-28 18:12:17 +00:00
76d79e6e18 Merge pull request 'Update leenkx/Sources/iron/object/Animation.hx' (#8) from Onek8/LNXSDK:main into main
Reviewed-on: #8
2025-03-27 21:22:55 +00:00
ca8fd0b357 Update leenkx/Sources/iron/object/Animation.hx 2025-03-27 21:20:54 +00:00
87fa82e3d3 Merge pull request 'main' (#6) from Onek8/LNXSDK:main into main
Reviewed-on: #6
2025-03-25 23:36:02 +00:00
9fa58d9d7c Update leenkx/blender/lnx/logicnode/lnx_sockets.py 2025-03-25 23:34:47 +00:00
864568d66b Update leenkx/blender/lnx/node_utils.py 2025-03-25 23:29:22 +00:00
f3e96546ae Update leenkx/blender/lnx/logicnode/lnx_sockets.py 2025-03-25 19:52:50 +00:00
fcc114aed3 Update leenkx.py 2025-03-25 19:26:40 +00:00
df33848bee Merge pull request 'Animation fixes' (#5) from Onek8/LNXSDK:main into main
Reviewed-on: #5
2025-03-24 16:30:58 +00:00
c17516a4e2 Update leenkx/blender/lnx/logicnode/animation/LN_blend_space_gpu.py 2025-03-24 16:28:49 +00:00
9b9acd5e15 Update leenkx/blender/lnx/logicnode/lnx_sockets.py 2025-03-24 16:27:16 +00:00
3b0eb0e075 Update leenkx/blender/lnx/logicnode/animation/LN_bone_ik.py 2025-03-24 16:25:00 +00:00
f5b3da3a15 Update leenkx/blender/lnx/logicnode/animation/LN_blend_action.py 2025-03-24 16:22:49 +00:00
b71275d0d5 Merge pull request 'Update leenkx/blender/lnx/make.py' (#4) from Onek8/LNXSDK:main into main
Reviewed-on: #4
2025-03-23 16:47:47 +00:00
6aeb9b0f22 Update leenkx/blender/lnx/make.py 2025-03-23 16:46:18 +00:00
609477737e Update leenkx/blender/lnx/make.py 2025-03-23 13:17:06 +00:00
a747f89438 Update leenkx/blender/lnx/props.py 2025-03-19 16:26:03 +00:00
0bd0c57a00 Update leenkx/blender/lnx/write_data.py 2025-03-19 16:24:04 +00:00
f3ab801928 Update leenkx/blender/lnx/write_data.py 2025-03-19 12:36:00 +00:00
9b821d4b8e Update leenkx/blender/lnx/props.py 2025-03-19 12:34:18 +00:00
f2a0dbe36c Update leenkx/Shaders/std/shadows.glsl 2025-03-17 20:31:43 +00:00
12e66d8cf1 Update leenkx/Sources/leenkx/trait/physics/bullet/PhysicsWorld.hx 2025-03-15 21:23:07 +00:00
4b6424b702 Update leenkx/Shaders/ssrefr_pass/ssrefr_pass.frag.glsl 2025-03-15 15:44:22 +00:00
e66e082cc7 Update leenkx/blender/lnx/material/make_cluster.py 2025-03-15 07:22:49 +00:00
42eff22cbb Update leenkx/Shaders/std/shadows.glsl 2025-03-14 19:59:02 +00:00
448898a634 Update leenkx/blender/lnx/write_data.py 2025-03-14 17:33:00 +00:00
15ec41b1f0 Update leenkx/blender/lnx/material/make_mesh.py 2025-03-14 11:04:03 +00:00
c5a7746c84 Update leenkx/Sources/leenkx/logicnode/SetBoneTransformNode.hx 2025-03-12 13:02:09 +00:00
51aa8ea1d4 Upload files to "leenkx/Sources/leenkx/logicnode" 2025-03-12 13:00:54 +00:00
ccdfc4246f Upload files to "leenkx/blender/lnx/logicnode/animation" 2025-03-12 13:00:13 +00:00
aead4c4903 Update leenkx/Sources/leenkx/logicnode/SetParentBoneNode.hx 2025-03-11 19:00:35 +00:00
d2f4c0e221 Update leenkx/blender/lnx/logicnode/animation/LN_set_parent_bone.py 2025-03-11 18:59:58 +00:00
887eeebe27 Update leenkx/Sources/leenkx/logicnode/PlayActionFromNode.hx.backup 2025-03-11 18:57:52 +00:00
83077e3f15 Update leenkx/Sources/leenkx/logicnode/TouchPadNode.hx.backup 2025-03-11 18:57:25 +00:00
f5c20c5a13 Update leenkx/Sources/leenkx/logicnode/AudioHRTFPannerNode.hx 2025-03-11 18:56:39 +00:00
4bd4995b6e Update leenkx/Sources/leenkx/logicnode/SetParentBoneNode.hx 2025-03-11 11:27:26 +00:00
381744e678 Update leenkx/blender/lnx/logicnode/animation/LN_set_parent_bone.py 2025-03-11 11:26:34 +00:00
34c15c29cd Update leenkx/blender/lnx/props_ui.py 2025-03-07 11:15:32 +00:00
0346e27657 Update leenkx/blender/lnx/props_ui.py 2025-03-07 11:14:50 +00:00
9087b9c98c Update leenkx/Sources/zui/Zui.hx 2025-03-07 11:05:17 +00:00
f2cbcc88a7 moisesjpelaez - Enable touch input from mobile browsers #3129 2025-03-07 11:03:28 +00:00
b8d9ea2aff Update leenkx/Sources/leenkx/logicnode/GetBoneTransformNode.hx 2025-02-08 21:19:41 +00:00
37a09d0a21 Update leenkx/blender/lnx/keymap.py 2025-02-08 17:29:46 +00:00
ed932e3fa4 Update leenkx/blender/lnx/material/cycles_nodes/nodes_shader.py 2025-02-06 17:13:41 +00:00
f00edd882f Update leenkx/blender/lnx/material/cycles_nodes/nodes_shader.py 2025-02-06 17:08:33 +00:00
f403955fcd Update leenkx/blender/lnx/utils.py 2025-02-05 23:03:31 +00:00
a562af9b60 Update Kha/Backends/Kinc-HL/kinc-bridge/shader.c.h 2025-02-01 17:09:05 +00:00
bdd9b0197f Update lib/aura/Backends/hl/aura/math/FFT.h 2025-02-01 16:02:29 +00:00
f200933375 Update lib/aura/Backends/hl/aura/aurahl.c 2025-02-01 14:18:03 +00:00
829ef5f269 Update Kha/Kinc/Sources/kinc/input/gamepad.h 2025-02-01 14:10:05 +00:00
0d73133f36 Update Kha/Backends/Kinc-HL/kinc-bridge/system.c.h 2025-02-01 14:08:47 +00:00
181b860360 Update Kha/Backends/Kinc-HL/kinc-bridge/kinc.c.h 2025-02-01 13:53:43 +00:00
20db9cc24d Update Kha/Backends/Kinc-HL/kinc-bridge/compute.c.h 2025-02-01 12:16:54 +00:00
c67b38ea1e Update Compute Shader 2025-01-31 20:35:00 +00:00
adb95eab1e Hashlink Voxels Fix 2025-01-31 20:05:18 +00:00
93addd1200 Update Kha/Backends/Kinc-HL/hl/include/mbedtls/library/entropy_poll.c 2025-01-31 20:00:32 +00:00
7f9a7c9b4a Update leenkx/blender/lnx/material/make_mesh.py 2025-01-31 12:37:04 +00:00
7433409cda Anti aliasing only working with TAA 2025-01-31 08:56:57 +00:00
2a6e05aff1 Update new repo node links 2025-01-31 07:17:39 +00:00
348d7bf343 Merge pull request 'More 4.3 + support' (#3) from Onek8/LNXSDK:main into main
Reviewed-on: #3
2025-01-30 13:43:29 +00:00
4c6df16aa7 Update leenkx/blender/lnx/write_data.py 2025-01-30 13:39:55 +00:00
8a7f5ee519 Update leenkx/blender/lnx/props_ui.py 2025-01-30 13:21:20 +00:00
1958342a74 Add leenkx/blender/lnx/logicnode/browser/LN_detect_mobile_browser.py 2025-01-29 08:11:04 +00:00
16e8e00783 Delete leenkx/blender/lnx/logicnode/native/LN_detect_mobile_browser.py 2025-01-29 08:10:15 +00:00
bcdcbfb106 Delete leenkx/blender/lnx/logicnode/native/LN_loadUrl.py 2025-01-29 08:09:43 +00:00
28afefbbf7 Add leenkx/blender/lnx/logicnode/browser/LN_loadUrl.py 2025-01-29 08:04:56 +00:00
3d2130e26a Delete leenkx/blender/lnx/logicnode/browser/LN_loadUrl.py 2025-01-27 11:58:52 +00:00
9761719dd5 Delete leenkx/blender/lnx/logicnode/browser/LN_detect_mobile_browser.py 2025-01-27 11:58:45 +00:00
b2a781c7c2 Update leenkx/blender/lnx/material/make_mesh.py 2025-01-24 11:45:21 +00:00
7121737297 Fix missing export 2025-01-24 11:41:47 +00:00
b0991a8928 Update README.md 2025-01-24 08:38:05 +00:00
b84fc93899 Update leenkx/blender/lnx/material/make_mesh.py 2025-01-24 08:03:17 +00:00
06c0c430a8 Update leenkx/blender/lnx/utils.py 2025-01-23 17:15:03 +00:00
0f0c67dc07 Update leenkx/blender/lnx/utils.py 2025-01-23 17:07:29 +00:00
3bb2d65faa Update leenkx.py 2025-01-23 17:05:07 +00:00
20e33afeac Merge pull request 'main' (#2) from Onek8/LNXSDK:main into main
Reviewed-on: #2
2025-01-23 16:09:12 +00:00
9c5fc5d1d3 merge upstream 2025-01-23 16:07:22 +00:00
6bed0cbc6d Update leenkx.py 2025-01-23 15:59:04 +00:00
0eb4effeb3 Update leenkx/Sources/leenkx/logicnode/AudioLoadNode.hx 2025-01-23 15:52:00 +00:00
238acaad0a Delete leenkx/Sources/iron2/tools/io_export_lnx.py 2025-01-22 16:35:58 +00:00
f4f5665835 Delete leenkx/Sources/iron2/README.md 2025-01-22 16:35:48 +00:00
eb15dddd38 Delete leenkx/Sources/iron2/LICENSE.md 2025-01-22 16:35:43 +00:00
8c238c320d Delete leenkx/Sources/iron2/checkstyle.json 2025-01-22 16:35:37 +00:00
ef27ce45ae Delete leenkx/Sources/iron2/changes.md 2025-01-22 16:35:31 +00:00
61a4bf0ff8 Delete Krom/README.md 2025-01-22 16:33:00 +00:00
b985c5949b Update Krom/README.md 2025-01-22 16:32:52 +00:00
cd6930c56b Update README.md 2025-01-22 15:34:31 +00:00
014951b080 Update README.md 2025-01-22 15:33:58 +00:00
489d4d56f6 Merge pull request 'Upload files to "/"' (#1) from Onek8/LNXSDK:main into main
Reviewed-on: #1
2025-01-22 15:23:23 +00:00
a36294b518 Update Files 2025-01-22 16:18:30 +01:00
ed4603cf95 Upload files to "/" 2025-01-22 14:19:54 +00:00
16090 changed files with 2967406 additions and 1 deletions

11
.editorconfig Normal file
View File

@ -0,0 +1,11 @@
root = true
[*]
charset = utf-8
tab_width = 4
indent_style = tab
[*.py]
indent_size = 4
tab_width = 4
indent_style = space

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
*.hdr binary
blender/lnx/props.py ident

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
__pycache__/
*.pyc
*.DS_Store

8
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"editor.detectIndentation": false,
"editor.tabSize": 4,
"editor.insertSpaces": false,
"[python]": {
"editor.insertSpaces": true
}
}

79
Kha/.clang-format Normal file
View File

@ -0,0 +1,79 @@
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: true
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 160
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
FixNamespaceComments: false
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: All
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp03
TabWidth: 4
UseTab: ForIndentation

6
Kha/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,6 @@
{
"[haxe]": {
"editor.formatOnSave": true,
"editor.formatOnPaste": false
},
}

View File

@ -0,0 +1,3 @@
package kha;
typedef Blob = kha.internal.BytesBlob;

View File

@ -0,0 +1,75 @@
package kha;
class Display {
static var instance: Display = new Display();
function new() {}
public static function init(): Void {}
public static var primary(get, never): Display;
static function get_primary(): Display {
return instance;
}
public static var all(get, never): Array<Display>;
static function get_all(): Array<Display> {
return [primary];
}
public var available(get, never): Bool;
function get_available(): Bool {
return true;
}
public var name(get, never): String;
function get_name(): String {
return "Display";
}
public var x(get, never): Int;
function get_x(): Int {
return 0;
}
public var y(get, never): Int;
function get_y(): Int {
return 0;
}
public var width(get, never): Int;
function get_width(): Int {
return 1920;
}
public var height(get, never): Int;
function get_height(): Int {
return 1080;
}
public var frequency(get, never): Int;
function get_frequency(): Int {
return 60;
}
public var pixelsPerInch(get, never): Int;
function get_pixelsPerInch(): Int {
return 96;
}
public var modes(get, never): Array<DisplayMode>;
function get_modes(): Array<DisplayMode> {
return [];
}
}

View File

@ -0,0 +1,27 @@
package kha;
class DisplayImpl {
public static function count(): Int {
return 1;
}
public static function width(index: Int): Int {
return -1;
}
public static function height(index: Int): Int {
return -1;
}
public static function x(index: Int): Int {
return -1;
}
public static function y(index: Int): Int {
return -1;
}
public static function isPrimary(index: Int): Bool {
return true;
}
}

View File

@ -0,0 +1,7 @@
package kha;
class EnvironmentVariables {
public static function get(name: String): String {
return null;
}
}

View File

@ -0,0 +1,3 @@
package kha;
typedef Font = kha.Kravur;

View File

@ -0,0 +1,173 @@
package kha;
import haxe.io.Bytes;
import kha.graphics4.DepthStencilFormat;
import kha.graphics4.TextureFormat;
import kha.graphics4.Usage;
class Image implements Canvas implements Resource {
public static function create(width: Int, height: Int, format: TextureFormat = null, usage: Usage = null): Image {
return null;
}
public static function create3D(width: Int, height: Int, depth: Int, format: TextureFormat = null, usage: Usage = null): Image {
return null;
}
public static function createRenderTarget(width: Int, height: Int, format: TextureFormat = null,
depthStencil: DepthStencilFormat = DepthStencilFormat.NoDepthAndStencil, antiAliasingSamples: Int = 1): Image {
return null;
}
public static function fromBytes(bytes: Bytes, width: Int, height: Int, format: TextureFormat = null, usage: Usage = null): Image {
return null;
}
public static function fromBytes3D(bytes: Bytes, width: Int, height: Int, depth: Int, format: TextureFormat = null, usage: Usage = null): Image {
return null;
}
public static var maxSize(get, never): Int;
static function get_maxSize(): Int {
return 0;
}
public static var nonPow2Supported(get, never): Bool;
static function get_nonPow2Supported(): Bool {
return false;
}
public static function renderTargetsInvertedY(): Bool {
return false;
}
public function isOpaque(x: Int, y: Int): Bool {
return false;
}
/**
* Returns the color of a pixel identified by its x/y-coordinates. This only works for images for which
* the readable flag is set to true because by default images only exist in video-memory. To load images
* which are readable use a line ala project.addAssets('Assets/image.png', { readable: true }); in
* your khafile.
* For reading the content of render-targets use getPixels() instead.
*/
public function at(x: Int, y: Int): Color {
return Color.Black;
}
public function unload(): Void {}
/**
* Returns a writable Bytes object. Once unlock() is called the content of the Bytes object
* is written into the image.
* This can not be used to read the current content of an image - for this use at() or getPixels() instead.
*/
public function lock(level: Int = 0): Bytes {
return null;
}
public function unlock(): Void {}
/**
* Returns the content of an image. This only works if the image is a render-target and it is very slow
* because data will be copied from video-memory to main-memory. This is useful for making screenshots
* but please avoid using it for regular rendering.
* For reading the content of images which are not render-targets use at() instead.
*/
public function getPixels(): Bytes {
return null;
}
public function generateMipmaps(levels: Int): Void {}
public function setMipmaps(mipmaps: Array<Image>): Void {}
public function setDepthStencilFrom(image: Image): Void {}
public function clear(x: Int, y: Int, z: Int, width: Int, height: Int, depth: Int, color: Color): Void {}
/**
* Returns the original width of the image.
*/
public var width(get, never): Int;
function get_width(): Int {
return 0;
}
/**
* Returns the original height of the image.
*/
public var height(get, never): Int;
function get_height(): Int {
return 0;
}
public var depth(get, never): Int;
function get_depth(): Int {
return 1;
}
public var format(get, never): TextureFormat;
function get_format(): TextureFormat {
return TextureFormat.RGBA32;
}
/**
* Very old GPUs only supported power of two texture-widths.
* When an Image is created on such a GPU, Kha automatically increases
* its size to a power of two and realWidth returns this new, internal
* size. Knowing the real size is important for calculating
* texture-coordinates correctly but all of this is irrelevant unless
* you really want to support very very old GPUs.
*/
public var realWidth(get, never): Int;
function get_realWidth(): Int {
return 0;
}
/**
* Very old GPUs only supported power of two texture-heights.
* When an Image is created on such a GPU, Kha automatically increases
* its size to a power of two and realHeight returns this new, internal
* size. Knowing the real size is important for calculating
* texture-coordinates correctly but all of this is irrelevant unless
* you really want to support very very old GPUs.
*/
public var realHeight(get, never): Int;
function get_realHeight(): Int {
return 0;
}
public var stride(get, never): Int;
function get_stride(): Int {
return 0;
}
public var g1(get, never): kha.graphics1.Graphics;
function get_g1(): kha.graphics1.Graphics {
return null;
}
public var g2(get, never): kha.graphics2.Graphics;
function get_g2(): kha.graphics2.Graphics {
return null;
}
public var g4(get, never): kha.graphics4.Graphics;
function get_g4(): kha.graphics4.Graphics {
return null;
}
}

View File

@ -0,0 +1,31 @@
package kha;
import kha.FontStyle;
import kha.Blob;
import kha.Kravur;
import haxe.io.Bytes;
import haxe.io.BytesData;
class LoaderImpl {
public static function getImageFormats(): Array<String> {
return ["png", "jpg"];
}
public static function loadImageFromDescription(desc: Dynamic, done: kha.Image->Void, failed: AssetError->Void) {}
public static function getSoundFormats(): Array<String> {
return ["mp4", "ogg"];
}
public static function loadSoundFromDescription(desc: Dynamic, done: kha.Sound->Void, failed: AssetError->Void) {}
public static function getVideoFormats(): Array<String> {
return ["mp4", "webm"];
}
public static function loadVideoFromDescription(desc: Dynamic, done: kha.Video->Void, failed: AssetError->Void): Void {}
public static function loadBlobFromDescription(desc: Dynamic, done: Blob->Void, failed: AssetError->Void) {}
public static function loadFontFromDescription(desc: Dynamic, done: Font->Void, failed: AssetError->Void): Void {}
}

View File

@ -0,0 +1,15 @@
package kha;
import haxe.io.Bytes;
import haxe.io.BytesBuffer;
import haxe.io.BytesData;
class Storage {
public static function namedFile(name: String): StorageFile {
return null;
}
public static function defaultFile(): StorageFile {
return namedFile("default.kha");
}
}

View File

@ -0,0 +1,139 @@
package kha;
import kha.graphics4.TextureFormat;
import kha.input.Gamepad;
import kha.input.Keyboard;
import kha.input.Mouse;
import kha.input.MouseImpl;
import kha.input.Surface;
import kha.System;
class SystemImpl {
public static function init(options: SystemOptions, callback: Window->Void): Void {}
public static function getScreenRotation(): ScreenRotation {
return ScreenRotation.RotationNone;
}
public static function getTime(): Float {
return 0;
}
public static function windowWidth(id: Int): Int {
return 640;
}
public static function windowHeight(id: Int): Int {
return 480;
}
public static function screenDpi(): Int {
return 96;
}
public static function getVsync(): Bool {
return true;
}
public static function getRefreshRate(): Int {
return 60;
}
public static function getSystemId(): String {
return "Empty";
}
public static function vibrate(ms: Int): Void {}
public static function getLanguage(): String {
return "en";
}
public static function requestShutdown(): Bool {
return true;
}
public static function getMouse(num: Int): Mouse {
return null;
}
public static function getKeyboard(num: Int): Keyboard {
return null;
}
public static function lockMouse(): Void {}
public static function unlockMouse(): Void {}
public static function canLockMouse(): Bool {
return false;
}
public static function isMouseLocked(): Bool {
return false;
}
public static function notifyOfMouseLockChange(func: Void->Void, error: Void->Void): Void {}
public static function removeFromMouseLockChange(func: Void->Void, error: Void->Void): Void {}
static function unload(): Void {}
public static function canSwitchFullscreen(): Bool {
return false;
}
public static function isFullscreen(): Bool {
return false;
}
public static function requestFullscreen(): Void {}
public static function exitFullscreen(): Void {}
public static function notifyOfFullscreenChange(func: Void->Void, error: Void->Void): Void {}
public static function removeFromFullscreenChange(func: Void->Void, error: Void->Void): Void {}
public static function changeResolution(width: Int, height: Int): Void {}
public static function setKeepScreenOn(on: Bool): Void {}
public static function loadUrl(url: String): Void {}
public static function getGamepadId(index: Int): String {
return "unknown";
}
public static function getGamepadVendor(index: Int): String {
return "unknown";
}
public static function setGamepadRumble(index: Int, leftAmount: Float, rightAmount: Float) {}
public static function getPen(num: Int): kha.input.Pen {
return null;
}
public static function safeZone(): Float {
return 1.0;
}
public static function login(): Void {}
public static function automaticSafeZone(): Bool {
return true;
}
public static function setSafeZone(value: Float): Void {}
public static function unlockAchievement(id: Int): Void {}
public static function waitingForLogin(): Bool {
return false;
}
public static function disallowUserChange(): Void {}
public static function allowUserChange(): Void {}
}

View File

@ -0,0 +1,134 @@
package kha;
class Window {
static var windows: Array<Window> = [];
var defaultWidth: Int;
var defaultHeight: Int;
@:noCompletion
@:noDoc
public function new(defaultWidth: Int, defaultHeight: Int) {
windows.push(this);
}
public static function create(win: WindowOptions = null, frame: FramebufferOptions = null): Window {
return null;
}
public static function destroy(window: Window): Void {}
public static function get(index: Int): Window {
return windows[index];
}
public static var all(get, never): Array<Window>;
static function get_all(): Array<Window> {
return windows;
}
public function resize(width: Int, height: Int): Void {}
public function move(x: Int, y: Int): Void {}
public function changeWindowFeatures(features: Int): Void {}
public function changeFramebuffer(frame: FramebufferOptions): Void {}
public var x(get, set): Int;
function get_x(): Int {
return 0;
}
function set_x(value: Int): Int {
return 0;
}
public var y(get, set): Int;
function get_y(): Int {
return 0;
}
function set_y(value: Int): Int {
return 0;
}
public var width(get, set): Int;
function get_width(): Int {
return 800;
}
function set_width(value: Int): Int {
return 800;
}
public var height(get, set): Int;
function get_height(): Int {
return 600;
}
function set_height(value: Int): Int {
return 600;
}
public var mode(get, set): WindowMode;
function get_mode(): WindowMode {
return Windowed;
}
function set_mode(mode: WindowMode): WindowMode {
if (mode == Fullscreen || mode == ExclusiveFullscreen) {
if (!isFullscreen()) {
requestFullscreen();
}
}
else {
if (isFullscreen()) {
exitFullscreen();
}
}
return mode;
}
function isFullscreen(): Bool {
return false;
}
function requestFullscreen(): Void {}
function exitFullscreen(): Void {}
public var visible(get, set): Bool;
function get_visible(): Bool {
return true;
}
function set_visible(value: Bool): Bool {
return true;
}
public var title(get, set): String;
function get_title(): String {
return "Kha";
}
function set_title(value: String): String {
return "Kha";
}
public function notifyOnResize(callback: Int->Int->Void): Void {}
public var vSynced(get, never): Bool;
function get_vSynced(): Bool {
return true;
}
}

View File

@ -0,0 +1,153 @@
package kha.arrays;
import kha.FastFloat;
class ByteArray {
public var buffer(get, never): ByteBuffer;
inline function get_buffer(): ByteBuffer {
return null;
}
public function new(buffer: ByteBuffer, ?byteOffset: Int, ?byteLength: Int) {}
static public function make(byteLength: Int): ByteArray {
return null;
}
public var byteLength(get, never): Int;
inline function get_byteLength(): Int {
return 0;
}
public var byteOffset(get, never): Int;
inline function get_byteOffset(): Int {
return 0;
}
public inline function getInt8(byteOffset: Int): Int {
return 0;
}
public inline function getUint8(byteOffset: Int): Int {
return 0;
}
public inline function getInt16(byteOffset: Int): Int {
return 0;
}
public inline function getUint16(byteOffset: Int): Int {
return 0;
}
public inline function getInt32(byteOffset: Int): Int {
return 0;
}
public inline function getUint32(byteOffset: Int): Int {
return 0;
}
public inline function getFloat32(byteOffset: Int): FastFloat {
return 0;
}
public inline function getFloat64(byteOffset: Int): Float {
return 0;
}
public inline function setInt8(byteOffset: Int, value: Int): Void {}
public inline function setUint8(byteOffset: Int, value: Int): Void {}
public inline function setInt16(byteOffset: Int, value: Int): Void {}
public inline function setUint16(byteOffset: Int, value: Int): Void {}
public inline function setInt32(byteOffset: Int, value: Int): Void {}
public inline function setUint32(byteOffset: Int, value: Int): Void {}
public inline function setFloat32(byteOffset: Int, value: FastFloat): Void {}
public inline function setFloat64(byteOffset: Int, value: Float): Void {}
public inline function getInt16LE(byteOffset: Int): Int {
return 0;
}
public inline function getUint16LE(byteOffset: Int): Int {
return 0;
}
public inline function getInt32LE(byteOffset: Int): Int {
return 0;
}
public inline function getUint32LE(byteOffset: Int): Int {
return 0;
}
public inline function getFloat32LE(byteOffset: Int): FastFloat {
return 0;
}
public inline function getFloat64LE(byteOffset: Int): Float {
return 0;
}
public inline function setInt16LE(byteOffset: Int, value: Int): Void {}
public inline function setUint16LE(byteOffset: Int, value: Int): Void {}
public inline function setInt32LE(byteOffset: Int, value: Int): Void {}
public inline function setUint32LE(byteOffset: Int, value: Int): Void {}
public inline function setFloat32LE(byteOffset: Int, value: FastFloat): Void {}
public inline function setFloat64LE(byteOffset: Int, value: Float): Void {}
public inline function getInt16BE(byteOffset: Int): Int {
return 0;
}
public inline function getUint16BE(byteOffset: Int): Int {
return 0;
}
public inline function getInt32BE(byteOffset: Int): Int {
return 0;
}
public inline function getUint32BE(byteOffset: Int): Int {
return 0;
}
public inline function getFloat32BE(byteOffset: Int): FastFloat {
return 0;
}
public inline function getFloat64BE(byteOffset: Int): Float {
return 0;
}
public inline function setInt16BE(byteOffset: Int, value: Int): Void {}
public inline function setUint16BE(byteOffset: Int, value: Int): Void {}
public inline function setInt32BE(byteOffset: Int, value: Int): Void {}
public inline function setUint32BE(byteOffset: Int, value: Int): Void {}
public inline function setFloat32BE(byteOffset: Int, value: FastFloat): Void {}
public inline function setFloat64BE(byteOffset: Int, value: Float): Void {}
public inline function subarray(start: Int, ?end: Int): ByteArray {
return new ByteArray(buffer, start, end != null ? end - start : null);
}
}

View File

@ -0,0 +1,9 @@
package kha.arrays;
class ByteBuffer {
public static function create(length: Int): ByteBuffer {
return null;
}
function new(length: Int) {}
}

View File

@ -0,0 +1,23 @@
package kha.audio1;
import kha.Sound;
class Audio {
/**
* Plays a sound immediately.
* @param sound
* The sound to play
* @param loop
* Whether or not to automatically loop the sound
* @return A channel object that can be used to control the playing sound. Please be a ware that Null is returned when the maximum number of simultaneously played channels was reached.
*/
public static function play(sound: Sound, loop: Bool = false): AudioChannel {
return null;
}
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
return null;
}
public static function _playAgain(channel: kha.audio2.AudioChannel): Void {}
}

View File

@ -0,0 +1,14 @@
package kha.audio2;
import kha.Sound;
import kha.internal.IntBox;
class Audio {
public static var disableGcInteractions = false;
public static var samplesPerSecond: Int;
public static var audioCallback: IntBox->Buffer->Void;
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
return null;
}
}

View File

@ -0,0 +1,47 @@
package kha.graphics4;
import haxe.io.Bytes;
class CubeMap implements Canvas implements Resource {
public static function createRenderTarget(size: Int, format: TextureFormat = null, depthStencil: DepthStencilFormat = null): CubeMap {
return null;
}
public function unload(): Void {}
public function lock(level: Int = 0): Bytes {
return null;
}
public function unlock(): Void {}
public var width(get, never): Int;
function get_width(): Int {
return 0;
}
public var height(get, never): Int;
function get_height(): Int {
return 0;
}
public var g1(get, never): kha.graphics1.Graphics;
function get_g1(): kha.graphics1.Graphics {
return null;
}
public var g2(get, never): kha.graphics2.Graphics;
function get_g2(): kha.graphics2.Graphics {
return null;
}
public var g4(get, never): kha.graphics4.Graphics;
function get_g4(): kha.graphics4.Graphics {
return null;
}
}

View File

@ -0,0 +1,19 @@
package kha.graphics4;
class FragmentShader {
public var sources: Array<String>;
public var type: Dynamic;
public var shader: Dynamic;
public var files: Array<String>;
public function new(sources: Array<Blob>, files: Array<String>) {}
public static function fromSource(source: String): FragmentShader {
return null;
}
public function delete(): Void {
shader = null;
sources = null;
}
}

View File

@ -0,0 +1,19 @@
package kha.graphics4;
import kha.graphics4.Usage;
class IndexBuffer {
public function new(indexCount: Int, usage: Usage, canRead: Bool = false) {}
public function lock(?start: Int, ?count: Int): Array<Int> {
return null;
}
public function unlock(?count: Int): Void {}
public function set(): Void {}
public function count(): Int {
return 0;
}
}

View File

@ -0,0 +1,24 @@
package kha.graphics4;
import kha.graphics4.FragmentShader;
import kha.graphics4.VertexData;
import kha.graphics4.VertexShader;
import kha.graphics4.VertexStructure;
class PipelineState extends PipelineStateBase {
public function new() {
super();
}
public function compile(): Void {}
public function set(): Void {}
public function getConstantLocation(name: String): kha.graphics4.ConstantLocation {
return null;
}
public function getTextureUnit(name: String): kha.graphics4.TextureUnit {
return null;
}
}

View File

@ -0,0 +1,28 @@
package kha.graphics4;
import kha.arrays.Float32Array;
import kha.graphics4.Usage;
import kha.graphics4.VertexStructure;
import kha.graphics4.VertexData;
class VertexBuffer {
public function new(vertexCount: Int, structure: VertexStructure, usage: Usage, instanceDataStepRate: Int = 0, canRead: Bool = false) {}
public function lock(?start: Int, ?count: Int): Float32Array {
return null;
}
public function unlock(?count: Int): Void {}
public function stride(): Int {
return 0;
}
public function count(): Int {
return 0;
}
public function set(offset: Int): Int {
return 0;
}
}

View File

@ -0,0 +1,19 @@
package kha.graphics4;
class VertexShader {
public var sources: Array<String>;
public var type: Dynamic;
public var shader: Dynamic;
public var files: Array<String>;
public function new(sources: Array<Blob>, files: Array<String>) {}
public static function fromSource(source: String): FragmentShader {
return null;
}
public function delete(): Void {
shader = null;
sources = null;
}
}

View File

@ -0,0 +1,7 @@
package kha.input;
class MouseImpl extends kha.input.Mouse {
public function new() {
super();
}
}

View File

@ -0,0 +1,11 @@
package kha.netsync;
import haxe.io.Bytes;
class Network {
public function new(url: String, port: Int, errorCallback: Void->Void, closeCallback: Void->Void) {}
public function send(bytes: Bytes, mandatory: Bool): Void {}
public function listen(listener: Bytes->Void): Void {}
}

View File

@ -0,0 +1,8 @@
package kha.network;
import haxe.io.Bytes;
class Http {
public static function request(url: String, path: String, data: String, port: Int, secure: Bool, method: HttpMethod, headers: Map<String, String>,
callback: Int->Int->String->Void /*error, response, body*/): Void {}
}

View File

@ -0,0 +1,3 @@
package kha;
typedef Blob = kha.internal.BytesBlob;

View File

@ -0,0 +1,77 @@
package kha;
import js.Browser;
class Display {
static var instance: Display = new Display();
function new() {}
public static function init(): Void {}
public static var primary(get, never): Display;
static function get_primary(): Display {
return instance;
}
public static var all(get, never): Array<Display>;
static function get_all(): Array<Display> {
return [primary];
}
public var available(get, never): Bool;
function get_available(): Bool {
return true;
}
public var name(get, never): String;
function get_name(): String {
return "Display";
}
public var x(get, never): Int;
function get_x(): Int {
return 0;
}
public var y(get, never): Int;
function get_y(): Int {
return 0;
}
public var width(get, never): Int;
function get_width(): Int {
return 800;
}
public var height(get, never): Int;
function get_height(): Int {
return 600;
}
public var frequency(get, never): Int;
function get_frequency(): Int {
return 60;
}
public var pixelsPerInch(get, never): Int;
function get_pixelsPerInch(): Int {
return 96;
}
public var modes(get, never): Array<DisplayMode>;
function get_modes(): Array<DisplayMode> {
return [];
}
}

View File

@ -0,0 +1,3 @@
package kha;
typedef Font = kha.Kravur;

View File

@ -0,0 +1,222 @@
package kha;
import haxe.io.Bytes;
import kha.graphics4.Graphics;
import kha.graphics4.DepthStencilFormat;
import kha.graphics4.TextureFormat;
import kha.graphics4.Usage;
class Image implements Canvas implements Resource {
public var id: Int;
public var _rtid: Int;
public static var _lastId: Int = -1;
static var lastRtId: Int = -1;
var w: Int;
var h: Int;
var rw: Int;
var rh: Int;
var myFormat: TextureFormat;
var bytes: Bytes = null;
public function new(id: Int, rtid: Int, width: Int, height: Int, realWidth: Int, realHeight: Int, format: TextureFormat) {
this.id = id;
this._rtid = rtid;
w = width;
h = height;
rw = realWidth;
rh = realHeight;
myFormat = format;
}
public static function create(width: Int, height: Int, format: TextureFormat = null, usage: Usage = null, readable: Bool = false): Image {
if (format == null)
format = TextureFormat.RGBA32;
if (usage == null)
usage = Usage.StaticUsage;
var id = ++_lastId;
Worker.postMessage({
command: 'createImage',
id: id,
width: width,
height: height,
format: format,
usage: usage
});
return new Image(id, -1, width, height, width, height, format);
}
public static function create3D(width: Int, height: Int, depth: Int, format: TextureFormat = null, usage: Usage = null, readable: Bool = false): Image {
return null;
}
public static function createRenderTarget(width: Int, height: Int, format: TextureFormat = null,
depthStencil: DepthStencilFormat = DepthStencilFormat.NoDepthAndStencil, antiAliasingSamples: Int = 1): Image {
if (format == null)
format = TextureFormat.RGBA32;
var rtid = ++lastRtId;
Worker.postMessage({
command: 'createRenderTarget',
id: rtid,
width: width,
height: height
});
return new Image(-1, rtid, width, height, width, height, format);
}
public static function fromBytes(bytes: Bytes, width: Int, height: Int, format: TextureFormat = null, usage: Usage = null, readable: Bool = false): Image {
return null;
}
public static function fromBytes3D(bytes: Bytes, width: Int, height: Int, depth: Int, format: TextureFormat = null, usage: Usage = null,
readable: Bool = false): Image {
return null;
}
public static var maxSize(get, never): Int;
static function get_maxSize(): Int {
return 1024 * 4;
}
public static var nonPow2Supported(get, never): Bool;
static function get_nonPow2Supported(): Bool {
return true;
}
public static function renderTargetsInvertedY(): Bool {
return true;
}
public function isOpaque(x: Int, y: Int): Bool {
return false;
}
public function unload(): Void {}
public function lock(level: Int = 0): Bytes {
if (bytes == null) {
switch (myFormat) {
case RGBA32:
bytes = Bytes.alloc(4 * width * height);
case L8:
bytes = Bytes.alloc(width * height);
case RGBA128:
bytes = Bytes.alloc(16 * width * height);
case DEPTH16:
bytes = Bytes.alloc(2 * width * height);
case RGBA64:
bytes = Bytes.alloc(8 * width * height);
case A32:
bytes = Bytes.alloc(4 * width * height);
case A16:
bytes = Bytes.alloc(2 * width * height);
}
}
return bytes;
}
public function unlock(): Void {
Worker.postMessage({command: 'unlockImage', id: id, bytes: bytes.getData()});
}
public function getPixels(): Bytes {
return null;
}
public function generateMipmaps(levels: Int): Void {}
public function setMipmaps(mipmaps: Array<Image>): Void {}
public function setDepthStencilFrom(image: Image): Void {}
public function clear(x: Int, y: Int, z: Int, width: Int, height: Int, depth: Int, color: Color): Void {}
public var width(get, never): Int;
function get_width(): Int {
return w;
}
public var height(get, never): Int;
function get_height(): Int {
return h;
}
public var depth(get, never): Int;
function get_depth(): Int {
return 1;
}
public var format(get, never): TextureFormat;
function get_format(): TextureFormat {
return myFormat;
}
public var realWidth(get, never): Int;
function get_realWidth(): Int {
return rw;
}
public var realHeight(get, never): Int;
function get_realHeight(): Int {
return rh;
}
static function formatByteSize(format: TextureFormat): Int {
return switch (format) {
case RGBA32: 4;
case L8: 1;
case RGBA128: 16;
case DEPTH16: 2;
case RGBA64: 8;
case A32: 4;
case A16: 2;
default: 4;
}
}
public var stride(get, never): Int;
function get_stride(): Int {
return formatByteSize(myFormat) * width;
}
var graphics1: kha.graphics1.Graphics;
var graphics2: kha.graphics2.Graphics;
var graphics4: kha.graphics4.Graphics;
public var g1(get, never): kha.graphics1.Graphics;
function get_g1(): kha.graphics1.Graphics {
if (graphics1 == null) {
graphics1 = new kha.graphics2.Graphics1(this);
}
return graphics1;
}
public var g2(get, never): kha.graphics2.Graphics;
function get_g2(): kha.graphics2.Graphics {
if (graphics2 == null) {
graphics2 = new kha.graphics4.Graphics2(this);
}
return graphics2;
}
public var g4(get, never): kha.graphics4.Graphics;
function get_g4(): kha.graphics4.Graphics {
if (graphics4 == null) {
graphics4 = new kha.html5worker.Graphics(this);
}
return graphics4;
}
}

View File

@ -0,0 +1,80 @@
package kha;
import haxe.io.Bytes;
import kha.graphics4.TextureFormat;
class LoaderImpl {
static var loadingImages: Map<Int, Image->Void> = new Map();
static var loadingSounds: Map<Int, Sound->Void> = new Map();
static var soundId = -1;
static var loadingVideos: Map<Int, Video->Void> = new Map();
static var videoId = -1;
static var loadingBlobs: Map<Int, Blob->Void> = new Map();
static var blobId = -1;
static var sounds: Map<Int, Sound> = new Map();
public static function getImageFormats(): Array<String> {
return ["png", "jpg", "hdr"];
}
public static function loadImageFromDescription(desc: Dynamic, done: kha.Image->Void, failed: AssetError->Void) {
++kha.Image._lastId;
loadingImages[kha.Image._lastId] = done;
Worker.postMessage({command: 'loadImage', file: desc.files[0], id: kha.Image._lastId});
}
public static function _loadedImage(value: Dynamic) {
var image = new Image(value.id, -1, value.width, value.height, value.realWidth, value.realHeight, TextureFormat.RGBA32);
loadingImages[value.id](image);
loadingImages.remove(value.id);
}
public static function getSoundFormats(): Array<String> {
return ["mp4"];
}
public static function loadSoundFromDescription(desc: Dynamic, done: kha.Sound->Void, failed: AssetError->Void) {
++soundId;
loadingSounds[soundId] = done;
Worker.postMessage({command: 'loadSound', file: desc.files[0], id: soundId});
}
public static function _loadedSound(value: Dynamic) {
var sound = new kha.html5worker.Sound(value.id);
loadingSounds[value.id](sound);
loadingSounds.remove(value.id);
sounds.set(value.id, sound);
}
public static function _uncompressedSound(value: Dynamic): Void {
cast(sounds[value.id], kha.html5worker.Sound)._callback();
}
public static function getVideoFormats(): Array<String> {
return ["mp4"];
}
public static function loadVideoFromDescription(desc: Dynamic, done: kha.Video->Void, failed: AssetError->Void): Void {
++videoId;
loadingVideos[videoId] = done;
Worker.postMessage({command: 'loadVideo', file: desc.files[0], id: videoId});
}
public static function loadBlobFromDescription(desc: Dynamic, done: Blob->Void, failed: AssetError->Void) {
++blobId;
loadingBlobs[blobId] = done;
Worker.postMessage({command: 'loadBlob', file: desc.files[0], id: blobId});
}
public static function _loadedBlob(value: Dynamic) {
var blob = new Blob(Bytes.ofData(value.data));
loadingBlobs[value.id](blob);
loadingBlobs.remove(value.id);
}
public static function loadFontFromDescription(desc: Dynamic, done: Font->Void, failed: AssetError->Void): Void {
loadBlobFromDescription(desc, function(blob: Blob) {
done(new Kravur(blob));
}, failed);
}
}

View File

@ -0,0 +1,89 @@
package kha;
import kha.Game;
import kha.input.Gamepad;
import kha.input.Keyboard;
import kha.js.WorkerGraphics;
import kha.Key;
import kha.Loader;
class Starter {
var gameToStart: Game;
static var frame: Framebuffer = null;
static var keyboard: Keyboard;
static var mouse: kha.input.Mouse;
static var gamepad: Gamepad;
public static var mouseX: Int;
public static var mouseY: Int;
public function new() {
Worker.handleMessages(messageHandler);
keyboard = new Keyboard();
mouse = new kha.input.Mouse();
gamepad = new Gamepad();
Loader.init(new kha.js.Loader());
Scheduler.init();
}
public function start(game: Game): Void {
gameToStart = game;
Configuration.setScreen(new EmptyScreen(Color.fromBytes(0, 0, 0)));
Loader.the.loadProject(loadFinished);
}
public function loadFinished() {
Loader.the.initProject();
gameToStart.width = Loader.the.width;
gameToStart.height = Loader.the.height;
Sys.init(gameToStart.width, gameToStart.height);
frame = new Framebuffer(new WorkerGraphics(gameToStart.width, gameToStart.height), null);
Scheduler.start();
Configuration.setScreen(gameToStart);
gameToStart.loadFinished();
}
public function lockMouse(): Void {}
public function unlockMouse(): Void {}
public function canLockMouse(): Bool {
return false;
}
public function isMouseLocked(): Bool {
return false;
}
public function notifyOfMouseLockChange(func: Void->Void, error: Void->Void): Void {}
public function removeFromMouseLockChange(func: Void->Void, error: Void->Void): Void {}
function messageHandler(value: Dynamic): Void {
switch (value.data.command) {
case 'loadedBlob':
cast(Loader.the, kha.js.Loader).loadedBlob(value.data);
case 'loadedImage':
cast(Loader.the, kha.js.Loader).loadedImage(value.data);
case 'loadedSound':
cast(Loader.the, kha.js.Loader).loadedSound(value.data);
case 'loadedMusic':
cast(Loader.the, kha.js.Loader).loadedMusic(value.data);
case 'frame':
if (frame != null) {
Scheduler.executeFrame();
Configuration.screen().render(frame);
}
case 'keyDown':
Configuration.screen().keyDown(Key.createByIndex(value.data.key), value.data.char);
case 'keyUp':
Configuration.screen().keyUp(Key.createByIndex(value.data.key), value.data.char);
}
}
}

View File

@ -0,0 +1,15 @@
package kha;
import haxe.io.Bytes;
import haxe.io.BytesData;
import js.lib.ArrayBuffer;
class Storage {
public static function namedFile(name: String): StorageFile {
return null;
}
public static function defaultFile(): StorageFile {
return namedFile("default.kha");
}
}

View File

@ -0,0 +1,241 @@
package kha;
import kha.input.Gamepad;
import kha.input.Keyboard;
import kha.input.KeyCode;
import kha.input.Mouse;
import kha.input.Surface;
import kha.System;
class GamepadStates {
public var axes: Array<Float>;
public var buttons: Array<Float>;
public function new() {
axes = new Array<Float>();
buttons = new Array<Float>();
}
}
class SystemImpl {
static var options: SystemOptions;
@:allow(kha.Window)
static var width: Int = 800;
@:allow(kha.Window)
static var height: Int = 600;
static var dpi: Int = 96;
static inline var maxGamepads: Int = 4;
static var frame: Framebuffer;
static var keyboard: Keyboard = null;
static var mouse: kha.input.Mouse;
static var surface: Surface;
static var gamepads: Array<Gamepad>;
public static function init(options: SystemOptions, callback: Window->Void) {
Worker.handleMessages(messageHandler);
Shaders.init();
var shaders = new Array<Dynamic>();
for (field in Reflect.fields(Shaders)) {
if (field != "init" && field != "__name__" && field.substr(field.length - 5, 4) != "Data") {
var shader = Reflect.field(Shaders, field);
shaders.push({
name: field,
files: shader.files,
sources: shader.sources
});
}
}
Worker.postMessage({command: 'setShaders', shaders: shaders});
SystemImpl.options = options;
// haxe.Log.trace = untyped js.Boot.__trace; // Hack for JS trace problems
keyboard = new Keyboard();
mouse = new Mouse();
surface = new Surface();
gamepads = new Array<Gamepad>();
for (i in 0...maxGamepads) {
gamepads[i] = new Gamepad(i);
}
var window = new Window();
var g4 = new kha.html5worker.Graphics();
frame = new Framebuffer(0, null, null, g4);
frame.init(new kha.graphics2.Graphics1(frame), new kha.graphics4.Graphics2(frame), g4);
Scheduler.init();
Scheduler.start();
callback(window);
}
public static function windowWidth(windowId: Int = 0): Int {
return Window.get(0).width;
}
public static function windowHeight(windowId: Int = 0): Int {
return Window.get(0).height;
}
public static function screenDpi(): Int {
return dpi;
}
public static function getScreenRotation(): ScreenRotation {
return ScreenRotation.RotationNone;
}
public static function getTime(): Float {
return js.Syntax.code("Date.now()") / 1000;
}
public static function getVsync(): Bool {
return true;
}
public static function getRefreshRate(): Int {
return 60;
}
public static function getSystemId(): String {
return "HTML5-Worker";
}
public static function vibrate(ms: Int): Void {
js.Browser.navigator.vibrate(ms);
}
public static function getLanguage(): String {
final lang = js.Browser.navigator.language;
return lang.substr(0, 2).toLowerCase();
}
public static function requestShutdown(): Bool {
return false;
}
public static function getMouse(num: Int): Mouse {
if (num != 0)
return null;
return mouse;
}
public static function getKeyboard(num: Int): Keyboard {
if (num != 0)
return null;
return keyboard;
}
public static function lockMouse(): Void {}
public static function unlockMouse(): Void {}
public static function canLockMouse(): Bool {
return false;
}
public static function isMouseLocked(): Bool {
return false;
}
public static function notifyOfMouseLockChange(func: Void->Void, error: Void->Void): Void {}
public static function removeFromMouseLockChange(func: Void->Void, error: Void->Void): Void {}
static function unload(_): Void {}
public static function canSwitchFullscreen(): Bool {
return false;
}
public static function isFullscreen(): Bool {
return false;
}
public static function requestFullscreen(): Void {}
public static function exitFullscreen(): Void {}
public static function notifyOfFullscreenChange(func: Void->Void, error: Void->Void): Void {}
public static function removeFromFullscreenChange(func: Void->Void, error: Void->Void): Void {}
public static function changeResolution(width: Int, height: Int): Void {}
public static function setKeepScreenOn(on: Bool): Void {}
public static function loadUrl(url: String): Void {}
public static function getGamepadId(index: Int): String {
return "unknown";
}
public static function getGamepadVendor(index: Int): String {
return "unknown";
}
public static function setGamepadRumble(index: Int, leftAmount: Float, rightAmount: Float) {}
static function messageHandler(value: Dynamic): Void {
switch (value.data.command) {
case 'patch':
js.Lib.eval(value.data.source);
case 'loadedImage':
LoaderImpl._loadedImage(value.data);
case 'loadedSound':
LoaderImpl._loadedSound(value.data);
case 'loadedBlob':
LoaderImpl._loadedBlob(value.data);
case 'uncompressedSound':
LoaderImpl._uncompressedSound(value.data);
case 'frame':
if (frame != null) {
Scheduler.executeFrame();
Worker.postMessage({command: 'beginFrame'});
System.render([frame]);
Worker.postMessage({command: 'endFrame'});
}
case 'setWindowSize':
width = value.data.width;
height = value.data.height;
case 'keyDown':
keyboard.sendDownEvent(cast value.data.key);
case 'keyUp':
keyboard.sendUpEvent(cast value.data.key);
case 'keyPress':
keyboard.sendPressEvent(value.data.character);
case 'mouseDown':
mouse.sendDownEvent(0, value.data.button, value.data.x, value.data.y);
case 'mouseUp':
mouse.sendUpEvent(0, value.data.button, value.data.x, value.data.y);
case 'mouseMove':
mouse.sendMoveEvent(0, value.data.x, value.data.y, value.data.mx, value.data.my);
case 'mouseWheel':
mouse.sendWheelEvent(0, value.data.delta);
}
}
public static function safeZone(): Float {
return 1.0;
}
public static function login(): Void {}
public static function automaticSafeZone(): Bool {
return true;
}
public static function setSafeZone(value: Float): Void {}
public static function unlockAchievement(id: Int): Void {}
public static function waitingForLogin(): Bool {
return false;
}
public static function disallowUserChange(): Void {}
public static function allowUserChange(): Void {}
}

View File

@ -0,0 +1,119 @@
package kha;
class Window {
static var instance: Window;
@:allow(kha.SystemImpl)
function new() {
instance = this;
}
public static function create(win: WindowOptions = null, frame: FramebufferOptions = null): Window {
return null;
}
public static function destroy(window: Window): Void {}
public static function get(index: Int): Window {
if (index == 0) {
return instance;
}
else {
return null;
}
}
public static var all(get, never): Array<Window>;
static function get_all(): Array<Window> {
return [instance];
}
public function resize(width: Int, height: Int): Void {}
public function move(x: Int, y: Int): Void {}
public function changeWindowFeatures(features: Int): Void {}
public function changeFramebuffer(frame: FramebufferOptions): Void {}
public var x(get, set): Int;
function get_x(): Int {
return 0;
}
function set_x(value: Int): Int {
return 0;
}
public var y(get, set): Int;
function get_y(): Int {
return 0;
}
function set_y(value: Int): Int {
return 0;
}
public var width(get, set): Int;
function get_width(): Int {
return SystemImpl.width;
}
function set_width(value: Int): Int {
return SystemImpl.width;
}
public var height(get, set): Int;
function get_height(): Int {
return SystemImpl.height;
}
function set_height(value: Int): Int {
return SystemImpl.height;
}
public var mode(get, set): WindowMode;
function get_mode(): WindowMode {
return Windowed;
}
function set_mode(value: WindowMode): WindowMode {
return Windowed;
}
public var visible(get, set): Bool;
function get_visible(): Bool {
return true;
}
function set_visible(value: Bool): Bool {
return true;
}
public var title(get, set): String;
function get_title(): String {
return "Kha";
}
function set_title(value: String): String {
return "Kha";
}
public function notifyOnResize(callback: Int->Int->Void): Void {}
public function notifyOnPpiChange(callback: Int->Void): Void {}
public var vSynced(get, never): Bool;
function get_vSynced(): Bool {
return true;
}
}

View File

@ -0,0 +1,16 @@
package kha;
class Worker {
public static function postMessage(m: Dynamic): Void {
try {
js.Syntax.code("self.postMessage(m)");
}
catch (e:Dynamic) {
trace(e);
}
}
public static function handleMessages(messageHandler: Dynamic->Void) {
untyped js.Syntax.code("self.onmessage = messageHandler");
}
}

View File

@ -0,0 +1,187 @@
package kha.arrays;
import js.lib.DataView;
import kha.FastFloat;
@:forward
abstract ByteArray(DataView) to DataView {
static final LITTLE_ENDIAN: Bool = js.Syntax.code("new Uint8Array(new Uint32Array([0x12345678]).buffer)[0] === 0x78");
public var buffer(get, never): ByteBuffer;
inline function get_buffer(): ByteBuffer {
return cast this.buffer;
}
public function new(buffer: ByteBuffer, ?byteOffset: Int, ?byteLength: Int) {
this = new DataView(buffer, byteOffset, byteLength);
}
static public function make(byteLength: Int): ByteArray {
return new ByteArray(ByteBuffer.create(byteLength));
}
public inline function getInt8(byteOffset: Int): Int {
return this.getInt8(byteOffset);
}
public inline function getUint8(byteOffset: Int): Int {
return this.getUint8(byteOffset);
}
public inline function getInt16(byteOffset: Int): Int {
return this.getInt16(byteOffset, LITTLE_ENDIAN);
}
public inline function getUint16(byteOffset: Int): Int {
return this.getUint16(byteOffset, LITTLE_ENDIAN);
}
public inline function getInt32(byteOffset: Int): Int {
return this.getInt32(byteOffset, LITTLE_ENDIAN);
}
public inline function getUint32(byteOffset: Int): Int {
return this.getUint32(byteOffset, LITTLE_ENDIAN);
}
public inline function getFloat32(byteOffset: Int): FastFloat {
return this.getFloat32(byteOffset, LITTLE_ENDIAN);
}
public inline function getFloat64(byteOffset: Int): Float {
return this.getFloat64(byteOffset, LITTLE_ENDIAN);
}
public inline function setInt8(byteOffset: Int, value: Int): Void {
this.setInt8(byteOffset, value);
}
public inline function setUint8(byteOffset: Int, value: Int): Void {
this.setUint8(byteOffset, value);
}
public inline function setInt16(byteOffset: Int, value: Int): Void {
this.setInt16(byteOffset, value, LITTLE_ENDIAN);
}
public inline function setUint16(byteOffset: Int, value: Int): Void {
this.setUint16(byteOffset, value, LITTLE_ENDIAN);
}
public inline function setInt32(byteOffset: Int, value: Int): Void {
this.setInt32(byteOffset, value, LITTLE_ENDIAN);
}
public inline function setUint32(byteOffset: Int, value: Int): Void {
this.setUint32(byteOffset, value, LITTLE_ENDIAN);
}
public inline function setFloat32(byteOffset: Int, value: FastFloat): Void {
this.setFloat32(byteOffset, value, true);
}
public inline function setFloat64(byteOffset: Int, value: Float): Void {
this.setFloat64(byteOffset, value, LITTLE_ENDIAN);
}
public inline function getInt16LE(byteOffset: Int): Int {
return this.getInt16(byteOffset, true);
}
public inline function getUint16LE(byteOffset: Int): Int {
return this.getUint16(byteOffset, true);
}
public inline function getInt32LE(byteOffset: Int): Int {
return this.getInt32(byteOffset, true);
}
public inline function getUint32LE(byteOffset: Int): Int {
return this.getUint32(byteOffset, true);
}
public inline function getFloat32LE(byteOffset: Int): FastFloat {
return this.getFloat32(byteOffset, true);
}
public inline function getFloat64LE(byteOffset: Int): Float {
return this.getFloat64(byteOffset, true);
}
public inline function setInt16LE(byteOffset: Int, value: Int): Void {
this.setInt16(byteOffset, value, true);
}
public inline function setUint16LE(byteOffset: Int, value: Int): Void {
this.setUint16(byteOffset, value, true);
}
public inline function setInt32LE(byteOffset: Int, value: Int): Void {
this.setInt32(byteOffset, value, true);
}
public inline function setUint32LE(byteOffset: Int, value: Int): Void {
this.setUint32(byteOffset, value, true);
}
public inline function setFloat32LE(byteOffset: Int, value: FastFloat): Void {
this.setFloat32(byteOffset, value, true);
}
public inline function setFloat64LE(byteOffset: Int, value: Float): Void {
this.setFloat64(byteOffset, value, true);
}
public inline function getInt16BE(byteOffset: Int): Int {
return this.getInt16(byteOffset);
}
public inline function getUint16BE(byteOffset: Int): Int {
return this.getUint16(byteOffset);
}
public inline function getInt32BE(byteOffset: Int): Int {
return this.getInt32(byteOffset);
}
public inline function getUint32BE(byteOffset: Int): Int {
return this.getUint32(byteOffset);
}
public inline function getFloat32BE(byteOffset: Int): FastFloat {
return this.getFloat32(byteOffset);
}
public inline function getFloat64BE(byteOffset: Int): Float {
return this.getFloat64(byteOffset);
}
public inline function setInt16BE(byteOffset: Int, value: Int): Void {
this.setInt16(byteOffset, value);
}
public inline function setUint16BE(byteOffset: Int, value: Int): Void {
this.setUint16(byteOffset, value);
}
public inline function setInt32BE(byteOffset: Int, value: Int): Void {
this.setInt32(byteOffset, value);
}
public inline function setUint32BE(byteOffset: Int, value: Int): Void {
this.setUint32(byteOffset, value);
}
public inline function setFloat32BE(byteOffset: Int, value: FastFloat): Void {
this.setFloat32(byteOffset, value);
}
public inline function setFloat64BE(byteOffset: Int, value: Float): Void {
this.setFloat64(byteOffset, value);
}
public inline function subarray(start: Int, ?end: Int): ByteArray {
return new ByteArray(buffer, start, end != null ? end - start : null);
}
}

View File

@ -0,0 +1,14 @@
package kha.arrays;
import js.lib.ArrayBuffer;
@:forward
abstract ByteBuffer(ArrayBuffer) from ArrayBuffer to ArrayBuffer {
public static function create(length: Int): ByteBuffer {
return new ByteBuffer(length);
}
function new(length: Int) {
this = new ArrayBuffer(length);
}
}

View File

@ -0,0 +1,13 @@
package kha.audio1;
class Audio {
public static function play(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
Worker.postMessage({command: 'playSound', id: cast(sound, kha.html5worker.Sound)._id, loop: loop});
return null;
}
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
Worker.postMessage({command: 'streamSound', id: cast(sound, kha.html5worker.Sound)._id, loop: loop});
return null;
}
}

View File

@ -0,0 +1,13 @@
package kha.audio2;
import kha.Sound;
class Audio {
public static var disableGcInteractions = false;
public static var samplesPerSecond: Int;
public static var audioCallback: Int->Buffer->Void;
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
return null;
}
}

View File

@ -0,0 +1,44 @@
package kha.graphics4;
import haxe.io.Bytes;
class CubeMap implements Canvas implements Resource {
public static function createRenderTarget(size: Int, format: TextureFormat, depthStencil: DepthStencilFormat = NoDepthAndStencil): CubeMap {
return null;
}
public function unload(): Void {}
public function lock(level: Int = 0): Bytes {
return null;
}
public function unlock(): Void {}
public var width(get, never): Int;
public var height(get, never): Int;
function get_width(): Int {
return 512;
}
function get_height(): Int {
return 512;
}
public var g1(get, never): kha.graphics1.Graphics;
public var g2(get, never): kha.graphics2.Graphics;
public var g4(get, never): kha.graphics4.Graphics;
function get_g1(): kha.graphics1.Graphics {
return null;
}
function get_g2(): kha.graphics2.Graphics {
return null;
}
function get_g4(): kha.graphics4.Graphics {
return null;
}
}

View File

@ -0,0 +1,27 @@
package kha.graphics4;
class FragmentShader {
public var sources: Array<String>;
public var shader: Dynamic;
public var files: Array<String>;
public function new(sources: Array<Blob>, files: Array<String>) {
this.sources = [];
for (source in sources) {
this.sources.push(source.toString());
}
this.shader = null;
this.files = files;
}
public static function fromSource(source: String): FragmentShader {
var shader = new FragmentShader([], ["runtime-string"]);
shader.sources.push(source);
return shader;
}
public function delete(): Void {
shader = null;
sources = null;
}
}

View File

@ -0,0 +1,51 @@
package kha.graphics4;
import kha.arrays.Uint32Array;
import kha.graphics4.Usage;
class IndexBuffer {
static var lastId: Int = -1;
public var _id: Int;
public var _data: Uint32Array;
var mySize: Int;
var usage: Usage;
var lockStart: Int = 0;
var lockEnd: Int = 0;
public function new(indexCount: Int, usage: Usage, canRead: Bool = false) {
this.usage = usage;
mySize = indexCount;
_data = new Uint32Array(indexCount);
_id = ++lastId;
Worker.postMessage({
command: 'createIndexBuffer',
id: _id,
size: indexCount,
usage: usage
});
}
public function delete(): Void {
_data = null;
}
public function lock(?start: Int, ?count: Int): Uint32Array {
lockStart = start != null ? start : 0;
lockEnd = count != null ? start + count : mySize;
return _data.subarray(lockStart, lockEnd);
}
public function unlock(?count: Int): Void {
if (count != null)
lockEnd = lockStart + count;
Worker.postMessage({command: 'updateIndexBuffer', id: _id, data: _data.subarray(lockStart, lockEnd).buffer});
}
public function set(): Void {}
public function count(): Int {
return mySize;
}
}

View File

@ -0,0 +1,117 @@
package kha.graphics4;
import kha.graphics4.FragmentShader;
import kha.graphics4.VertexData;
import kha.graphics4.VertexShader;
import kha.graphics4.VertexStructure;
class PipelineState extends PipelineStateBase {
static var lastId: Int = -1;
public var _id: Int;
var textures: Array<String>;
var textureValues: Array<Dynamic>;
public function new() {
super();
_id = ++lastId;
textures = new Array<String>();
textureValues = new Array<Dynamic>();
}
public function delete(): Void {}
public function compile(): Void {
var index = 0;
for (structure in inputLayout) {
for (element in structure.elements) {
if (element.data == VertexData.Float4x4) {
index += 4;
}
else {
++index;
}
}
}
var layout = new Array<Dynamic>();
for (input in inputLayout) {
var elements = new Array<Dynamic>();
for (element in input.elements) {
elements.push({
name: element.name,
data: element.data
});
}
layout.push({
elements: elements
});
}
var stencilValue = -1;
switch (stencilReferenceValue) {
case Static(value):
stencilValue = value;
case Dynamic:
stencilValue = -1;
}
var state = {
cullMode: cullMode,
depthWrite: depthWrite,
depthMode: depthMode,
stencilFrontMode: stencilFrontMode,
stencilFrontBothPass: stencilFrontBothPass,
stencilFrontDepthFail: stencilFrontDepthFail,
stencilFrontFail: stencilFrontFail,
stencilBackMode: stencilBackMode,
stencilBackBothPass: stencilBackBothPass,
stencilBackDepthFail: stencilBackDepthFail,
stencilBackFail: stencilBackFail,
stencilReferenceValue: stencilValue,
stencilReadMask: stencilReadMask,
stencilWriteMask: stencilWriteMask,
blendSource: blendSource,
blendDestination: blendDestination,
alphaBlendSource: alphaBlendSource,
alphaBlendDestination: alphaBlendDestination,
colorWriteMaskRed: colorWriteMaskRed,
colorWriteMaskGreen: colorWriteMaskGreen,
colorWriteMaskBlue: colorWriteMaskBlue,
colorWriteMaskAlpha: colorWriteMaskAlpha,
conservativeRasterization: conservativeRasterization
};
Worker.postMessage({
command: 'compilePipeline',
id: _id,
frag: fragmentShader.files[0],
vert: vertexShader.files[0],
layout: layout,
state: state
});
}
public function getConstantLocation(name: String): kha.graphics4.ConstantLocation {
var loc = new kha.html5worker.ConstantLocation();
Worker.postMessage({
command: 'createConstantLocation',
id: loc._id,
name: name,
pipeline: _id
});
return loc;
}
public function getTextureUnit(name: String): kha.graphics4.TextureUnit {
var unit = new kha.html5worker.TextureUnit();
Worker.postMessage({
command: 'createTextureUnit',
id: unit._id,
name: name,
pipeline: _id
});
return unit;
}
}

View File

@ -0,0 +1,115 @@
package kha.graphics4;
import kha.arrays.Float32Array;
import kha.graphics4.Usage;
import kha.graphics4.VertexStructure;
import kha.graphics4.VertexData;
class VertexBuffer {
static var lastId: Int = -1;
public var _id: Int;
public var _data: Float32Array;
var mySize: Int;
var myStride: Int;
var sizes: Array<Int>;
var offsets: Array<Int>;
var usage: Usage;
var instanceDataStepRate: Int;
var lockStart: Int = 0;
var lockCount: Int = 0;
public function new(vertexCount: Int, structure: VertexStructure, usage: Usage, instanceDataStepRate: Int = 0, canRead: Bool = false) {
this.usage = usage;
this.instanceDataStepRate = instanceDataStepRate;
mySize = vertexCount;
myStride = 0;
for (element in structure.elements) {
myStride += VertexStructure.dataByteSize(element.data);
}
_data = new Float32Array(Std.int(vertexCount * myStride / 4));
sizes = new Array<Int>();
offsets = new Array<Int>();
sizes[structure.elements.length - 1] = 0;
offsets[structure.elements.length - 1] = 0;
var offset = 0;
var index = 0;
for (element in structure.elements) {
var size = 0;
size += Std.int(VertexStructure.dataByteSize(element.data) / 4);
sizes[index] = size;
offsets[index] = offset;
offset += VertexStructure.dataByteSize(element.data);
++index;
}
_id = ++lastId;
var elements = new Array<Dynamic>();
for (element in structure.elements) {
elements.push({
name: element.name,
data: element.data
});
}
Worker.postMessage({
command: 'createVertexBuffer',
id: _id,
size: vertexCount,
structure: {elements: elements},
usage: usage
});
}
public function delete(): Void {
_data = null;
}
public function lock(?start: Int, ?count: Int): Float32Array {
lockStart = start != null ? start : 0;
lockCount = count != null ? count : mySize;
return _data.subarray(Std.int(lockStart * stride() / 4), Std.int((lockStart + lockCount) * stride() / 4));
}
public function unlock(?count: Int): Void {
if (count != null)
lockCount = count;
Worker.postMessage({
command: 'updateVertexBuffer',
id: _id,
data: _data.subarray(Std.int(lockStart * stride() / 4), Std.int((lockStart + lockCount) * stride() / 4)).buffer,
start: lockStart,
count: lockCount
});
}
public function stride(): Int {
return myStride;
}
public function count(): Int {
return mySize;
}
public function set(offset: Int): Int {
var attributesOffset = 0;
for (i in 0...sizes.length) {
if (sizes[i] > 4) {
var size = sizes[i];
var addonOffset = 0;
while (size > 0) {
size -= 4;
addonOffset += 4 * 4;
++attributesOffset;
}
}
else {
++attributesOffset;
}
}
return attributesOffset;
}
}

View File

@ -0,0 +1,27 @@
package kha.graphics4;
class VertexShader {
public var sources: Array<String>;
public var shader: Dynamic;
public var files: Array<String>;
public function new(sources: Array<Blob>, files: Array<String>) {
this.sources = [];
for (source in sources) {
this.sources.push(source.toString());
}
this.shader = null;
this.files = files;
}
public static function fromSource(source: String): VertexShader {
var shader = new VertexShader([], ["runtime-string"]);
shader.sources.push(source);
return shader;
}
public function delete(): Void {
shader = null;
sources = null;
}
}

View File

@ -0,0 +1,11 @@
package kha.html5worker;
class ConstantLocation implements kha.graphics4.ConstantLocation {
static var lastId: Int = -1;
public var _id: Int;
public function new() {
_id = ++lastId;
}
}

View File

@ -0,0 +1,345 @@
package kha.html5worker;
import kha.arrays.Float32Array;
import kha.Canvas;
import kha.graphics4.IndexBuffer;
import kha.graphics4.MipMapFilter;
import kha.graphics4.PipelineState;
import kha.graphics4.TextureAddressing;
import kha.graphics4.TextureFilter;
import kha.graphics4.Usage;
import kha.graphics4.VertexBuffer;
import kha.graphics4.VertexStructure;
import kha.math.FastMatrix3;
import kha.math.FastMatrix4;
import kha.math.FastVector2;
import kha.math.FastVector3;
import kha.math.FastVector4;
class Graphics implements kha.graphics4.Graphics {
var renderTarget: Image;
public function new(renderTarget: Canvas = null) {
if (Std.isOfType(renderTarget, Image)) {
this.renderTarget = cast renderTarget;
}
}
public function begin(additionalRenderTargets: Array<Canvas> = null): Void {
Worker.postMessage({command: 'begin', renderTarget: renderTarget == null ? -1 : renderTarget._rtid});
}
public function beginFace(face: Int): Void {}
public function beginEye(eye: Int): Void {}
public function end(): Void {
Worker.postMessage({command: 'end'});
}
public function flush(): Void {}
public function vsynced(): Bool {
return true;
}
public function refreshRate(): Int {
return 60;
}
public function clear(?color: Color, ?depth: Float, ?stencil: Int): Void {
Worker.postMessage({
command: 'clear',
color: color == null ? null : color.value,
hasDepth: depth != null,
depth: depth,
hasStencil: stencil != null,
stencil: stencil
});
}
public function viewport(x: Int, y: Int, width: Int, height: Int): Void {
Worker.postMessage({
command: 'viewport',
x: x,
y: y,
width: width,
height: height
});
}
public function createVertexBuffer(vertexCount: Int, structure: VertexStructure, usage: Usage, canRead: Bool = false): kha.graphics4.VertexBuffer {
return new VertexBuffer(vertexCount, structure, usage);
}
public function setVertexBuffer(vertexBuffer: kha.graphics4.VertexBuffer): Void {
Worker.postMessage({command: 'setVertexBuffer', id: vertexBuffer._id});
}
public function setVertexBuffers(vertexBuffers: Array<kha.graphics4.VertexBuffer>): Void {
var ids = new Array<Int>();
for (buffer in vertexBuffers) {
ids.push(buffer._id);
}
Worker.postMessage({command: 'setVertexBuffers', ids: ids});
}
public function createIndexBuffer(indexCount: Int, usage: Usage, canRead: Bool = false): kha.graphics4.IndexBuffer {
return new IndexBuffer(indexCount, usage);
}
public function setIndexBuffer(indexBuffer: kha.graphics4.IndexBuffer): Void {
Worker.postMessage({command: 'setIndexBuffer', id: indexBuffer._id});
}
public function setTexture(stage: kha.graphics4.TextureUnit, texture: kha.Image): Void {
Worker.postMessage({
command: 'setTexture',
stage: cast(stage, kha.html5worker.TextureUnit)._id,
texture: texture == null ? -1 : texture.id,
renderTarget: texture == null ? -1 : texture._rtid
});
}
public function setTextureDepth(stage: kha.graphics4.TextureUnit, texture: kha.Image): Void {}
public function setTextureArray(unit: kha.graphics4.TextureUnit, texture: kha.Image): Void {}
public function setVideoTexture(unit: kha.graphics4.TextureUnit, texture: kha.Video): Void {}
public function setImageTexture(unit: kha.graphics4.TextureUnit, texture: kha.Image): Void {}
public function setTextureParameters(texunit: kha.graphics4.TextureUnit, uAddressing: TextureAddressing, vAddressing: TextureAddressing,
minificationFilter: TextureFilter, magnificationFilter: TextureFilter, mipmapFilter: MipMapFilter): Void {
Worker.postMessage({
command: 'setTextureParameters',
id: cast(texunit, kha.html5worker.TextureUnit)._id,
uAddressing: uAddressing,
vAddressing: vAddressing,
minificationFilter: minificationFilter,
magnificationFilter: magnificationFilter,
mipmapFilter: mipmapFilter
});
}
public function setTexture3DParameters(texunit: kha.graphics4.TextureUnit, uAddressing: TextureAddressing, vAddressing: TextureAddressing,
wAddressing: TextureAddressing, minificationFilter: TextureFilter, magnificationFilter: TextureFilter, mipmapFilter: MipMapFilter): Void {}
public function setTextureCompareMode(texunit: kha.graphics4.TextureUnit, enabled: Bool): Void {}
public function setCubeMapCompareMode(texunit: kha.graphics4.TextureUnit, enabled: Bool): Void {}
public function setCubeMap(stage: kha.graphics4.TextureUnit, cubeMap: kha.graphics4.CubeMap): Void {}
public function setCubeMapDepth(stage: kha.graphics4.TextureUnit, cubeMap: kha.graphics4.CubeMap): Void {}
public function setPipeline(pipe: PipelineState): Void {
Worker.postMessage({command: 'setPipeline', id: pipe._id});
}
public function setStencilReferenceValue(value: Int): Void {}
public function setBool(location: kha.graphics4.ConstantLocation, value: Bool): Void {
Worker.postMessage({
command: 'setBool',
location: cast(location, kha.html5worker.ConstantLocation)._id,
value: value
});
}
public function setInt(location: kha.graphics4.ConstantLocation, value: Int): Void {
Worker.postMessage({
command: 'setInt',
location: cast(location, kha.html5worker.ConstantLocation)._id,
value: value
});
}
public function setInt2(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int): Void {
Worker.postMessage({
command: 'setInt2',
location: cast(location, kha.html5worker.ConstantLocation)._id,
_0: value1,
_1: value2
});
}
public function setInt3(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int, value3: Int): Void {
Worker.postMessage({
command: 'setInt3',
location: cast(location, kha.html5worker.ConstantLocation)._id,
_0: value1,
_1: value2,
_2: value3
});
}
public function setInt4(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int, value3: Int, value4: Int): Void {
Worker.postMessage({
command: 'setInt4',
location: cast(location, kha.html5worker.ConstantLocation)._id,
_0: value1,
_1: value2,
_2: value3,
_3: value4
});
}
public function setInts(location: kha.graphics4.ConstantLocation, values: kha.arrays.Int32Array): Void {
Worker.postMessage({
command: 'setInts',
location: cast(location, kha.html5worker.ConstantLocation)._id,
values: values
});
}
public function setFloat(location: kha.graphics4.ConstantLocation, value: FastFloat): Void {
Worker.postMessage({
command: 'setFloat',
location: cast(location, kha.html5worker.ConstantLocation)._id,
value: value
});
}
public function setFloat2(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat): Void {
Worker.postMessage({
command: 'setFloat2',
location: cast(location, kha.html5worker.ConstantLocation)._id,
_0: value1,
_1: value2
});
}
public function setFloat3(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat, value3: FastFloat): Void {
Worker.postMessage({
command: 'setFloat3',
location: cast(location, kha.html5worker.ConstantLocation)._id,
_0: value1,
_1: value2,
_2: value3
});
}
public function setFloat4(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat, value3: FastFloat, value4: FastFloat): Void {
Worker.postMessage({
command: 'setFloat4',
location: cast(location, kha.html5worker.ConstantLocation)._id,
_0: value1,
_1: value2,
_2: value3,
_3: value4
});
}
public function setFloats(location: kha.graphics4.ConstantLocation, values: Float32Array): Void {
Worker.postMessage({
command: 'setFloats',
location: cast(location, kha.html5worker.ConstantLocation)._id,
values: values
});
}
public function setVector2(location: kha.graphics4.ConstantLocation, value: FastVector2): Void {
Worker.postMessage({
command: 'setVector2',
location: cast(location, kha.html5worker.ConstantLocation)._id,
x: value.x,
y: value.y
});
}
public function setVector3(location: kha.graphics4.ConstantLocation, value: FastVector3): Void {
Worker.postMessage({
command: 'setVector3',
location: cast(location, kha.html5worker.ConstantLocation)._id,
x: value.x,
y: value.y,
z: value.z
});
}
public function setVector4(location: kha.graphics4.ConstantLocation, value: FastVector4): Void {
Worker.postMessage({
command: 'setVector4',
location: cast(location, kha.html5worker.ConstantLocation)._id,
x: value.x,
y: value.y,
z: value.z,
w: value.w
});
}
public inline function setMatrix(location: kha.graphics4.ConstantLocation, matrix: FastMatrix4): Void {
Worker.postMessage({
command: 'setMatrix4',
location: cast(location, kha.html5worker.ConstantLocation)._id,
_00: matrix._00,
_01: matrix._01,
_02: matrix._02,
_03: matrix._03,
_10: matrix._10,
_11: matrix._11,
_12: matrix._12,
_13: matrix._13,
_20: matrix._20,
_21: matrix._21,
_22: matrix._22,
_23: matrix._23,
_30: matrix._30,
_31: matrix._31,
_32: matrix._32,
_33: matrix._33
});
}
public inline function setMatrix3(location: kha.graphics4.ConstantLocation, matrix: FastMatrix3): Void {
Worker.postMessage({
command: 'setMatrix3',
location: cast(location, kha.html5worker.ConstantLocation)._id,
_00: matrix._00,
_01: matrix._01,
_02: matrix._02,
_10: matrix._10,
_11: matrix._11,
_12: matrix._12,
_20: matrix._20,
_21: matrix._21,
_22: matrix._22
});
}
public function drawIndexedVertices(start: Int = 0, count: Int = -1): Void {
Worker.postMessage({command: 'drawIndexedVertices', start: start, count: count});
}
public function scissor(x: Int, y: Int, width: Int, height: Int): Void {
Worker.postMessage({
command: 'scissor',
x: x,
y: y,
width: width,
height: height
});
}
public function disableScissor(): Void {
Worker.postMessage({command: 'disableScissor'});
}
public function drawIndexedVerticesInstanced(instanceCount: Int, start: Int = 0, count: Int = -1) {
Worker.postMessage({
command: 'drawIndexedVerticesInstanced',
instanceCount: instanceCount,
start: start,
count: count
});
}
public function instancedRenderingAvailable(): Bool {
return true;
}
public function maxBoundTextures(): Int {
return 16;
}
}

View File

@ -0,0 +1,25 @@
package kha.html5worker;
import haxe.io.Bytes;
import haxe.ds.Vector;
class Sound extends kha.Sound {
public var _id: Int;
public var _callback: Void->Void;
public function new(id: Int) {
super();
this._id = id;
}
override public function uncompress(done: Void->Void): Void {
compressedData = null;
Worker.postMessage({command: 'uncompressSound', id: _id});
_callback = done;
}
override public function unload() {
compressedData = null;
uncompressedData = null;
}
}

View File

@ -0,0 +1,11 @@
package kha.html5worker;
class TextureUnit implements kha.graphics4.TextureUnit {
static var lastId: Int = -1;
public var _id: Int;
public function new() {
_id = ++lastId;
}
}

View File

@ -0,0 +1,3 @@
package kha;
typedef Blob = kha.internal.BytesBlob;

View File

@ -0,0 +1,234 @@
package kha;
import haxe.io.Bytes;
import js.Browser;
import js.lib.Uint8Array;
import js.html.VideoElement;
import js.html.webgl.GL;
import kha.graphics4.TextureFormat;
import kha.js.CanvasGraphics;
class CanvasImage extends Image {
public var image: Dynamic;
public var video: VideoElement;
static var context: Dynamic;
var data: Dynamic;
var myWidth: Int;
var myHeight: Int;
var myFormat: TextureFormat;
var renderTarget: Bool;
public var frameBuffer: Dynamic;
var graphics1: kha.graphics1.Graphics;
var g2canvas: CanvasGraphics = null;
public static function init() {
var canvas: Dynamic = Browser.document.createElement("canvas");
if (canvas != null) {
context = canvas.getContext("2d");
canvas.width = 2048;
canvas.height = 2048;
context.globalCompositeOperation = "copy";
}
}
public function new(width: Int, height: Int, format: TextureFormat, renderTarget: Bool) {
myWidth = width;
myHeight = height;
myFormat = format;
this.renderTarget = renderTarget;
image = null;
video = null;
if (renderTarget)
createTexture();
}
override function get_g1(): kha.graphics1.Graphics {
if (graphics1 == null) {
graphics1 = new kha.graphics2.Graphics1(this);
}
return graphics1;
}
override function get_g2(): kha.graphics2.Graphics {
if (g2canvas == null) {
var canvas: Dynamic = Browser.document.createElement("canvas");
image = canvas;
var context = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
g2canvas = new CanvasGraphics(context);
}
return g2canvas;
}
override function get_g4(): kha.graphics4.Graphics {
return null;
}
override function get_width(): Int {
return myWidth;
}
override function get_height(): Int {
return myHeight;
}
override function get_format(): TextureFormat {
return myFormat;
}
override function get_realWidth(): Int {
return myWidth;
}
override function get_realHeight(): Int {
return myHeight;
}
override function get_stride(): Int {
return myFormat == TextureFormat.RGBA32 ? 4 * width : width;
}
override public function isOpaque(x: Int, y: Int): Bool {
if (data == null) {
if (context == null)
return true;
else
createImageData();
}
return (data.data[y * Std.int(image.width) * 4 + x * 4 + 3] != 0);
}
override public function at(x: Int, y: Int): Color {
if (data == null) {
if (context == null)
return Color.Black;
else
createImageData();
}
var r = data.data[y * Std.int(image.width) * 4 + x * 4];
var g = data.data[y * Std.int(image.width) * 4 + x * 4 + 1];
var b = data.data[y * Std.int(image.width) * 4 + x * 4 + 2];
var a = data.data[y * Std.int(image.width) * 4 + x * 4 + 3];
return Color.fromValue((a << 24) | (r << 16) | (g << 8) | b);
}
function createImageData() {
context.strokeStyle = "rgba(0,0,0,0)";
context.fillStyle = "rgba(0,0,0,0)";
context.fillRect(0, 0, image.width, image.height);
context.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
data = context.getImageData(0, 0, image.width, image.height);
}
var texture: Dynamic;
static function upperPowerOfTwo(v: Int): Int {
v--;
v |= v >>> 1;
v |= v >>> 2;
v |= v >>> 4;
v |= v >>> 8;
v |= v >>> 16;
v++;
return v;
}
public function createTexture() {
if (SystemImpl.gl == null)
return;
texture = SystemImpl.gl.createTexture();
// texture.image = image;
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
// Sys.gl.pixelStorei(Sys.gl.UNPACK_FLIP_Y_WEBGL, true);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
if (renderTarget) {
frameBuffer = SystemImpl.gl.createFramebuffer();
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, texture, 0);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
else if (video != null)
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, video);
else
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, image);
// Sys.gl.generateMipmap(Sys.gl.TEXTURE_2D);
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
}
public function set(stage: Int): Void {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
if (video != null)
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, video);
}
public var bytes: Bytes;
override public function lock(level: Int = 0): Bytes {
bytes = Bytes.alloc(myFormat == TextureFormat.RGBA32 ? 4 * width * height : width * height);
return bytes;
}
override public function unlock(): Void {
data = null;
if (SystemImpl.gl != null) {
texture = SystemImpl.gl.createTexture();
// texture.image = image;
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
// Sys.gl.pixelStorei(Sys.gl.UNPACK_FLIP_Y_WEBGL, true);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.LUMINANCE, width, height, 0, GL.LUMINANCE, GL.UNSIGNED_BYTE, new Uint8Array(bytes.getData()));
if (SystemImpl.ie && SystemImpl.gl.getError() == 1282) { // no LUMINANCE support in IE11
var rgbaBytes = Bytes.alloc(width * height * 4);
for (y in 0...height)
for (x in 0...width) {
var value = bytes.get(y * width + x);
rgbaBytes.set(y * width * 4 + x * 4 + 0, value);
rgbaBytes.set(y * width * 4 + x * 4 + 1, value);
rgbaBytes.set(y * width * 4 + x * 4 + 2, value);
rgbaBytes.set(y * width * 4 + x * 4 + 3, 255);
}
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, new Uint8Array(rgbaBytes.getData()));
}
// Sys.gl.generateMipmap(Sys.gl.TEXTURE_2D);
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
bytes = null;
}
}
override public function getPixels(): Bytes {
@:privateAccess var context: js.html.CanvasRenderingContext2D = g2canvas.canvas;
var imageData: js.html.ImageData = context.getImageData(0, 0, width, height);
var bytes = Bytes.alloc(imageData.data.length);
for (i in 0...imageData.data.length) {
bytes.set(i, imageData.data[i]);
}
return bytes;
}
override public function unload(): Void {
image = null;
video = null;
data = null;
}
}

View File

@ -0,0 +1,86 @@
package kha;
import js.Browser;
class Display {
static var instance: Display = new Display();
function new() {}
public static function init(): Void {}
public static var primary(get, never): Display;
static function get_primary(): Display {
return instance;
}
public static var all(get, never): Array<Display>;
static function get_all(): Array<Display> {
return [primary];
}
public var available(get, never): Bool;
function get_available(): Bool {
return true;
}
public var name(get, never): String;
function get_name(): String {
return "Display";
}
public var x(get, never): Int;
function get_x(): Int {
return js.Browser.window.screen.left;
}
public var y(get, never): Int;
function get_y(): Int {
return js.Browser.window.screen.top;
}
public var width(get, never): Int;
function get_width(): Int {
return js.Browser.window.screen.width;
}
public var height(get, never): Int;
function get_height(): Int {
return js.Browser.window.screen.height;
}
public var frequency(get, never): Int;
function get_frequency(): Int {
return SystemImpl.estimatedRefreshRate;
}
public var pixelsPerInch(get, never): Int;
function get_pixelsPerInch(): Int {
var dpiElement = Browser.document.createElement("div");
dpiElement.style.position = "absolute";
dpiElement.style.width = "1in";
dpiElement.style.height = "1in";
dpiElement.style.left = "-100%";
dpiElement.style.top = "-100%";
Browser.document.body.appendChild(dpiElement);
var dpi: Int = dpiElement.offsetHeight;
dpiElement.remove();
return dpi;
}
public var modes(get, never): Array<DisplayMode>;
function get_modes(): Array<DisplayMode> {
return [];
}
}

View File

@ -0,0 +1,24 @@
package kha;
import js.Browser;
class EnvironmentVariables {
public static function get(name: String): String {
try {
var query = Browser.location.href.substr(Browser.location.href.indexOf("?") + 1);
var parts = query.split("&");
for (part in parts) {
var subparts = part.split("=");
if (subparts[0] == name) {
return subparts[1];
}
}
return null;
}
catch (error:Dynamic) {
return null;
}
}
}

View File

@ -0,0 +1,3 @@
package kha;
typedef Font = kha.Kravur;

View File

@ -0,0 +1,221 @@
package kha;
import haxe.io.Bytes;
import js.html.ImageElement;
import js.html.CanvasElement;
import js.html.webgl.GL;
import kha.graphics4.TextureFormat;
import kha.graphics4.DepthStencilFormat;
import kha.graphics4.Usage;
class Image implements Canvas implements Resource {
public static function create(width: Int, height: Int, format: TextureFormat = null, usage: Usage = null, readable: Bool = false): Image {
if (format == null)
format = TextureFormat.RGBA32;
if (usage == null)
usage = Usage.StaticUsage;
if (SystemImpl.gl == null)
return new CanvasImage(width, height, format, false);
else
return new WebGLImage(width, height, format, false, DepthStencilFormat.NoDepthAndStencil, 1, readable);
}
public static function create3D(width: Int, height: Int, depth: Int, format: TextureFormat = null, usage: Usage = null, readable: Bool = false): Image {
return null;
}
public static function createRenderTarget(width: Int, height: Int, format: TextureFormat = null,
depthStencil: DepthStencilFormat = DepthStencilFormat.NoDepthAndStencil, antiAliasingSamples: Int = 1): Image {
if (format == null)
format = TextureFormat.RGBA32;
if (SystemImpl.gl == null)
return new CanvasImage(width, height, format, true);
else
return new WebGLImage(width, height, format, true, depthStencil, antiAliasingSamples, false);
}
public static function fromCanvas(canvas: CanvasElement): Image {
if (SystemImpl.gl == null) {
var img = new CanvasImage(canvas.width, canvas.height, TextureFormat.RGBA32, false);
img.image = canvas;
img.createTexture();
return img;
}
else {
var img = new WebGLImage(canvas.width, canvas.height, TextureFormat.RGBA32, false, DepthStencilFormat.NoDepthAndStencil, 1, false);
img.image = canvas;
img.createTexture();
return img;
}
}
public static function fromImage(image: ImageElement, readable: Bool): Image {
if (SystemImpl.gl == null) {
var img = new CanvasImage(image.width, image.height, TextureFormat.RGBA32, false);
img.image = image;
img.createTexture();
return img;
}
else {
var img = new WebGLImage(image.width, image.height, TextureFormat.RGBA32, false, DepthStencilFormat.NoDepthAndStencil, 1, readable);
img.image = image;
img.createTexture();
return img;
}
}
public static function fromBytes(bytes: Bytes, width: Int, height: Int, format: TextureFormat = null, usage: Usage = null, readable: Bool = false): Image {
if (format == null)
format = TextureFormat.RGBA32;
if (usage == null)
usage = Usage.StaticUsage;
if (SystemImpl.gl != null) {
var img = new WebGLImage(width, height, format, false, DepthStencilFormat.NoDepthAndStencil, 1, readable);
img.image = img.bytesToArray(bytes);
img.createTexture();
return img;
}
var img = new CanvasImage(width, height, format, false);
var g2: kha.js.CanvasGraphics = cast img.g2;
@:privateAccess var canvas = g2.canvas;
var imageData = new js.html.ImageData(new js.lib.Uint8ClampedArray(bytes.getData()), width, height);
canvas.putImageData(imageData, 0, 0);
return img;
}
public static function fromBytes3D(bytes: Bytes, width: Int, height: Int, depth: Int, format: TextureFormat = null, usage: Usage = null,
readable: Bool = false): Image {
return null;
}
public static function fromEncodedBytes(bytes: Bytes, fileExtention: String, doneCallback: Image->Void, errorCallback: String->Void,
readable: Bool = false): Void {
var dataUrl = "data:image;base64," + haxe.crypto.Base64.encode(bytes);
var imageElement = cast(js.Browser.document.createElement("img"), ImageElement);
imageElement.onload = function() doneCallback(fromImage(imageElement, readable));
imageElement.onerror = function() errorCallback("Image was not created");
imageElement.src = dataUrl;
}
public static function fromVideo(video: kha.Video): Image {
final jsvideo: kha.js.Video = cast video;
if (SystemImpl.gl == null) {
var img = new CanvasImage(jsvideo.element.videoWidth, jsvideo.element.videoHeight, TextureFormat.RGBA32, false);
img.video = jsvideo.element;
img.createTexture();
return img;
}
else {
var img = new WebGLImage(jsvideo.element.videoWidth, jsvideo.element.videoHeight, TextureFormat.RGBA32, false,
DepthStencilFormat.NoDepthAndStencil, 1, false);
img.video = jsvideo.element;
img.createTexture();
return img;
}
}
public static var maxSize(get, never): Int;
static function get_maxSize(): Int {
return SystemImpl.gl == null ? 1024 * 8 : SystemImpl.gl.getParameter(GL.MAX_TEXTURE_SIZE);
}
public static var nonPow2Supported(get, never): Bool;
static function get_nonPow2Supported(): Bool {
return SystemImpl.gl != null;
}
public static function renderTargetsInvertedY(): Bool {
return true;
}
public function isOpaque(x: Int, y: Int): Bool {
return false;
}
public function at(x: Int, y: Int): Color {
return Color.Black;
}
public function unload(): Void {}
public function lock(level: Int = 0): Bytes {
return null;
}
public function unlock(): Void {}
public function getPixels(): Bytes {
return null;
}
public function generateMipmaps(levels: Int): Void {}
public function setMipmaps(mipmaps: Array<Image>): Void {}
public function setDepthStencilFrom(image: Image): Void {}
public function clear(x: Int, y: Int, z: Int, width: Int, height: Int, depth: Int, color: Color): Void {}
public var width(get, never): Int;
function get_width(): Int {
return 0;
}
public var height(get, never): Int;
function get_height(): Int {
return 0;
}
public var depth(get, never): Int;
function get_depth(): Int {
return 1;
}
public var format(get, never): TextureFormat;
function get_format(): TextureFormat {
return TextureFormat.RGBA32;
}
public var realWidth(get, never): Int;
function get_realWidth(): Int {
return 0;
}
public var realHeight(get, never): Int;
function get_realHeight(): Int {
return 0;
}
public var stride(get, never): Int;
function get_stride(): Int {
return 0;
}
public var g1(get, never): kha.graphics1.Graphics;
function get_g1(): kha.graphics1.Graphics {
return null;
}
public var g2(get, never): kha.graphics2.Graphics;
function get_g2(): kha.graphics2.Graphics {
return null;
}
public var g4(get, never): kha.graphics4.Graphics;
function get_g4(): kha.graphics4.Graphics {
return null;
}
}

View File

@ -0,0 +1,236 @@
package kha;
import js.html.FileReader;
import js.Syntax;
import js.Browser;
import js.html.ImageElement;
import js.html.XMLHttpRequest;
import haxe.io.Bytes;
import kha.Blob;
import kha.js.WebAudioSound;
import kha.js.MobileWebAudioSound;
import kha.graphics4.TextureFormat;
import kha.graphics4.Usage;
using StringTools;
class LoaderImpl {
@:allow(kha.SystemImpl)
static var dropFiles = new Map<String, js.html.File>();
public static function getImageFormats(): Array<String> {
return ["png", "jpg", "hdr"];
}
public static function loadImageFromDescription(desc: Dynamic, done: kha.Image->Void, failed: AssetError->Void) {
var readable = Reflect.hasField(desc, "readable") ? desc.readable : false;
if (StringTools.endsWith(desc.files[0], ".hdr")) {
loadBlobFromDescription(desc, function(blob) {
var hdrImage = kha.internal.HdrFormat.parse(blob.toBytes());
done(Image.fromBytes(hdrImage.data.view.buffer, hdrImage.width, hdrImage.height, TextureFormat.RGBA128,
readable ? Usage.DynamicUsage : Usage.StaticUsage));
}, failed);
}
else {
var img: ImageElement = cast Browser.document.createElement("img");
img.onerror = function(event: Dynamic) failed({url: desc.files[0], error: event});
img.onload = function(event: Dynamic) done(Image.fromImage(img, readable));
img.crossOrigin = "";
img.src = desc.files[0];
}
}
public static function getSoundFormats(): Array<String> {
var element = Browser.document.createAudioElement();
var formats = new Array<String>();
#if !kha_debug_html5
if (element.canPlayType("audio/mp4") != "")
formats.push("mp4");
if (element.canPlayType("audio/mp3") != "")
formats.push("mp3");
if (element.canPlayType("audio/wav") != "")
formats.push("wav");
#end
if (SystemImpl._hasWebAudio || element.canPlayType("audio/ogg") != "")
formats.push("ogg");
return formats;
}
public static function loadSoundFromDescription(desc: Dynamic, done: kha.Sound->Void, failed: AssetError->Void) {
if (SystemImpl._hasWebAudio) {
#if !kha_debug_html5
var element = Browser.document.createAudioElement();
if (element.canPlayType("audio/mp4") != "") {
for (i in 0...desc.files.length) {
var file: String = desc.files[i];
if (file.endsWith(".mp4")) {
new WebAudioSound(file, done, failed);
return;
}
}
}
if (element.canPlayType("audio/mp3") != "") {
for (i in 0...desc.files.length) {
var file: String = desc.files[i];
if (file.endsWith(".mp3")) {
new WebAudioSound(file, done, failed);
return;
}
}
}
if (element.canPlayType("audio/wav") != "") {
for (i in 0...desc.files.length) {
var file: String = desc.files[i];
if (file.endsWith(".wav")) {
new WebAudioSound(file, done, failed);
return;
}
}
}
#end
for (i in 0...desc.files.length) {
var file: String = desc.files[i];
if (file.endsWith(".ogg")) {
new WebAudioSound(file, done, failed);
return;
}
}
failed({
url: desc.files.join(","),
error: "Unable to find sound files with supported audio formats",
});
}
else if (SystemImpl.mobile) {
var element = Browser.document.createAudioElement();
if (element.canPlayType("audio/mp4") != "") {
for (i in 0...desc.files.length) {
var file: String = desc.files[i];
if (file.endsWith(".mp4")) {
new MobileWebAudioSound(file, done, failed);
return;
}
}
}
if (element.canPlayType("audio/mp3") != "") {
for (i in 0...desc.files.length) {
var file: String = desc.files[i];
if (file.endsWith(".mp3")) {
new MobileWebAudioSound(file, done, failed);
return;
}
}
}
if (element.canPlayType("audio/wav") != "") {
for (i in 0...desc.files.length) {
var file: String = desc.files[i];
if (file.endsWith(".wav")) {
new MobileWebAudioSound(file, done, failed);
return;
}
}
}
for (i in 0...desc.files.length) {
var file: String = desc.files[i];
if (file.endsWith(".ogg")) {
new MobileWebAudioSound(file, done, failed);
return;
}
}
failed({
url: desc.files.join(","),
error: "Unable to find sound files with supported audio formats",
});
}
else {
new kha.js.Sound(desc.files, done, failed);
}
}
public static function getVideoFormats(): Array<String> {
#if kha_debug_html5
return ["webm"];
#else
return ["mp4", "webm"];
#end
}
public static function loadVideoFromDescription(desc: Dynamic, done: kha.Video->Void, failed: AssetError->Void): Void {
kha.js.Video.fromFile(desc.files, done);
}
public static function loadRemote(desc: Dynamic, done: Blob->Void, failed: AssetError->Void) {
var request = untyped new XMLHttpRequest();
request.open("GET", desc.files[0], true);
request.responseType = "arraybuffer";
request.onreadystatechange = function() {
if (request.readyState != 4)
return;
if ((request.status >= 200 && request.status < 400)
|| (request.status == 0 && request.statusText == "")) { // Blobs loaded using --allow-file-access-from-files
var bytes: Bytes = null;
var arrayBuffer = request.response;
if (arrayBuffer != null) {
var byteArray: Dynamic = Syntax.code("new Uint8Array(arrayBuffer)");
bytes = Bytes.ofData(byteArray);
}
else if (request.responseBody != null) {
var data: Dynamic = untyped Syntax.code("VBArray(request.responseBody).toArray()");
bytes = Bytes.alloc(data.length);
for (i in 0...data.length)
bytes.set(i, data[i]);
}
else {
failed({url: desc.files[0]});
return;
}
done(new Blob(bytes));
}
else {
failed({url: desc.files[0]});
}
}
request.send(null);
}
public static function loadBlobFromDescription(desc: Dynamic, done: Blob->Void, failed: AssetError->Void) {
#if kha_debug_html5
var file: String = desc.files[0];
if (file.startsWith("http://") || file.startsWith("https://")) {
loadRemote(desc, done, failed);
}
else if (file.startsWith("drop://")) {
var dropFile = dropFiles.get(file.substring(7));
if (dropFile == null)
failed({url: file, error: 'file not found'});
else {
var reader = new FileReader();
reader.onloadend = () -> {
done(new Blob(Bytes.ofData(reader.result)));
};
reader.onerror = () -> failed({url: file, error: reader.error});
reader.readAsArrayBuffer(dropFile);
}
}
else {
var loadBlob = Syntax.code("window.electron.loadBlob");
loadBlob(desc, (byteArray: Dynamic) -> {
var bytes = Bytes.alloc(byteArray.byteLength);
for (i in 0...byteArray.byteLength)
bytes.set(i, byteArray[i]);
done(new Blob(bytes));
}, failed);
}
#else
loadRemote(desc, done, failed);
#end
}
public static function loadFontFromDescription(desc: Dynamic, done: Font->Void, failed: AssetError->Void): Void {
loadBlobFromDescription(desc, function(blob: Blob) {
done(new Font(blob));
}, failed);
}
}

View File

@ -0,0 +1,13 @@
package kha;
import haxe.macro.Context;
import haxe.macro.Expr;
class Macros {
public static macro function canvasId(): Expr {
return {
expr: EConst(CString(Context.getDefines().get("canvas_id"))),
pos: Context.currentPos()
};
}
}

View File

@ -0,0 +1,102 @@
package kha;
import haxe.io.Bytes;
import haxe.io.BytesBuffer;
import haxe.io.BytesData;
import js.Browser;
using StringTools;
class LocalStorageFile extends StorageFile {
var name: String;
public function new(name: String) {
this.name = name;
}
override public function read(): Blob {
var storage = Browser.getLocalStorage();
if (storage == null)
return null;
var value: String = storage.getItem(System.title + "_" + name);
if (value == null)
return null;
else
return Blob.fromBytes(decode(value));
}
override public function write(data: Blob): Void {
var storage = Browser.getLocalStorage();
if (storage == null)
return;
storage.setItem(System.title + "_" + name, encode(data.bytes.getData()));
}
/**
* Encodes byte array to yEnc string (from SASStore).
* @param {Array} source Byte array to convert to yEnc.
* @return {string} Resulting yEnc string from byte array.
*/
static function encode(source: BytesData): String {
var reserved = [0, 10, 13, 61];
var output = "";
var converted, ele;
var bytes = new js.lib.Uint8Array(source);
for (i in 0...bytes.length) {
ele = bytes[i];
converted = (ele + 42) % 256;
if (!Lambda.has(reserved, converted)) {
output += String.fromCharCode(converted);
}
else {
converted = (converted + 64) % 256;
output += "=" + String.fromCharCode(converted);
}
}
return output;
}
/**
* Decodes yEnc string to byte array (from SASStore).
* @param {string} source yEnc string to decode to byte array.
* @return {Array} Resulting byte array from yEnc string.
*/
static function decode(source: String): Bytes {
var output = new BytesBuffer();
var ck = false;
var c;
for (i in 0...source.length) {
c = source.fastCodeAt(i);
// ignore newlines
if (c == 13 || c == 10) {
continue;
}
// if we're an "=" and we haven't been flagged, set flag
if (c == 61 && !ck) {
ck = true;
continue;
}
if (ck) {
ck = false;
c = c - 64;
}
if (c < 42 && c > 0) {
output.addByte(c + 214);
}
else {
output.addByte(c - 42);
}
}
return output.getBytes();
}
}
class Storage {
public static function namedFile(name: String): StorageFile {
return new LocalStorageFile(name);
}
public static function defaultFile(): StorageFile {
return namedFile("default.kha");
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,584 @@
package kha;
import haxe.io.Bytes;
import js.Browser;
import js.lib.Uint8Array;
import js.lib.Uint16Array;
import js.lib.Float32Array;
import js.html.VideoElement;
import js.html.webgl.GL;
import js.html.webgl.Framebuffer;
import js.html.webgl.Renderbuffer;
import js.html.webgl.Texture;
import kha.graphics4.TextureFormat;
import kha.graphics4.DepthStencilFormat;
import kha.js.graphics4.Graphics;
class WebGLImage extends Image {
public var image: Dynamic;
public var video: VideoElement;
static var context: js.html.CanvasRenderingContext2D;
var data: js.html.ImageData;
var myWidth: Int;
var myHeight: Int;
var myFormat: TextureFormat;
var renderTarget: Bool;
var samples: Int;
public var frameBuffer: Framebuffer = null;
public var renderBuffer: Renderbuffer = null;
public var texture: Texture = null;
public var depthTexture: Texture = null;
public var MSAAFrameBuffer: Framebuffer = null;
var MSAAColorBuffer: Renderbuffer;
var MSAADepthBuffer: Renderbuffer;
var graphics1: kha.graphics1.Graphics;
var graphics2: kha.graphics2.Graphics;
var graphics4: kha.graphics4.Graphics;
var depthStencilFormat: DepthStencilFormat;
var readable: Bool;
// WebGL2 constants
static inline var GL_RGBA16F = 0x881A;
static inline var GL_RGBA32F = 0x8814;
static inline var GL_R16F = 0x822D;
static inline var GL_R32F = 0x822E;
static inline var GL_RED = 0x1903;
static inline var GL_DEPTH_COMPONENT24 = 0x81A6;
static inline var GL_DEPTH24_STENCIL8 = 0x88F0;
static inline var GL_DEPTH32F_STENCIL8 = 0x8CAD;
static var canvas: js.html.CanvasElement;
public static function init() {
if (context == null) {
// create only once
canvas = Browser.document.createCanvasElement();
if (canvas != null) {
context = canvas.getContext("2d");
canvas.width = 4096;
canvas.height = 4096;
context.globalCompositeOperation = "copy";
}
}
}
public function new(width: Int, height: Int, format: TextureFormat, renderTarget: Bool, depthStencilFormat: DepthStencilFormat, samples: Int,
readable: Bool) {
myWidth = width;
myHeight = height;
myFormat = format;
this.renderTarget = renderTarget;
this.samples = samples;
this.readable = readable;
image = null;
video = null;
this.depthStencilFormat = depthStencilFormat;
init();
if (renderTarget)
createTexture();
}
override function get_g1(): kha.graphics1.Graphics {
if (graphics1 == null) {
graphics1 = new kha.graphics2.Graphics1(this);
}
return graphics1;
}
override function get_g2(): kha.graphics2.Graphics {
if (graphics2 == null) {
graphics2 = new kha.js.graphics4.Graphics2(this);
}
return graphics2;
}
override function get_g4(): kha.graphics4.Graphics {
if (graphics4 == null) {
graphics4 = new Graphics(this);
}
return graphics4;
}
override function get_width(): Int {
return myWidth;
}
override function get_height(): Int {
return myHeight;
}
override function get_format(): TextureFormat {
return myFormat;
}
override function get_realWidth(): Int {
return myWidth;
}
override function get_realHeight(): Int {
return myHeight;
}
override function get_stride(): Int {
return formatByteSize(myFormat) * width;
}
override public function isOpaque(x: Int, y: Int): Bool {
if (data == null) {
if (context == null)
return true;
else
createImageData();
}
return (data.data[y * Std.int(image.width) * 4 + x * 4 + 3] != 0);
}
override public function at(x: Int, y: Int): Color {
if (bytes != null) {
var r = bytes.get(y * width * 4 + x * 4);
var g = bytes.get(y * width * 4 + x * 4 + 1);
var b = bytes.get(y * width * 4 + x * 4 + 2);
var a = bytes.get(y * width * 4 + x * 4 + 3);
return Color.fromValue((a << 24) | (r << 16) | (g << 8) | b);
}
else {
if (data == null) {
if (context == null)
return Color.Black;
else
createImageData();
}
var r = data.data[y * width * 4 + x * 4];
var g = data.data[y * width * 4 + x * 4 + 1];
var b = data.data[y * width * 4 + x * 4 + 2];
var a = data.data[y * width * 4 + x * 4 + 3];
return Color.fromValue((a << 24) | (r << 16) | (g << 8) | b);
}
}
function createImageData() {
if (Std.isOfType(image, Uint8Array)) {
data = new js.html.ImageData(new js.lib.Uint8ClampedArray(image.buffer), this.width, this.height);
}
else {
if (this.width > canvas.width || this.height > canvas.height) {
var cw = canvas.width;
var ch = canvas.height;
while (this.width > cw || this.height > ch) {
cw *= 2;
ch *= 2;
}
canvas.width = cw;
canvas.height = ch;
}
context.strokeStyle = "rgba(0,0,0,0)";
context.fillStyle = "rgba(0,0,0,0)";
context.fillRect(0, 0, image.width, image.height);
context.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
data = context.getImageData(0, 0, image.width, image.height);
}
}
static function upperPowerOfTwo(v: Int): Int {
v--;
v |= v >>> 1;
v |= v >>> 2;
v |= v >>> 4;
v |= v >>> 8;
v |= v >>> 16;
v++;
return v;
}
public function createTexture(): Void {
if (SystemImpl.gl == null)
return;
texture = SystemImpl.gl.createTexture();
// texture.image = image;
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
// Sys.gl.pixelStorei(Sys.gl.UNPACK_FLIP_Y_WEBGL, true);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
if (renderTarget) {
frameBuffer = SystemImpl.gl.createFramebuffer();
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
switch (myFormat) {
case DEPTH16:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, realWidth, realHeight, 0,
GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
case RGBA128:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.FLOAT, null);
case RGBA64:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, realWidth, realHeight, 0, GL.RGBA,
SystemImpl.halfFloat.HALF_FLOAT_OES, null);
case RGBA32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
case A32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, realWidth, realHeight, 0,
SystemImpl.gl2 ? GL_RED : GL.ALPHA, GL.FLOAT, null);
case A16:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, realWidth, realHeight, 0,
SystemImpl.gl2 ? GL_RED : GL.ALPHA, SystemImpl.halfFloat.HALF_FLOAT_OES, null);
default:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
}
if (myFormat == DEPTH16) {
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_2D, texture, 0);
// Some WebGL implementations throw incomplete framebuffer error, create color attachment
if (!SystemImpl.gl2) {
var colortex = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, colortex);
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, realWidth, realHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, colortex, 0);
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
}
}
else {
if (samples > 1 && SystemImpl.gl2) {
MSAAFrameBuffer = SystemImpl.gl.createFramebuffer();
MSAAColorBuffer = SystemImpl.gl.createRenderbuffer();
SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, MSAAColorBuffer);
var MSAAFormat = switch (myFormat) {
case RGBA128:
untyped SystemImpl.gl.RGBA32F;
case RGBA64:
untyped SystemImpl.gl.RGBA16F;
case RGBA32:
untyped SystemImpl.gl.RGBA8;
case A32:
GL_R32F;
case A16:
GL_R16F;
default:
untyped SystemImpl.gl.RGBA8;
};
untyped SystemImpl.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, MSAAFormat, realWidth, realHeight);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.RENDERBUFFER, MSAAColorBuffer);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, MSAAFrameBuffer);
}
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_2D, texture, 0);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
initDepthStencilBuffer(depthStencilFormat);
var e = SystemImpl.gl.checkFramebufferStatus(GL.FRAMEBUFFER);
if (e != GL.FRAMEBUFFER_COMPLETE) {
trace("checkframebufferStatus error " + e);
}
SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, null);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
else if (video != null) {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, video);
}
else {
switch (myFormat) {
case RGBA128:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.FLOAT, image);
case RGBA64:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA,
SystemImpl.halfFloat.HALF_FLOAT_OES, image);
case RGBA32:
if (Std.isOfType(image, Uint8Array)) {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, image);
}
else {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, image);
}
case A32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, myWidth, myHeight, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
GL.FLOAT, image);
case A16:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, myWidth, myHeight, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
SystemImpl.halfFloat.HALF_FLOAT_OES, image);
case L8:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.LUMINANCE, myWidth, myHeight, 0, GL.LUMINANCE, GL.UNSIGNED_BYTE, image);
default:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, image);
}
}
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
}
function initDepthStencilBuffer(depthStencilFormat: DepthStencilFormat) {
switch (depthStencilFormat) {
case NoDepthAndStencil:
case DepthOnly, Depth16:
{
if (SystemImpl.depthTexture == null) {
renderBuffer = SystemImpl.gl.createRenderbuffer();
SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, renderBuffer);
SystemImpl.gl.renderbufferStorage(GL.RENDERBUFFER, GL.DEPTH_COMPONENT16, realWidth, realHeight);
SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.RENDERBUFFER, renderBuffer);
}
else {
depthTexture = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, depthTexture);
if (depthStencilFormat == DepthOnly)
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_DEPTH_COMPONENT24 : GL.DEPTH_COMPONENT, realWidth, realHeight, 0,
GL.DEPTH_COMPONENT, GL.UNSIGNED_INT, null);
else
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, realWidth, realHeight, 0,
GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
if (samples > 1 && SystemImpl.gl2) {
MSAADepthBuffer = SystemImpl.gl.createRenderbuffer();
SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, MSAADepthBuffer);
if (depthStencilFormat == DepthOnly)
untyped SystemImpl.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, GL_DEPTH_COMPONENT24, realWidth, realHeight);
else
untyped SystemImpl.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, GL.DEPTH_COMPONENT16, realWidth, realHeight);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.RENDERBUFFER, MSAADepthBuffer);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, MSAAFrameBuffer);
}
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_2D, depthTexture, 0);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
}
case DepthAutoStencilAuto, Depth24Stencil8, Depth32Stencil8:
if (SystemImpl.depthTexture == null) {
renderBuffer = SystemImpl.gl.createRenderbuffer();
SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, renderBuffer);
SystemImpl.gl.renderbufferStorage(GL.RENDERBUFFER, GL.DEPTH_STENCIL, realWidth, realHeight);
SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.RENDERBUFFER, renderBuffer);
}
else {
depthTexture = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, depthTexture);
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_DEPTH24_STENCIL8 : GL.DEPTH_STENCIL, realWidth, realHeight, 0,
GL.DEPTH_STENCIL, SystemImpl.depthTexture.UNSIGNED_INT_24_8_WEBGL, null);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
if (samples > 1 && SystemImpl.gl2) {
MSAADepthBuffer = SystemImpl.gl.createRenderbuffer();
SystemImpl.gl.bindRenderbuffer(GL.RENDERBUFFER, MSAADepthBuffer);
untyped SystemImpl.gl.renderbufferStorageMultisample(GL.RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, realWidth, realHeight);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.RENDERBUFFER, MSAADepthBuffer);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, MSAAFrameBuffer);
}
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_2D, depthTexture, 0);
}
}
}
public function set(stage: Int): Void {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
if (video != null)
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, video);
}
public function setDepth(stage: Int): Void {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, depthTexture);
}
override public function setDepthStencilFrom(image: Image): Void {
depthTexture = cast(image, WebGLImage).depthTexture;
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_2D, depthTexture, 0);
if (samples > 1 && SystemImpl.gl2) {
MSAADepthBuffer = cast(image, WebGLImage).MSAADepthBuffer;
SystemImpl.gl.framebufferRenderbuffer(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.RENDERBUFFER, MSAADepthBuffer);
}
}
static function formatByteSize(format: TextureFormat): Int {
return switch (format) {
case RGBA32: 4;
case L8: 1;
case RGBA128: 16;
case DEPTH16: 2;
case RGBA64: 8;
case A32: 4;
case A16: 2;
default: 4;
}
}
public function bytesToArray(bytes: Bytes): js.lib.ArrayBufferView {
return switch (myFormat) {
case RGBA32, L8:
new Uint8Array(bytes.getData());
case RGBA128, RGBA64, A32, A16:
new Float32Array(bytes.getData());
default:
new Uint8Array(bytes.getData());
}
}
public var bytes: Bytes;
override public function lock(level: Int = 0): Bytes {
bytes = Bytes.alloc(formatByteSize(myFormat) * width * height);
return bytes;
}
override public function unlock(): Void {
data = null;
image = null;
if (SystemImpl.gl != null) {
texture = SystemImpl.gl.createTexture();
// texture.image = image;
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
// Sys.gl.pixelStorei(Sys.gl.UNPACK_FLIP_Y_WEBGL, true);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
switch (myFormat) {
case L8:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.LUMINANCE, width, height, 0, GL.LUMINANCE, GL.UNSIGNED_BYTE, bytesToArray(bytes));
if (SystemImpl.ie && SystemImpl.gl.getError() == 1282) { // no LUMINANCE support in IE11
var rgbaBytes = Bytes.alloc(width * height * 4);
for (y in 0...height)
for (x in 0...width) {
var value = bytes.get(y * width + x);
rgbaBytes.set(y * width * 4 + x * 4 + 0, value);
rgbaBytes.set(y * width * 4 + x * 4 + 1, value);
rgbaBytes.set(y * width * 4 + x * 4 + 2, value);
rgbaBytes.set(y * width * 4 + x * 4 + 3, 255);
}
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(rgbaBytes));
}
case RGBA128:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, width, height, 0, GL.RGBA, GL.FLOAT,
bytesToArray(bytes));
case RGBA64:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, width, height, 0, GL.RGBA,
SystemImpl.halfFloat.HALF_FLOAT_OES, bytesToArray(bytes));
case A32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, width, height, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
GL.FLOAT, bytesToArray(bytes));
case A16:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, width, height, 0, SystemImpl.gl2 ? GL_RED : GL.ALPHA,
SystemImpl.halfFloat.HALF_FLOAT_OES, bytesToArray(bytes));
case RGBA32:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(bytes));
default:
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, width, height, 0, GL.RGBA, GL.UNSIGNED_BYTE, bytesToArray(bytes));
}
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
if (!readable) {
bytes = null;
}
}
}
var pixels: js.lib.ArrayBufferView = null;
override public function getPixels(): Bytes {
if (frameBuffer == null)
return null;
if (pixels == null) {
switch (myFormat) {
case RGBA128, A32:
pixels = new Float32Array(Std.int(formatByteSize(myFormat) / 4) * width * height);
case RGBA64, A16:
pixels = new Uint16Array(Std.int(formatByteSize(myFormat) / 2) * width * height);
case RGBA32, L8:
pixels = new Uint8Array(formatByteSize(myFormat) * width * height);
default:
pixels = new Uint8Array(formatByteSize(myFormat) * width * height);
}
}
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
switch (myFormat) {
case RGBA128:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, GL.FLOAT, pixels);
case RGBA64:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, SystemImpl.halfFloat.HALF_FLOAT_OES, pixels);
case RGBA32:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, GL.UNSIGNED_BYTE, pixels);
case A32:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, SystemImpl.gl2 ? GL_RED : GL.ALPHA, GL.FLOAT, pixels);
case A16:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, SystemImpl.gl2 ? GL_RED : GL.ALPHA, SystemImpl.halfFloat.HALF_FLOAT_OES, pixels);
case L8:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, SystemImpl.gl2 ? GL_RED : GL.ALPHA, GL.UNSIGNED_BYTE, pixels);
default:
SystemImpl.gl.readPixels(0, 0, myWidth, myHeight, GL.RGBA, GL.UNSIGNED_BYTE, pixels);
}
return Bytes.ofData(pixels.buffer);
}
override public function unload(): Void {
if (texture != null)
SystemImpl.gl.deleteTexture(texture);
if (depthTexture != null)
SystemImpl.gl.deleteTexture(depthTexture);
if (frameBuffer != null)
SystemImpl.gl.deleteFramebuffer(frameBuffer);
if (renderBuffer != null)
SystemImpl.gl.deleteRenderbuffer(renderBuffer);
if (MSAAFrameBuffer != null)
SystemImpl.gl.deleteFramebuffer(MSAAFrameBuffer);
if (MSAAColorBuffer != null)
SystemImpl.gl.deleteRenderbuffer(MSAAColorBuffer);
if (MSAADepthBuffer != null)
SystemImpl.gl.deleteRenderbuffer(MSAADepthBuffer);
}
override public function generateMipmaps(levels: Int): Void {
// WebGL requires to generate all mipmaps down to 1x1 size, ignoring levels for now
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
SystemImpl.gl.generateMipmap(GL.TEXTURE_2D);
}
override public function setMipmaps(mipmaps: Array<Image>): Void {
// Similar to generateMipmaps, specify all the levels down to 1x1 size
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, texture);
if (myFormat == TextureFormat.RGBA128) {
for (i in 0...mipmaps.length) {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, i + 1, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, mipmaps[i].width, mipmaps[i].height, 0, GL.RGBA,
GL.FLOAT, cast(mipmaps[i], WebGLImage).image);
}
}
else if (myFormat == TextureFormat.RGBA64) {
for (i in 0...mipmaps.length) {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, i + 1, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, mipmaps[i].width, mipmaps[i].height, 0, GL.RGBA,
SystemImpl.halfFloat.HALF_FLOAT_OES, cast(mipmaps[i], WebGLImage).image);
}
}
else {
for (i in 0...mipmaps.length) {
SystemImpl.gl.texImage2D(GL.TEXTURE_2D, i + 1, GL.RGBA, GL.RGBA, GL.UNSIGNED_BYTE, cast(mipmaps[i], WebGLImage).image);
}
}
}
}

View File

@ -0,0 +1,195 @@
package kha;
import js.Syntax;
import js.html.MutationObserver;
class Window {
static var windows: Array<Window> = [];
static var resizeCallbacks: Array<Array<Int->Int->Void>> = [];
var num: Int;
var canvas: js.html.CanvasElement;
var defaultWidth: Int;
var defaultHeight: Int;
@:noCompletion
@:noDoc
public function new(num: Int, defaultWidth: Int, defaultHeight: Int, canvas: js.html.CanvasElement) {
this.num = num;
this.canvas = canvas;
this.defaultWidth = defaultWidth;
this.defaultHeight = defaultHeight;
windows.push(this);
resizeCallbacks[num] = [];
windows.push(this);
final observer: MutationObserver = new MutationObserver(function(mutations: Array<js.html.MutationRecord>, observer: MutationObserver) {
var isResize = false;
for (mutation in mutations) {
if (mutation.attributeName == "width" || mutation.attributeName == "height") {
isResize = true;
break;
}
}
if (isResize) {
this.resize(canvas.width, canvas.height);
}
});
observer.observe(canvas, {attributes: true});
}
public static function create(win: WindowOptions = null, frame: FramebufferOptions = null): Window {
return null;
}
public static function destroy(window: Window): Void {}
public static function get(index: Int): Window {
return windows[index];
}
public static var all(get, never): Array<Window>;
static function get_all(): Array<Window> {
return windows;
}
public function resize(width: Int, height: Int): Void {
for (callback in resizeCallbacks[num]) {
callback(width, height);
}
}
public function move(x: Int, y: Int): Void {}
public function changeWindowFeatures(features: Int): Void {}
public function changeFramebuffer(frame: FramebufferOptions): Void {}
public var x(get, set): Int;
function get_x(): Int {
return 0;
}
function set_x(value: Int): Int {
return 0;
}
public var y(get, set): Int;
function get_y(): Int {
return 0;
}
function set_y(value: Int): Int {
return 0;
}
public var width(get, set): Int;
function get_width(): Int {
return canvas.width == 0 ? defaultWidth : canvas.width;
}
function set_width(value: Int): Int {
return 800;
}
public var height(get, set): Int;
function get_height(): Int {
return canvas.height == 0 ? defaultHeight : canvas.height;
}
function set_height(value: Int): Int {
return 600;
}
public var mode(get, set): WindowMode;
function get_mode(): WindowMode {
return isFullscreen() ? Fullscreen : Windowed;
}
function set_mode(mode: WindowMode): WindowMode {
if (mode == Fullscreen || mode == ExclusiveFullscreen) {
if (!isFullscreen()) {
requestFullscreen();
}
}
else {
if (isFullscreen()) {
exitFullscreen();
}
}
return mode;
}
function isFullscreen(): Bool {
return Syntax.code("document.fullscreenElement === this.canvas ||
document.mozFullScreenElement === this.canvas ||
document.webkitFullscreenElement === this.canvas ||
document.msFullscreenElement === this.canvas ");
}
function requestFullscreen(): Void {
untyped if (canvas.requestFullscreen) {
var c: Dynamic = canvas;
c.requestFullscreen({navigationUI: "hide"});
}
else if (canvas.msRequestFullscreen) {
canvas.msRequestFullscreen();
}
else if (canvas.mozRequestFullScreen) {
canvas.mozRequestFullScreen();
}
else if (canvas.webkitRequestFullscreen) {
canvas.webkitRequestFullscreen();
}
}
function exitFullscreen(): Void {
untyped if (document.exitFullscreen) {
document.exitFullscreen();
}
else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
}
else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
public var visible(get, set): Bool;
function get_visible(): Bool {
return true;
}
function set_visible(value: Bool): Bool {
return true;
}
public var title(get, set): String;
function get_title(): String {
return "Kha";
}
function set_title(value: String): String {
return "Kha";
}
public function notifyOnResize(callback: Int->Int->Void): Void {
resizeCallbacks[num].push(callback);
}
public var vSynced(get, never): Bool;
function get_vSynced(): Bool {
return true;
}
}

View File

@ -0,0 +1,187 @@
package kha.arrays;
import js.lib.DataView;
import kha.FastFloat;
@:forward
abstract ByteArray(DataView) to DataView {
static final LITTLE_ENDIAN: Bool = js.Syntax.code("new Uint8Array(new Uint32Array([0x12345678]).buffer)[0] === 0x78");
public var buffer(get, never): ByteBuffer;
inline function get_buffer(): ByteBuffer {
return cast this.buffer;
}
public function new(buffer: ByteBuffer, ?byteOffset: Int, ?byteLength: Int) {
this = new DataView(buffer, byteOffset, byteLength);
}
static public function make(byteLength: Int): ByteArray {
return new ByteArray(ByteBuffer.create(byteLength));
}
public inline function getInt8(byteOffset: Int): Int {
return this.getInt8(byteOffset);
}
public inline function getUint8(byteOffset: Int): Int {
return this.getUint8(byteOffset);
}
public inline function getInt16(byteOffset: Int): Int {
return this.getInt16(byteOffset, LITTLE_ENDIAN);
}
public inline function getUint16(byteOffset: Int): Int {
return this.getUint16(byteOffset, LITTLE_ENDIAN);
}
public inline function getInt32(byteOffset: Int): Int {
return this.getInt32(byteOffset, LITTLE_ENDIAN);
}
public inline function getUint32(byteOffset: Int): Int {
return this.getUint32(byteOffset, LITTLE_ENDIAN);
}
public inline function getFloat32(byteOffset: Int): FastFloat {
return this.getFloat32(byteOffset, LITTLE_ENDIAN);
}
public inline function getFloat64(byteOffset: Int): Float {
return this.getFloat64(byteOffset, LITTLE_ENDIAN);
}
public inline function setInt8(byteOffset: Int, value: Int): Void {
this.setInt8(byteOffset, value);
}
public inline function setUint8(byteOffset: Int, value: Int): Void {
this.setUint8(byteOffset, value);
}
public inline function setInt16(byteOffset: Int, value: Int): Void {
this.setInt16(byteOffset, value, LITTLE_ENDIAN);
}
public inline function setUint16(byteOffset: Int, value: Int): Void {
this.setUint16(byteOffset, value, LITTLE_ENDIAN);
}
public inline function setInt32(byteOffset: Int, value: Int): Void {
this.setInt32(byteOffset, value, LITTLE_ENDIAN);
}
public inline function setUint32(byteOffset: Int, value: Int): Void {
this.setUint32(byteOffset, value, LITTLE_ENDIAN);
}
public inline function setFloat32(byteOffset: Int, value: FastFloat): Void {
this.setFloat32(byteOffset, value, true);
}
public inline function setFloat64(byteOffset: Int, value: Float): Void {
this.setFloat64(byteOffset, value, LITTLE_ENDIAN);
}
public inline function getInt16LE(byteOffset: Int): Int {
return this.getInt16(byteOffset, true);
}
public inline function getUint16LE(byteOffset: Int): Int {
return this.getUint16(byteOffset, true);
}
public inline function getInt32LE(byteOffset: Int): Int {
return this.getInt32(byteOffset, true);
}
public inline function getUint32LE(byteOffset: Int): Int {
return this.getUint32(byteOffset, true);
}
public inline function getFloat32LE(byteOffset: Int): FastFloat {
return this.getFloat32(byteOffset, true);
}
public inline function getFloat64LE(byteOffset: Int): Float {
return this.getFloat64(byteOffset, true);
}
public inline function setInt16LE(byteOffset: Int, value: Int): Void {
this.setInt16(byteOffset, value, true);
}
public inline function setUint16LE(byteOffset: Int, value: Int): Void {
this.setUint16(byteOffset, value, true);
}
public inline function setInt32LE(byteOffset: Int, value: Int): Void {
this.setInt32(byteOffset, value, true);
}
public inline function setUint32LE(byteOffset: Int, value: Int): Void {
this.setUint32(byteOffset, value, true);
}
public inline function setFloat32LE(byteOffset: Int, value: FastFloat): Void {
this.setFloat32(byteOffset, value, true);
}
public inline function setFloat64LE(byteOffset: Int, value: Float): Void {
this.setFloat64(byteOffset, value, true);
}
public inline function getInt16BE(byteOffset: Int): Int {
return this.getInt16(byteOffset);
}
public inline function getUint16BE(byteOffset: Int): Int {
return this.getUint16(byteOffset);
}
public inline function getInt32BE(byteOffset: Int): Int {
return this.getInt32(byteOffset);
}
public inline function getUint32BE(byteOffset: Int): Int {
return this.getUint32(byteOffset);
}
public inline function getFloat32BE(byteOffset: Int): FastFloat {
return this.getFloat32(byteOffset);
}
public inline function getFloat64BE(byteOffset: Int): Float {
return this.getFloat64(byteOffset);
}
public inline function setInt16BE(byteOffset: Int, value: Int): Void {
this.setInt16(byteOffset, value);
}
public inline function setUint16BE(byteOffset: Int, value: Int): Void {
this.setUint16(byteOffset, value);
}
public inline function setInt32BE(byteOffset: Int, value: Int): Void {
this.setInt32(byteOffset, value);
}
public inline function setUint32BE(byteOffset: Int, value: Int): Void {
this.setUint32(byteOffset, value);
}
public inline function setFloat32BE(byteOffset: Int, value: FastFloat): Void {
this.setFloat32(byteOffset, value);
}
public inline function setFloat64BE(byteOffset: Int, value: Float): Void {
this.setFloat64(byteOffset, value);
}
public inline function subarray(start: Int, ?end: Int): ByteArray {
return new ByteArray(buffer, start, end != null ? end - start : null);
}
}

View File

@ -0,0 +1,14 @@
package kha.arrays;
import js.lib.ArrayBuffer;
@:forward
abstract ByteBuffer(ArrayBuffer) from ArrayBuffer to ArrayBuffer {
public static function create(length: Int): ByteBuffer {
return new ByteBuffer(length);
}
function new(length: Int) {
this = new ArrayBuffer(length);
}
}

View File

@ -0,0 +1,3 @@
package kha.audio1;
typedef Audio = kha.audio2.Audio1;

View File

@ -0,0 +1,107 @@
package kha.audio2;
import js.Syntax;
import js.Browser;
import js.html.URL;
import js.html.audio.AudioContext;
import js.html.audio.AudioProcessingEvent;
import js.html.audio.ScriptProcessorNode;
import kha.internal.IntBox;
import kha.js.AEAudioChannel;
import kha.Sound;
class Audio {
public static var disableGcInteractions = false;
static var intBox: IntBox = new IntBox(0);
static var buffer: Buffer;
@:noCompletion public static var _context: AudioContext;
static var processingNode: ScriptProcessorNode;
static function initContext(): Void {
try {
_context = new AudioContext();
return;
}
catch (e:Dynamic) {}
try {
Syntax.code("this._context = new webkitAudioContext();");
return;
}
catch (e:Dynamic) {}
}
@:noCompletion
public static function _init(): Bool {
initContext();
if (_context == null)
return false;
Audio.samplesPerSecond = Math.round(_context.sampleRate);
var bufferSize = 1024 * 2;
buffer = new Buffer(bufferSize * 4, 2, Std.int(_context.sampleRate));
processingNode = _context.createScriptProcessor(bufferSize, 0, 2);
processingNode.onaudioprocess = function(e: AudioProcessingEvent) {
var output1 = e.outputBuffer.getChannelData(0);
var output2 = e.outputBuffer.getChannelData(1);
if (audioCallback != null) {
intBox.value = e.outputBuffer.length * 2;
audioCallback(intBox, buffer);
for (i in 0...e.outputBuffer.length) {
output1[i] = buffer.data.get(buffer.readLocation);
buffer.readLocation += 1;
output2[i] = buffer.data.get(buffer.readLocation);
buffer.readLocation += 1;
if (buffer.readLocation >= buffer.size) {
buffer.readLocation = 0;
}
}
}
else {
for (i in 0...e.outputBuffer.length) {
output1[i] = 0;
output2[i] = 0;
}
}
}
processingNode.connect(_context.destination);
return true;
}
public static var samplesPerSecond: Int;
public static var audioCallback: kha.internal.IntBox->Buffer->Void;
static var virtualChannels: Array<VirtualStreamChannel> = [];
public static function wakeChannels() {
SystemImpl.mobileAudioPlaying = true;
for (channel in virtualChannels) {
channel.wake();
}
}
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
// var source = _context.createMediaStreamSource(cast sound.compressedData.getData());
// source.connect(_context.destination);
var element = Browser.document.createAudioElement();
#if kha_debug_html5
var blob = new js.html.Blob([sound.compressedData.getData()], {type: "audio/ogg"});
#else
var blob = new js.html.Blob([sound.compressedData.getData()], {type: "audio/mp4"});
#end
element.src = URL.createObjectURL(blob);
element.loop = loop;
var channel = new AEAudioChannel(element, loop);
if (SystemImpl.mobileAudioPlaying) {
channel.play();
return channel;
}
else {
var virtualChannel = new VirtualStreamChannel(channel, loop);
virtualChannels.push(virtualChannel);
return virtualChannel;
}
}
}

View File

@ -0,0 +1,126 @@
package kha.audio2;
import kha.js.AEAudioChannel;
import kha.audio1.AudioChannel;
enum abstract PlayMode(Int) {
var Stopped;
var Paused;
var Playing;
}
class VirtualStreamChannel implements kha.audio1.AudioChannel {
var aeChannel: AEAudioChannel;
var mode = PlayMode.Playing;
var lastTickTime: Float;
var lastPosition: Float;
var looping: Bool;
public function new(aeChannel: AEAudioChannel, looping: Bool) {
this.aeChannel = aeChannel;
this.looping = looping;
lastTickTime = Scheduler.realTime();
lastPosition = 0;
}
public function wake(): Void {
updatePosition();
aeChannel.position = lastPosition;
aeChannel.play();
}
function updatePosition(): Void {
var now = Scheduler.realTime();
switch (mode) {
case Stopped:
lastPosition = 0;
case Paused:
// nothing
case Playing:
lastPosition += now - lastTickTime;
while (lastPosition > length) {
lastPosition -= length;
}
}
lastTickTime = now;
}
public function play(): Void {
if (SystemImpl.mobileAudioPlaying) {
aeChannel.play();
}
else {
updatePosition();
mode = Playing;
}
}
public function pause(): Void {
if (SystemImpl.mobileAudioPlaying) {
aeChannel.pause();
}
else {
updatePosition();
mode = Paused;
}
}
public function stop(): Void {
if (SystemImpl.mobileAudioPlaying) {
aeChannel.stop();
}
else {
updatePosition();
mode = Stopped;
}
}
public var length(get, never): Float; // Seconds
function get_length(): Float {
return aeChannel.length;
}
public var position(get, set): Float; // Seconds
function get_position(): Float {
if (SystemImpl.mobileAudioPlaying) {
return aeChannel.position;
}
else {
updatePosition();
return lastPosition;
}
}
function set_position(value: Float): Float {
if (SystemImpl.mobileAudioPlaying) {
return aeChannel.position = value;
}
else {
updatePosition();
return lastPosition = value;
}
}
public var volume(get, set): Float;
function get_volume(): Float {
return aeChannel.volume;
}
function set_volume(value: Float): Float {
return aeChannel.volume = value;
}
public var finished(get, never): Bool;
function get_finished(): Bool {
if (SystemImpl.mobileAudioPlaying) {
return aeChannel.finished;
}
else {
return mode == Stopped || (!looping && position >= length);
}
}
}

View File

@ -0,0 +1,51 @@
package kha.capture;
import js.html.audio.AudioProcessingEvent;
import kha.audio2.Buffer;
class AudioCapture {
static var input: js.html.audio.MediaStreamAudioSourceNode;
static var processingNode: js.html.audio.ScriptProcessorNode;
static var buffer: Buffer;
public static var audioCallback: Int->Buffer->Void;
public static function init(initialized: Void->Void, error: Void->Void): Void {
if (kha.audio2.Audio._context == null) {
error();
return;
}
var getUserMedia = untyped __js__("navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia");
getUserMedia.call(js.Browser.navigator, {audio: true}, function(stream: Dynamic) {
input = kha.audio2.Audio._context.createMediaStreamSource(stream);
var bufferSize = 1024 * 2;
buffer = new Buffer(bufferSize * 4, 2, Std.int(kha.audio2.Audio._context.sampleRate));
processingNode = kha.audio2.Audio._context.createScriptProcessor(bufferSize, 1, 0);
processingNode.onaudioprocess = function(e: AudioProcessingEvent) {
if (audioCallback != null) {
var input1 = e.inputBuffer.getChannelData(0);
var input2 = e.inputBuffer.getChannelData(0);
for (i in 0...e.inputBuffer.length) {
buffer.data.set(buffer.writeLocation, input1[i]);
buffer.writeLocation += 1;
buffer.data.set(buffer.writeLocation, input2[i]);
buffer.writeLocation += 1;
if (buffer.writeLocation >= buffer.size) {
buffer.writeLocation = 0;
}
}
audioCallback(e.inputBuffer.length * 2, buffer);
}
}
input.connect(processingNode);
// input.connect(kha.audio2.Audio._context.destination);
initialized();
}, function() {
error();
});
}
}

View File

@ -0,0 +1,18 @@
package kha.capture;
import js.Browser;
class VideoCapture {
public static function init(initialized: kha.Video->Void, error: Void->Void): Void {
var getUserMedia = untyped __js__("navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia");
getUserMedia.call(js.Browser.navigator, {audio: true, video: true}, function(stream: Dynamic) {
var element: js.html.VideoElement = cast Browser.document.createElement("video");
element.srcObject = stream;
element.onloadedmetadata = function(e) {
initialized(kha.js.Video.fromElement(element));
}
}, function() {
error();
});
}
}

View File

@ -0,0 +1,199 @@
package kha.graphics4;
import js.html.webgl.GL;
import haxe.io.Bytes;
import kha.js.graphics4.Graphics;
class CubeMap implements Canvas implements Resource {
var myWidth: Int;
var myHeight: Int;
var format: TextureFormat;
var renderTarget: Bool;
var depthStencilFormat: DepthStencilFormat;
var graphics4: kha.graphics4.Graphics;
public var frameBuffer: Dynamic = null;
public var texture: Dynamic = null;
public var depthTexture: Dynamic = null;
public var isDepthAttachment: Bool = false;
// WebGL2 constants
static inline var GL_RGBA16F = 0x881A;
static inline var GL_RGBA32F = 0x8814;
static inline var GL_R16F = 0x822D;
static inline var GL_R32F = 0x822E;
static inline var GL_DEPTH_COMPONENT24 = 0x81A6;
static inline var GL_DEPTH24_STENCIL8 = 0x88F0;
static inline var GL_DEPTH32F_STENCIL8 = 0x8CAD;
function new(size: Int, format: TextureFormat, renderTarget: Bool, depthStencilFormat: DepthStencilFormat) {
myWidth = size;
myHeight = size;
this.format = format;
this.renderTarget = renderTarget;
this.depthStencilFormat = depthStencilFormat;
if (renderTarget)
createTexture();
}
public static function createRenderTarget(size: Int, format: TextureFormat = null, depthStencil: DepthStencilFormat = null): CubeMap {
if (format == null)
format = TextureFormat.RGBA32;
if (depthStencil == null)
depthStencil = NoDepthAndStencil;
return new CubeMap(size, format, true, depthStencil);
}
function createTexture() {
if (SystemImpl.gl == null)
return;
texture = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
if (renderTarget) {
frameBuffer = SystemImpl.gl.createFramebuffer();
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
switch (format) {
case DEPTH16:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, myWidth,
myHeight, 0, GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
case RGBA128:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_RGBA32F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA,
GL.FLOAT, null);
case RGBA64:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_RGBA16F : GL.RGBA, myWidth, myHeight, 0, GL.RGBA,
SystemImpl.halfFloat.HALF_FLOAT_OES, null);
case RGBA32:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
case A32:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_R32F : GL.ALPHA, myWidth, myHeight, 0, GL.ALPHA,
GL.FLOAT, null);
case A16:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, SystemImpl.gl2 ? GL_R16F : GL.ALPHA, myWidth, myHeight, 0, GL.ALPHA,
SystemImpl.halfFloat.HALF_FLOAT_OES, null);
default:
for (i in 0...6)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
}
if (format == DEPTH16) {
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
isDepthAttachment = true;
// Some WebGL implementations throw incomplete framebuffer error, create color attachment
if (!SystemImpl.gl2) {
var colortex = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, colortex);
for (i in 0...6) {
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL.RGBA, myWidth, myHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, null);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_CUBE_MAP_POSITIVE_X + i, colortex, 0);
}
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
}
}
initDepthStencilBuffer(depthStencilFormat);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
}
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, null);
}
function initDepthStencilBuffer(depthStencilFormat: DepthStencilFormat) {
switch (depthStencilFormat) {
case NoDepthAndStencil:
case DepthOnly, Depth16:
{
depthTexture = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
if (depthStencilFormat == DepthOnly)
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL_DEPTH_COMPONENT24 : GL.DEPTH_COMPONENT, myWidth, myHeight, 0,
GL.DEPTH_COMPONENT, GL.UNSIGNED_INT, null);
else
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL.DEPTH_COMPONENT16 : GL.DEPTH_COMPONENT, myWidth, myHeight, 0,
GL.DEPTH_COMPONENT, GL.UNSIGNED_SHORT, null);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_ATTACHMENT, GL.TEXTURE_CUBE_MAP, depthTexture, 0);
}
case DepthAutoStencilAuto, Depth24Stencil8, Depth32Stencil8:
depthTexture = SystemImpl.gl.createTexture();
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
SystemImpl.gl.texImage2D(GL.TEXTURE_CUBE_MAP, 0, SystemImpl.gl2 ? GL_DEPTH24_STENCIL8 : GL.DEPTH_STENCIL, myWidth, myHeight, 0,
GL.DEPTH_STENCIL, SystemImpl.depthTexture.UNSIGNED_INT_24_8_WEBGL, null);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, GL.DEPTH_STENCIL_ATTACHMENT, GL.TEXTURE_CUBE_MAP, depthTexture, 0);
}
}
public function set(stage: Int): Void {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, texture);
}
public function setDepth(stage: Int): Void {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + stage);
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, depthTexture);
}
public function unload(): Void {}
public function lock(level: Int = 0): Bytes {
return null;
}
public function unlock(): Void {}
public var width(get, never): Int;
function get_width(): Int {
return myWidth;
}
public var height(get, never): Int;
function get_height(): Int {
return myHeight;
}
public var g1(get, never): kha.graphics1.Graphics;
function get_g1(): kha.graphics1.Graphics {
return null;
}
public var g2(get, never): kha.graphics2.Graphics;
function get_g2(): kha.graphics2.Graphics {
return null;
}
public var g4(get, never): kha.graphics4.Graphics;
function get_g4(): kha.graphics4.Graphics {
if (graphics4 == null) {
graphics4 = new Graphics(this);
}
return graphics4;
}
}

View File

@ -0,0 +1,32 @@
package kha.graphics4;
import js.html.webgl.GL;
class FragmentShader {
public var sources: Array<String>;
public var type: Dynamic;
public var shader: Dynamic;
public var files: Array<String>;
public function new(sources: Array<Blob>, files: Array<String>) {
this.sources = [];
for (source in sources) {
this.sources.push(source.toString());
}
this.type = GL.FRAGMENT_SHADER;
this.shader = null;
this.files = files;
}
public static function fromSource(source: String): FragmentShader {
var shader = new FragmentShader([], ["runtime-string"]);
shader.sources.push(source);
return shader;
}
public function delete(): Void {
SystemImpl.gl.deleteShader(shader);
shader = null;
sources = null;
}
}

View File

@ -0,0 +1,50 @@
package kha.graphics4;
import js.html.webgl.GL;
import kha.arrays.Uint32Array;
import kha.graphics4.Usage;
class IndexBuffer {
public var _data: Uint32Array;
var buffer: Dynamic;
var mySize: Int;
var usage: Usage;
var lockStart: Int = 0;
var lockEnd: Int = 0;
public function new(indexCount: Int, usage: Usage, canRead: Bool = false) {
this.usage = usage;
mySize = indexCount;
buffer = SystemImpl.gl.createBuffer();
_data = new Uint32Array(indexCount);
}
public function delete(): Void {
_data = null;
SystemImpl.gl.deleteBuffer(buffer);
}
public function lock(?start: Int, ?count: Int): Uint32Array {
lockStart = start != null ? start : 0;
lockEnd = count != null ? start + count : mySize;
return _data.subarray(lockStart, lockEnd);
}
public function unlock(?count: Int): Void {
if (count != null)
lockEnd = lockStart + count;
SystemImpl.gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, buffer);
var data = _data.subarray(lockStart, lockEnd);
var glData: Dynamic = SystemImpl.elementIndexUint == null ? new js.lib.Uint16Array(data.buffer) : data;
SystemImpl.gl.bufferData(GL.ELEMENT_ARRAY_BUFFER, glData, usage == Usage.DynamicUsage ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
}
public function set(): Void {
SystemImpl.gl.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, buffer);
}
public function count(): Int {
return mySize;
}
}

View File

@ -0,0 +1,133 @@
package kha.graphics4;
import js.html.webgl.GL;
import kha.graphics4.VertexData;
class PipelineState extends PipelineStateBase {
var program: Dynamic = null;
var textures: Array<String>;
var textureValues: Array<Dynamic>;
public function new() {
super();
textures = new Array<String>();
textureValues = new Array<Dynamic>();
}
public function delete(): Void {
if (program != null) {
SystemImpl.gl.deleteProgram(program);
}
}
public function compile(): Void {
if (program != null) {
SystemImpl.gl.deleteProgram(program);
}
program = SystemImpl.gl.createProgram();
compileShader(vertexShader);
compileShader(fragmentShader);
SystemImpl.gl.attachShader(program, vertexShader.shader);
SystemImpl.gl.attachShader(program, fragmentShader.shader);
var index = 0;
for (structure in inputLayout) {
for (element in structure.elements) {
SystemImpl.gl.bindAttribLocation(program, index, element.name);
if (element.data == VertexData.Float32_4X4) {
index += 4;
}
else {
++index;
}
}
}
SystemImpl.gl.linkProgram(program);
if (!SystemImpl.gl.getProgramParameter(program, GL.LINK_STATUS)) {
var message = "Could not link the shader program:\n" + SystemImpl.gl.getProgramInfoLog(program);
trace("Error: " + message);
throw message;
}
}
public function set(): Void {
SystemImpl.gl.useProgram(program);
for (index in 0...textureValues.length)
SystemImpl.gl.uniform1i(textureValues[index], index);
SystemImpl.gl.colorMask(colorWriteMaskRed, colorWriteMaskGreen, colorWriteMaskBlue, colorWriteMaskAlpha);
}
function compileShader(shader: Dynamic): Void {
if (shader.shader != null)
return;
var s = SystemImpl.gl.createShader(shader.type);
var highp = SystemImpl.gl.getShaderPrecisionFormat(GL.FRAGMENT_SHADER, GL.HIGH_FLOAT);
var highpSupported = highp.precision != 0;
var files: Array<String> = shader.files;
for (i in 0...files.length) {
if (SystemImpl.gl2) {
if (files[i].indexOf("-webgl2") >= 0 || files[i].indexOf("runtime-string") >= 0) {
SystemImpl.gl.shaderSource(s, shader.sources[i]);
break;
}
}
else {
if (!highpSupported && (files[i].indexOf("-relaxed") >= 0 || files[i].indexOf("runtime-string") >= 0)) {
SystemImpl.gl.shaderSource(s, shader.sources[i]);
break;
}
if (highpSupported && (files[i].indexOf("-relaxed") < 0 || files[i].indexOf("runtime-string") >= 0)) {
SystemImpl.gl.shaderSource(s, shader.sources[i]);
break;
}
}
}
SystemImpl.gl.compileShader(s);
if (!SystemImpl.gl.getShaderParameter(s, GL.COMPILE_STATUS)) {
var message = "Could not compile shader:\n" + SystemImpl.gl.getShaderInfoLog(s);
trace("Error: " + message);
throw message;
}
shader.shader = s;
}
public function getConstantLocation(name: String): kha.graphics4.ConstantLocation {
var location = SystemImpl.gl.getUniformLocation(program, name);
if (location == null) {
trace("Warning: Uniform " + name + " not found.");
}
var type = GL.FLOAT;
var count: Int = SystemImpl.gl.getProgramParameter(program, GL.ACTIVE_UNIFORMS);
for (i in 0...count) {
var info = SystemImpl.gl.getActiveUniform(program, i);
if (info.name == name || info.name == name + "[0]") {
type = info.type;
break;
}
}
return new kha.js.graphics4.ConstantLocation(location, type);
}
public function getTextureUnit(name: String): kha.graphics4.TextureUnit {
var index = findTexture(name);
if (index < 0) {
var location = SystemImpl.gl.getUniformLocation(program, name);
if (location == null) {
trace("Warning: Sampler " + name + " not found.");
}
index = textures.length;
textureValues.push(location);
textures.push(name);
}
return new kha.js.graphics4.TextureUnit(index);
}
function findTexture(name: String): Int {
for (index in 0...textures.length) {
if (textures[index] == name)
return index;
}
return -1;
}
}

View File

@ -0,0 +1,206 @@
package kha.graphics4;
import kha.arrays.Float32Array;
import js.html.webgl.GL;
import kha.arrays.ByteArray;
import kha.graphics4.Usage;
import kha.graphics4.VertexStructure;
class VertexBuffer {
public var _data: ByteArray;
var buffer: Dynamic;
var mySize: Int;
var myStride: Int;
var sizes: Array<Int>;
var offsets: Array<Int>;
var types: Array<Int>;
var instanceDataStepRate: Int;
var lockStart: Int = 0;
var lockEnd: Int = 0;
public function new(vertexCount: Int, structure: VertexStructure, usage: Usage, instanceDataStepRate: Int = 0, canRead: Bool = false) {
this.instanceDataStepRate = instanceDataStepRate;
mySize = vertexCount;
myStride = 0;
for (element in structure.elements) {
myStride += VertexStructure.dataByteSize(element.data);
}
buffer = SystemImpl.gl.createBuffer();
_data = ByteArray.make(vertexCount * myStride);
sizes = new Array<Int>();
offsets = new Array<Int>();
types = new Array<Int>();
sizes[structure.elements.length - 1] = 0;
offsets[structure.elements.length - 1] = 0;
types[structure.elements.length - 1] = 0;
var offset = 0;
var index = 0;
for (element in structure.elements) {
var size;
var type;
switch (element.data) {
case Float32_1X:
size = 1;
type = GL.FLOAT;
case Float32_2X:
size = 2;
type = GL.FLOAT;
case Float32_3X:
size = 3;
type = GL.FLOAT;
case Float32_4X:
size = 4;
type = GL.FLOAT;
case Float32_4X4:
size = 4 * 4;
type = GL.FLOAT;
case Int8_1X, Int8_1X_Normalized:
size = 1;
type = GL.BYTE;
case Int8_2X, Int8_2X_Normalized:
size = 2;
type = GL.BYTE;
case Int8_4X, Int8_4X_Normalized:
size = 4;
type = GL.BYTE;
case UInt8_1X, UInt8_1X_Normalized:
size = 1;
type = GL.UNSIGNED_BYTE;
case UInt8_2X, UInt8_2X_Normalized:
size = 2;
type = GL.UNSIGNED_BYTE;
case UInt8_4X, UInt8_4X_Normalized:
size = 4;
type = GL.UNSIGNED_BYTE;
case Int16_1X, Int16_1X_Normalized:
size = 1;
type = GL.SHORT;
case Int16_2X, Int16_2X_Normalized:
size = 2;
type = GL.SHORT;
case Int16_4X, Int16_4X_Normalized:
size = 4;
type = GL.SHORT;
case UInt16_1X, UInt16_1X_Normalized:
size = 1;
type = GL.UNSIGNED_SHORT;
case UInt16_2X, UInt16_2X_Normalized:
size = 2;
type = GL.UNSIGNED_SHORT;
case UInt16_4X, UInt16_4X_Normalized:
size = 4;
type = GL.UNSIGNED_SHORT;
case Int32_1X:
size = 1;
type = GL.INT;
case Int32_2X:
size = 2;
type = GL.INT;
case Int32_3X:
size = 3;
type = GL.INT;
case Int32_4X:
size = 4;
type = GL.INT;
case UInt32_1X:
size = 1;
type = GL.UNSIGNED_INT;
case UInt32_2X:
size = 2;
type = GL.UNSIGNED_INT;
case UInt32_3X:
size = 3;
type = GL.UNSIGNED_INT;
case UInt32_4X:
size = 4;
type = GL.UNSIGNED_INT;
}
sizes[index] = size;
offsets[index] = offset;
types[index] = type;
offset += VertexStructure.dataByteSize(element.data);
++index;
}
SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
SystemImpl.gl.bufferData(GL.ARRAY_BUFFER, _data.subarray(0 * stride(), mySize * stride()),
usage == Usage.DynamicUsage ? GL.DYNAMIC_DRAW : GL.STATIC_DRAW);
}
public function delete(): Void {
_data = null;
SystemImpl.gl.deleteBuffer(buffer);
}
public function lock(?start: Int, ?count: Int): Float32Array {
lockStart = start != null ? start : 0;
lockEnd = count != null ? start + count : mySize;
return _data.subarray(lockStart * stride(), lockEnd * stride());
}
public function unlock(?count: Int): Void {
if (count != null)
lockEnd = lockStart + count;
SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
if (SystemImpl.safari) {
SystemImpl.gl.bufferData(GL.ARRAY_BUFFER, _data.subarray(0 * stride(), lockEnd * stride()), GL.DYNAMIC_DRAW);
}
else {
SystemImpl.gl.bufferSubData(GL.ARRAY_BUFFER, lockStart * stride(), _data.subarray(lockStart * stride(), lockEnd * stride()));
}
}
public function stride(): Int {
return myStride;
}
public function count(): Int {
return mySize;
}
public function set(offset: Int): Int {
var ext: Dynamic = SystemImpl.gl2 ? true : SystemImpl.gl.getExtension("ANGLE_instanced_arrays");
SystemImpl.gl.bindBuffer(GL.ARRAY_BUFFER, buffer);
var attributesOffset = 0;
for (i in 0...sizes.length) {
if (sizes[i] > 4) {
var size = sizes[i];
var addonOffset = 0;
while (size > 0) {
SystemImpl.gl.enableVertexAttribArray(offset + attributesOffset);
SystemImpl.gl.vertexAttribPointer(offset + attributesOffset, 4, GL.FLOAT, false, myStride, offsets[i] + addonOffset);
if (ext) {
if (SystemImpl.gl2) {
untyped SystemImpl.gl.vertexAttribDivisor(offset + attributesOffset, instanceDataStepRate);
}
else {
ext.vertexAttribDivisorANGLE(offset + attributesOffset, instanceDataStepRate);
}
}
size -= 4;
addonOffset += 4 * 4;
++attributesOffset;
}
}
else {
var normalized = types[i] == GL.FLOAT ? false : true;
SystemImpl.gl.enableVertexAttribArray(offset + attributesOffset);
SystemImpl.gl.vertexAttribPointer(offset + attributesOffset, sizes[i], types[i], normalized, myStride, offsets[i]);
if (ext) {
if (SystemImpl.gl2) {
untyped SystemImpl.gl.vertexAttribDivisor(offset + attributesOffset, instanceDataStepRate);
}
else {
ext.vertexAttribDivisorANGLE(offset + attributesOffset, instanceDataStepRate);
}
}
++attributesOffset;
}
}
return attributesOffset;
}
}

View File

@ -0,0 +1,32 @@
package kha.graphics4;
import js.html.webgl.GL;
class VertexShader {
public var sources: Array<String>;
public var type: Dynamic;
public var shader: Dynamic;
public var files: Array<String>;
public function new(sources: Array<Blob>, files: Array<String>) {
this.sources = [];
for (source in sources) {
this.sources.push(source.toString());
}
this.type = GL.VERTEX_SHADER;
this.shader = null;
this.files = files;
}
public static function fromSource(source: String): VertexShader {
var shader = new VertexShader([], ["runtime-string"]);
shader.sources.push(source);
return shader;
}
public function delete(): Void {
SystemImpl.gl.deleteShader(shader);
shader = null;
sources = null;
}
}

View File

@ -0,0 +1,76 @@
package kha.input;
import kha.SystemImpl;
import kha.input.Mouse;
class MouseImpl extends kha.input.Mouse {
public function new() {
super();
}
override public function lock(): Void {
SystemImpl.lockMouse();
}
override public function unlock(): Void {
SystemImpl.unlockMouse();
}
override public function canLock(): Bool {
return SystemImpl.canLockMouse();
}
override public function isLocked(): Bool {
return SystemImpl.isMouseLocked();
}
override public function notifyOnLockChange(func: Void->Void, error: Void->Void): Void {
SystemImpl.notifyOfMouseLockChange(func, error);
}
override public function removeFromLockChange(func: Void->Void, error: Void->Void): Void {
SystemImpl.removeFromMouseLockChange(func, error);
}
override public function hideSystemCursor(): Void {
SystemImpl.khanvas.style.cursor = "none";
}
override public function showSystemCursor(): Void {
SystemImpl.khanvas.style.cursor = "default";
}
override public function setSystemCursor(cursor: MouseCursor): Void {
SystemImpl.khanvas.style.cursor = switch (cursor) {
case Default: "default";
case Pointer: "pointer";
case Text: "text";
case EastWestResize: "ew-resize";
case NorthSouthResize: "ns-resize";
case NorthEastResize: "ne-resize";
case SouthEastResize: "se-resize";
case NorthWestResize: "nw-resize";
case SouthWestResize: "sw-resize";
case Grab: "grab";
case Grabbing: "grabbing";
case NotAllowed: "not-allowed";
case Wait: "wait";
case Crosshair: "crosshair";
case Custom(image):
var canvas = js.Browser.document.createCanvasElement();
canvas.width = image.width;
canvas.height = image.height;
if (Std.isOfType(image, WebGLImage)) {
canvas.getContext2d().drawImage(cast(image, WebGLImage).image, 0, 0);
}
else {
canvas.getContext2d().drawImage(cast(image, CanvasImage).image, 0, 0);
}
var dataURL = canvas.toDataURL("image/png");
dataURL = StringTools.replace(dataURL, "/^data:image\\/(png|jpg);base64,/", "");
'url(\'$dataURL\'),auto';
default: "default";
}
}
}

View File

@ -0,0 +1,37 @@
package kha.input;
import kha.SystemImpl;
class Sensor {
static var isInited: Bool = false;
static var accelerometer: Sensor = new Sensor();
static var gyroscope: Sensor = new Sensor();
var listeners: Array<Float->Float->Float->Void> = new Array();
public static function get(type: SensorType): Sensor {
switch (type) {
case Accelerometer:
return accelerometer;
case Gyroscope:
return gyroscope;
}
}
public function notify(listener: Float->Float->Float->Void): Void {
if (!isInited) {
SystemImpl.initSensor();
isInited = true;
}
listeners.push(listener);
}
function new() {}
public static function _changed(type: Int, x: Float, y: Float, z: Float): Void {
var sensor = get(type == 0 ? SensorType.Accelerometer : SensorType.Gyroscope);
for (listener in sensor.listeners) {
listener(x, y, z);
}
}
}

View File

@ -0,0 +1,77 @@
package kha.js;
import js.html.AudioElement;
import kha.audio1.AudioChannel;
class AEAudioChannel implements kha.audio1.AudioChannel {
var element: AudioElement;
var stopped = false;
var looping: Bool;
public function new(element: AudioElement, looping: Bool) {
this.element = element;
this.looping = looping;
}
public function play(): Void {
stopped = false;
element.play();
}
public function pause(): Void {
try {
element.pause();
}
catch (e:Dynamic) {
trace(e);
}
}
public function stop(): Void {
try {
element.pause();
element.currentTime = 0;
stopped = true;
}
catch (e:Dynamic) {
trace(e);
}
}
public var length(get, never): Float; // Seconds
function get_length(): Float {
if (Math.isFinite(element.duration)) {
return element.duration;
}
else {
return Math.POSITIVE_INFINITY;
}
}
public var position(get, set): Float; // Seconds
function get_position(): Float {
return element.currentTime;
}
function set_position(value: Float): Float {
return element.currentTime = value;
}
public var volume(get, set): Float;
function get_volume(): Float {
return element.volume;
}
function set_volume(value: Float): Float {
return element.volume = value;
}
public var finished(get, never): Bool;
function get_finished(): Bool {
return stopped || (!looping && position >= length);
}
}

View File

@ -0,0 +1,15 @@
package kha.js;
@:keep
class AudioElementAudio {
public static function play(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
return stream(sound, loop);
}
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
sound.element.loop = loop;
var channel = new AEAudioChannel(sound.element, loop);
channel.play();
return cast channel;
}
}

View File

@ -0,0 +1,264 @@
package kha.js;
import kha.Color;
import kha.graphics2.Graphics;
import kha.graphics2.ImageScaleQuality;
import kha.math.FastMatrix3;
import js.html.CanvasRenderingContext2D;
class CanvasGraphics extends Graphics {
var canvas: CanvasRenderingContext2D;
var webfont: kha.js.Font;
var myColor: Color;
var scaleQuality: ImageScaleQuality;
var clipping: Bool = false;
static var instance: CanvasGraphics;
public function new(canvas: CanvasRenderingContext2D) {
super();
this.canvas = canvas;
instance = this;
myColor = Color.fromBytes(0, 0, 0);
// webfont = new Font("Arial", new FontStyle(false, false, false), 12);
// canvas.globalCompositeOperation = "normal";
}
public static function stringWidth(font: kha.Font, text: String): Float {
if (instance == null)
return 5 * text.length;
else {
instance.font = font;
return instance.canvas.measureText(text).width;
}
}
override public function begin(clear: Bool = true, clearColor: Color = null): Void {
if (clear)
this.clear(clearColor);
}
override public function clear(color: Color = null): Void {
if (color == null)
color = 0x00000000;
canvas.strokeStyle = "rgba(" + color.Rb + "," + color.Gb + "," + color.Bb + "," + color.A + ")";
canvas.fillStyle = "rgba(" + color.Rb + "," + color.Gb + "," + color.Bb + "," + color.A + ")";
if (color.A == 0) // if color is transparent, clear the screen. Note: in Canvas, transparent colors will overlay, not overwrite.
canvas.clearRect(0, 0, canvas.canvas.width, canvas.canvas.height);
else
canvas.fillRect(0, 0, canvas.canvas.width, canvas.canvas.height);
this.color = myColor;
}
override public function end(): Void {}
/*override public function translate(x: Float, y: Float) {
tx = x;
ty = y;
}*/
override public function drawImage(img: kha.Image, x: Float, y: Float) {
canvas.globalAlpha = opacity;
canvas.drawImage(cast(img, CanvasImage).image, x, y);
canvas.globalAlpha = 1;
}
override public function drawScaledSubImage(image: kha.Image, sx: Float, sy: Float, sw: Float, sh: Float, dx: Float, dy: Float, dw: Float, dh: Float) {
canvas.globalAlpha = opacity;
try {
if (dw < 0 || dh < 0) {
canvas.save();
canvas.translate(dx, dy);
var x = 0.0;
var y = 0.0;
if (dw < 0) {
canvas.scale(-1, 1);
x = -dw;
}
if (dh < 0) {
canvas.scale(1, -1);
y = -dh;
}
canvas.drawImage(cast(image, CanvasImage).image, sx, sy, sw, sh, x, y, dw, dh);
canvas.restore();
}
else {
canvas.drawImage(cast(image, CanvasImage).image, sx, sy, sw, sh, dx, dy, dw, dh);
}
}
catch (ex:Dynamic) {}
canvas.globalAlpha = 1;
}
override function set_color(color: Color): Color {
myColor = color;
canvas.strokeStyle = "rgba(" + color.Rb + "," + color.Gb + "," + color.Bb + "," + color.A + ")";
canvas.fillStyle = "rgba(" + color.Rb + "," + color.Gb + "," + color.Bb + "," + color.A + ")";
return color;
}
override function get_color(): Color {
return myColor;
}
override function get_imageScaleQuality(): ImageScaleQuality {
return scaleQuality;
}
override function set_imageScaleQuality(value: ImageScaleQuality): ImageScaleQuality {
if (value == ImageScaleQuality.Low) {
untyped canvas.mozImageSmoothingEnabled = false;
untyped canvas.webkitImageSmoothingEnabled = false;
untyped canvas.msImageSmoothingEnabled = false;
canvas.imageSmoothingEnabled = false;
}
else {
untyped canvas.mozImageSmoothingEnabled = true;
untyped canvas.webkitImageSmoothingEnabled = true;
untyped canvas.msImageSmoothingEnabled = true;
canvas.imageSmoothingEnabled = true;
}
return scaleQuality = value;
}
override public function drawRect(x: Float, y: Float, width: Float, height: Float, strength: Float = 1.0) {
canvas.beginPath();
var oldStrength = canvas.lineWidth;
canvas.lineWidth = Math.round(strength);
canvas.rect(x, y, width, height);
canvas.stroke();
canvas.lineWidth = oldStrength;
}
override public function fillRect(x: Float, y: Float, width: Float, height: Float) {
canvas.globalAlpha = opacity * myColor.A;
canvas.fillRect(x, y, width, height);
canvas.globalAlpha = opacity;
}
public function drawArc(cx: Float, cy: Float, radius: Float, sAngle: Float, eAngle: Float, strength: Float = 1.0, ccw: Bool = false) {
_drawArc(cx, cy, radius, sAngle, eAngle, strength, ccw);
}
public function drawCircle(cx: Float, cy: Float, radius: Float, strength: Float = 1.0) {
_drawArc(cx, cy, radius, 0, 2 * Math.PI, strength, false);
}
inline function _drawArc(cx: Float, cy: Float, radius: Float, sAngle: Float, eAngle: Float, strength: Float, ccw: Bool) {
canvas.beginPath();
var oldStrength = canvas.lineWidth;
canvas.lineWidth = Math.round(strength);
canvas.arc(cx, cy, radius, sAngle, eAngle, ccw);
canvas.stroke();
canvas.lineWidth = oldStrength;
}
public function fillArc(cx: Float, cy: Float, radius: Float, sAngle: Float, eAngle: Float, ccw: Bool = false) {
canvas.beginPath();
canvas.arc(cx, cy, radius, sAngle, eAngle, ccw);
canvas.fill();
}
public function fillCircle(cx: Float, cy: Float, radius: Float) {
canvas.beginPath();
canvas.arc(cx, cy, radius, 0, 2 * Math.PI, false);
canvas.fill();
}
var bakedQuadCache = new kha.Kravur.AlignedQuad();
override public function drawString(text: String, x: Float, y: Float) {
// canvas.fillText(text, tx + x, ty + y + webfont.getHeight());
// canvas.drawImage(cast(webfont.getTexture(), Image).image, 0, 0, 50, 50, tx + x, ty + y, 50, 50);
var image = webfont.getImage(fontSize, myColor);
if (image.width > 0) {
// the image created in getImage() is not imediately useable
var xpos = x;
var ypos = y;
for (i in 0...text.length) {
var q = webfont.kravur._get(fontSize).getBakedQuad(bakedQuadCache, kha.graphics2.Graphics.fontGlyphs.indexOf(text.charCodeAt(i)), xpos, ypos);
if (q != null) {
if (q.s1 - q.s0 > 0 && q.t1 - q.t0 > 0 && q.x1 - q.x0 > 0 && q.y1 - q.y0 > 0)
canvas.drawImage(image, q.s0 * image.width, q.t0 * image.height, (q.s1 - q.s0) * image.width, (q.t1 - q.t0) * image.height, q.x0,
q.y0, q.x1 - q.x0, q.y1 - q.y0);
xpos += q.xadvance;
}
}
}
}
override public function drawCharacters(text: Array<Int>, start: Int, length: Int, x: Float, y: Float): Void {
var image = webfont.getImage(fontSize, myColor);
if (image.width > 0) {
// the image created in getImage() is not imediately useable
var xpos = x;
var ypos = y;
for (i in start...start + length) {
var q = webfont.kravur._get(fontSize).getBakedQuad(bakedQuadCache, kha.graphics2.Graphics.fontGlyphs.indexOf(text[i]), xpos, ypos);
if (q != null) {
if (q.s1 - q.s0 > 0 && q.t1 - q.t0 > 0 && q.x1 - q.x0 > 0 && q.y1 - q.y0 > 0)
canvas.drawImage(image, q.s0 * image.width, q.t0 * image.height, (q.s1 - q.s0) * image.width, (q.t1 - q.t0) * image.height, q.x0,
q.y0, q.x1 - q.x0, q.y1 - q.y0);
xpos += q.xadvance;
}
}
}
}
override function set_font(font: kha.Font): kha.Font {
webfont = cast(font, kha.js.Font);
// canvas.font = webfont.size + "px " + webfont.name;
return cast webfont;
}
override function get_font(): kha.Font {
return cast webfont;
}
override public function drawLine(x1: Float, y1: Float, x2: Float, y2: Float, strength: Float = 1.0) {
canvas.beginPath();
var oldWith = canvas.lineWidth;
canvas.lineWidth = Math.round(strength);
canvas.moveTo(x1, y1);
canvas.lineTo(x2, y2);
canvas.moveTo(0, 0);
canvas.stroke();
canvas.lineWidth = oldWith;
}
override public function fillTriangle(x1: Float, y1: Float, x2: Float, y2: Float, x3: Float, y3: Float) {
canvas.beginPath();
canvas.moveTo(x1, y1);
canvas.lineTo(x2, y2);
canvas.lineTo(x3, y3);
canvas.closePath();
canvas.fill();
}
override public function scissor(x: Int, y: Int, width: Int, height: Int): Void {
if (!clipping) {
canvas.save();
clipping = true;
}
canvas.beginPath();
canvas.rect(x, y, width, height);
canvas.clip();
}
override public function disableScissor(): Void {
if (clipping) {
canvas.restore();
clipping = false;
}
}
override public function drawVideo(video: kha.Video, x: Float, y: Float, width: Float, height: Float): Void {
canvas.drawImage(cast(video, Video).element, x, y, width, height);
}
override public function setTransformation(transformation: FastMatrix3): Void {
canvas.setTransform(transformation._00, transformation._01, transformation._10, transformation._11, transformation._20, transformation._21);
}
}

View File

@ -0,0 +1,77 @@
package kha.js;
import js.Syntax;
import haxe.io.Bytes;
import js.Browser;
import js.html.ImageElement;
import kha.Color;
import kha.Kravur;
@:keepInit
class Font implements Resource {
public var kravur: Kravur;
var images: Map<Int, Map<Int, ImageElement>> = new Map();
public function new(blob: Blob) {
this.kravur = Syntax.code("new kha_js_Font.Kravur(blob);");
}
public static function fromBytes(bytes: Bytes): Font {
return new Font(Blob.fromBytes(bytes));
}
public function height(fontSize: Int): Float {
return kravur._get(fontSize).getHeight();
}
public function width(fontSize: Int, str: String): Float {
return kravur._get(fontSize).stringWidth(str);
}
public function widthOfCharacters(fontSize: Int, characters: Array<Int>, start: Int, length: Int): Float {
return kravur._get(fontSize).charactersWidth(characters, start, length);
}
public function baseline(fontSize: Int): Float {
return kravur._get(fontSize).getBaselinePosition();
}
public function getImage(fontSize: Int, color: Color): ImageElement {
var glyphs = kha.graphics2.Graphics.fontGlyphs;
var imageIndex = fontSize * 10000 + glyphs.length;
if (!images.exists(imageIndex)) {
images[imageIndex] = new Map();
}
if (!images[imageIndex].exists(color.value)) {
var kravur = this.kravur._get(fontSize);
var canvas = Browser.document.createCanvasElement();
canvas.width = kravur.width;
canvas.height = kravur.height;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.fillRect(0, 0, kravur.width, kravur.height);
var imageData = ctx.getImageData(0, 0, kravur.width, kravur.height);
var bytes = cast(kravur.getTexture(), CanvasImage).bytes;
for (i in 0...bytes.length) {
imageData.data[i * 4 + 0] = color.Rb;
imageData.data[i * 4 + 1] = color.Gb;
imageData.data[i * 4 + 2] = color.Bb;
imageData.data[i * 4 + 3] = bytes.get(i);
}
ctx.putImageData(imageData, 0, 0);
var img = Browser.document.createImageElement();
img.src = canvas.toDataURL("image/png");
images[imageIndex][color.value] = img;
return img;
}
return images[imageIndex][color.value];
}
public function unload(): Void {
kravur = null;
images = null;
}
}

View File

@ -0,0 +1,32 @@
package kha.js;
import js.Syntax;
import js.html.audio.AudioContext;
@:keep
class MobileWebAudio {
@:noCompletion public static var _context: AudioContext;
@:noCompletion public static function _init(): Void {
try {
_context = new AudioContext();
return;
}
catch (e:Dynamic) {}
try {
Syntax.code("this._context = new webkitAudioContext();");
return;
}
catch (e:Dynamic) {}
}
public static function play(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
var channel = new MobileWebAudioChannel(cast sound, loop);
channel.play();
return channel;
}
public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
return play(sound, loop);
}
}

View File

@ -0,0 +1,105 @@
package kha.js;
import js.html.audio.AudioBuffer;
import js.html.audio.AudioBufferSourceNode;
import js.html.audio.GainNode;
class MobileWebAudioChannel implements kha.audio1.AudioChannel {
var buffer: AudioBuffer;
var loop: Bool;
var source: AudioBufferSourceNode;
var gain: GainNode;
var startTime: Float;
var pauseTime: Float;
var paused: Bool = false;
var stopped: Bool = false;
public function new(sound: MobileWebAudioSound, loop: Bool) {
this.buffer = sound._buffer;
this.loop = loop;
createSource();
}
function createSource(): Void {
source = MobileWebAudio._context.createBufferSource();
source.loop = loop;
source.buffer = buffer;
source.onended = function() {
stopped = true;
}
gain = MobileWebAudio._context.createGain();
source.connect(gain);
gain.connect(MobileWebAudio._context.destination);
}
public function play(): Void {
if (paused || stopped) {
createSource();
}
stopped = false;
if (paused) {
paused = false;
startTime = MobileWebAudio._context.currentTime - pauseTime;
source.start(0, pauseTime);
}
else {
startTime = MobileWebAudio._context.currentTime;
source.start();
}
}
public function pause(): Void {
final wasStopped = paused || stopped;
pauseTime = MobileWebAudio._context.currentTime - startTime;
paused = true;
if (wasStopped)
return;
source.stop();
}
public function stop(): Void {
final wasStopped = paused || stopped;
paused = false;
stopped = true;
if (wasStopped)
return;
source.stop();
}
public var length(get, never): Float; // Seconds
function get_length(): Float {
return source.buffer.duration;
}
public var position(get, set): Float; // Seconds
function get_position(): Float {
if (stopped)
return length;
if (paused)
return pauseTime;
else
return MobileWebAudio._context.currentTime - startTime;
}
function set_position(value: Float): Float {
return value;
}
public var volume(get, set): Float;
function get_volume(): Float {
return gain.gain.value;
}
function set_volume(value: Float): Float {
return gain.gain.value = value;
}
public var finished(get, never): Bool;
function get_finished(): Bool {
return stopped;
}
}

View File

@ -0,0 +1,37 @@
package kha.js;
import haxe.io.Bytes;
import js.html.XMLHttpRequest;
class MobileWebAudioSound extends kha.Sound {
public var _buffer: Dynamic;
public function new(filename: String, done: kha.Sound->Void, failed: AssetError->Void) {
super();
var request = untyped new XMLHttpRequest();
request.open("GET", filename, true);
request.responseType = "arraybuffer";
request.onerror = function() {
failed({url: filename});
};
request.onload = function() {
compressedData = Bytes.ofData(request.response);
uncompressedData = null;
MobileWebAudio._context.decodeAudioData(compressedData.getData(), function(buffer) {
length = buffer.duration;
channels = buffer.numberOfChannels;
_buffer = buffer;
done(this);
}, function() {
failed({url: filename, error: "Audio format not supported"});
});
};
request.send(null);
}
override public function uncompress(done: Void->Void): Void {
done();
}
}

View File

@ -0,0 +1,132 @@
package kha.js;
import js.Browser;
import js.html.AudioElement;
import js.html.ErrorEvent;
import js.html.Event;
import js.html.MediaError;
using StringTools;
/*class SoundChannel extends kha.SoundChannel {
private var element: Dynamic;
public function new(element: Dynamic) {
super();
this.element = element;
}
override public function play(): Void {
super.play();
element.play();
}
override public function pause(): Void {
try {
element.pause();
}
catch (e: Dynamic) {
trace(e);
}
}
override public function stop(): Void {
try {
element.pause();
element.currentTime = 0;
super.stop();
}
catch (e: Dynamic) {
trace(e);
}
}
override public function getCurrentPos(): Int {
return Math.ceil(element.currentTime * 1000); // Miliseconds
}
override public function getLength(): Int {
if (Math.isFinite(element.duration)) {
return Math.floor(element.duration * 1000); // Miliseconds
}
else {
return -1;
}
}
}*/
class Sound extends kha.Sound {
var filenames: Array<String>;
static var loading: Array<Sound> = new Array();
var done: kha.Sound->Void;
var failed: AssetError->Void;
public var element: AudioElement;
public function new(filenames: Array<String>, done: kha.Sound->Void, failed: AssetError->Void) {
super();
this.done = done;
this.failed = failed;
loading.push(this); // prevent gc from removing this
element = Browser.document.createAudioElement();
this.filenames = [];
for (filename in filenames) {
if (element.canPlayType("audio/ogg") != "" && filename.endsWith(".ogg"))
this.filenames.push(filename);
if (element.canPlayType("audio/mp4") != "" && filename.endsWith(".mp4"))
this.filenames.push(filename);
if (element.canPlayType("audio/wav") != "" && filename.endsWith(".wav"))
this.filenames.push(filename);
}
element.addEventListener("error", errorListener, false);
element.addEventListener("canplay", canPlayThroughListener, false);
element.src = this.filenames[0];
element.preload = "auto";
element.load();
}
// override public function play(): kha.SoundChannel {
// try {
// element.play();
// }
// catch (e: Dynamic) {
// trace(e);
// }
// return new SoundChannel(element);
// }
function errorListener(eventInfo: ErrorEvent): Void {
if (element.error.code == MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) {
for (i in 0...filenames.length - 1) {
if (element.src == filenames[i]) {
// try loading with next extension:
element.src = filenames[i + 1];
return;
}
}
}
failed({url: element.src});
finishAsset();
}
function canPlayThroughListener(eventInfo: Event): Void {
finishAsset();
}
function finishAsset() {
element.removeEventListener("error", errorListener, false);
element.removeEventListener("canplaythrough", canPlayThroughListener, false);
done(this);
loading.remove(this);
}
override public function uncompress(done: Void->Void): Void {
done();
}
}

View File

@ -0,0 +1,147 @@
package kha.js;
import js.Browser;
import js.html.ErrorEvent;
import js.html.Event;
import js.html.MediaError;
import js.html.VideoElement;
using StringTools;
class Video extends kha.Video {
public var element: VideoElement;
public var texture: Image;
var filenames: Array<String>;
var done: kha.Video->Void;
function new() {
super();
}
public static function fromElement(element: js.html.VideoElement): Video {
var video = new Video();
video.element = element;
if (SystemImpl.gl != null)
video.texture = Image.fromVideo(video);
return video;
}
public static function fromFile(filenames: Array<String>, done: kha.Video->Void): Void {
var video = new Video();
video.done = done;
video.element = cast Browser.document.createElement("video");
video.filenames = [];
for (filename in filenames) {
if (video.element.canPlayType("video/webm") != "" && filename.endsWith(".webm"))
video.filenames.push(filename);
#if !kha_debug_html5
if (video.element.canPlayType("video/mp4") != "" && filename.endsWith(".mp4"))
video.filenames.push(filename);
#end
}
video.element.addEventListener("error", video.errorListener, false);
video.element.addEventListener("canplaythrough", video.canPlayThroughListener, false);
video.element.preload = "auto";
video.element.src = video.filenames[0];
}
override public function width(): Int {
return element.videoWidth;
}
override public function height(): Int {
return element.videoHeight;
}
override public function play(loop: Bool = false): Void {
try {
element.loop = loop;
element.play();
}
catch (e:Dynamic) {
trace(e);
}
}
override public function pause(): Void {
try {
element.pause();
}
catch (e:Dynamic) {
trace(e);
}
}
override public function stop(): Void {
try {
element.pause();
element.currentTime = 0;
}
catch (e:Dynamic) {
trace(e);
}
}
override public function getCurrentPos(): Int {
return Math.ceil(element.currentTime * 1000); // Miliseconds
}
override function get_position(): Int {
return Math.ceil(element.currentTime * 1000);
}
override function set_position(value: Int): Int {
element.currentTime = value / 1000;
return value;
}
override public function getVolume(): Float {
return element.volume;
}
override public function setVolume(volume: Float): Void {
element.volume = volume;
}
override public function getLength(): Int {
if (Math.isFinite(element.duration)) {
return Math.floor(element.duration * 1000); // Miliseconds
}
else {
return -1;
}
}
function errorListener(eventInfo: ErrorEvent): Void {
if (element.error.code == MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) {
for (i in 0...filenames.length - 1) {
if (element.src == filenames[i]) {
// try loading with next extension:
element.src = filenames[i + 1];
return;
}
}
}
trace("Error loading " + element.src);
finishAsset();
}
function canPlayThroughListener(eventInfo: Event): Void {
finishAsset();
}
function finishAsset() {
element.removeEventListener("error", errorListener, false);
element.removeEventListener("canplaythrough", canPlayThroughListener, false);
if (SystemImpl.gl != null)
texture = Image.fromVideo(this);
done(this);
}
}

View File

@ -0,0 +1,114 @@
package kha.js;
import haxe.io.Bytes;
import js.Browser;
import js.html.XMLHttpRequest;
import kha.audio2.Audio;
/*
class WebAudioChannel extends kha.SoundChannel {
private var buffer: Dynamic;
private var startTime: Float;
private var offset: Float;
private var source: Dynamic;
public function new(buffer: Dynamic) {
super();
this.offset = 0;
this.buffer = buffer;
this.startTime = Audio._context.currentTime;
this.source = Audio._context.createBufferSource();
this.source.buffer = this.buffer;
this.source.connect(Audio._context.destination);
this.source.start(0);
}
override public function play(): Void {
if (source != null) return;
super.play();
startTime = Audio._context.currentTime - offset;
source.start(0, offset);
}
override public function pause(): Void {
source.stop();
offset = Audio._context.currentTime - startTime;
startTime = -1;
source = null;
}
override public function stop(): Void {
source.stop();
source = null;
offset = 0;
startTime = -1;
super.stop();
}
override public function getCurrentPos(): Int {
if (startTime < 0) return Math.ceil(offset * 1000);
else return Math.ceil((Audio._context.currentTime - startTime) * 1000); //Miliseconds
}
override public function getLength(): Int {
return Math.floor(buffer.duration * 1000); //Miliseconds
}
}
*/
class WebAudioSound extends kha.Sound {
public function new(filename: String, done: kha.Sound->Void, failed: AssetError->Void) {
super();
var request = untyped new XMLHttpRequest();
request.open("GET", filename, true);
request.responseType = "arraybuffer";
request.onerror = function() {
failed({url: filename});
};
request.onload = function() {
compressedData = Bytes.ofData(request.response);
uncompressedData = null;
done(this);
};
request.send(null);
}
function superUncompress(done: Void->Void): Void {
super.uncompress(done);
}
override public function uncompress(done: Void->Void): Void {
Audio._context.decodeAudioData(compressedData.getData(), function(buffer: js.html.audio.AudioBuffer) {
final ch0 = buffer.getChannelData(0);
final ch1 = buffer.numberOfChannels == 1 ? ch0 : buffer.getChannelData(1);
final len = ch0.length;
uncompressedData = new kha.arrays.Float32Array(len * 2);
length = buffer.duration;
channels = buffer.numberOfChannels;
sampleRate = Math.round(buffer.sampleRate);
var idx = 0;
var i = 0;
final lidx = len * 2;
function uncompressInner() {
var chk_len = idx + 11025;
var next_chk = chk_len > lidx ? lidx : chk_len;
while (idx < next_chk) {
uncompressedData[idx] = ch0[i];
uncompressedData[idx + 1] = ch1[i];
idx += 2;
++i;
}
if (idx < lidx)
js.Browser.window.setTimeout(uncompressInner, 0);
else {
compressedData = null;
done();
}
};
uncompressInner();
}, function() {
superUncompress(done);
});
}
}

View File

@ -0,0 +1,11 @@
package kha.js.graphics4;
class ConstantLocation implements kha.graphics4.ConstantLocation {
public var value: Dynamic;
public var type: Int;
public function new(value: Dynamic, type: Int) {
this.value = value;
this.type = type;
}
}

View File

@ -0,0 +1,738 @@
package kha.js.graphics4;
import js.html.webgl.GL2;
import kha.graphics4.StencilValue;
import kha.arrays.Float32Array;
import kha.arrays.Int32Array;
import js.html.webgl.GL;
import kha.graphics4.BlendingFactor;
import kha.graphics4.BlendingOperation;
import kha.graphics4.CompareMode;
import kha.graphics4.CubeMap;
import kha.graphics4.CullMode;
import kha.graphics4.IndexBuffer;
import kha.graphics4.MipMapFilter;
import kha.graphics4.PipelineState;
import kha.graphics4.StencilAction;
import kha.graphics4.TextureAddressing;
import kha.graphics4.TextureFilter;
import kha.graphics4.Usage;
import kha.graphics4.VertexBuffer;
import kha.graphics4.VertexStructure;
import kha.Image;
import kha.math.FastMatrix3;
import kha.math.FastMatrix4;
import kha.math.FastVector2;
import kha.math.FastVector3;
import kha.math.FastVector4;
import kha.WebGLImage;
class Graphics implements kha.graphics4.Graphics {
var currentPipeline: PipelineState = null;
var depthTest: Bool = false;
var depthMask: Bool = false;
var colorMaskRed: Bool = true;
var colorMaskGreen: Bool = true;
var colorMaskBlue: Bool = true;
var colorMaskAlpha: Bool = true;
var indicesCount: Int;
var renderTarget: Canvas;
var renderTargetFrameBuffer: Dynamic;
var renderTargetMSAA: Dynamic;
var renderTargetTexture: Dynamic;
var isCubeMap: Bool = false;
var isDepthAttachment: Bool = false;
var instancedExtension: Dynamic;
var blendMinMaxExtension: Dynamic;
static var current: Graphics = null;
static var useVertexAttributes: Int = 0;
public function new(renderTarget: Canvas = null) {
this.renderTarget = renderTarget;
init();
if (SystemImpl.gl2) {
instancedExtension = true;
}
else {
instancedExtension = SystemImpl.gl.getExtension("ANGLE_instanced_arrays");
blendMinMaxExtension = SystemImpl.gl.getExtension("EXT_blend_minmax");
}
}
function init() {
if (renderTarget == null)
return;
isCubeMap = Std.isOfType(renderTarget, CubeMap);
if (isCubeMap) {
var cubeMap: CubeMap = cast(renderTarget, CubeMap);
renderTargetFrameBuffer = cubeMap.frameBuffer;
renderTargetTexture = cubeMap.texture;
isDepthAttachment = cubeMap.isDepthAttachment;
}
else {
var image: WebGLImage = cast(renderTarget, WebGLImage);
renderTargetFrameBuffer = image.frameBuffer;
renderTargetMSAA = image.MSAAFrameBuffer;
renderTargetTexture = image.texture;
}
}
public function begin(additionalRenderTargets: Array<Canvas> = null): Void {
if (current == null) {
current = this;
}
else {
throw "End before you begin";
}
SystemImpl.gl.enable(GL.BLEND);
SystemImpl.gl.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
if (renderTarget == null) {
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
SystemImpl.gl.viewport(0, 0, System.windowWidth(), System.windowHeight());
}
else {
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, renderTargetFrameBuffer);
// if (isCubeMap) SystemImpl.gl.framebufferTexture(GL.FRAMEBUFFER, GL.COLOR_ATTACHMENT0, GL.TEXTURE_CUBE_MAP, renderTargetTexture, 0); // Layered
SystemImpl.gl.viewport(0, 0, renderTarget.width, renderTarget.height);
if (additionalRenderTargets != null) {
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, SystemImpl.drawBuffers.COLOR_ATTACHMENT0_WEBGL, GL.TEXTURE_2D, renderTargetTexture, 0);
for (i in 0...additionalRenderTargets.length) {
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, SystemImpl.drawBuffers.COLOR_ATTACHMENT0_WEBGL + i + 1, GL.TEXTURE_2D,
cast(additionalRenderTargets[i], WebGLImage).texture, 0);
}
var attachments = [SystemImpl.drawBuffers.COLOR_ATTACHMENT0_WEBGL];
for (i in 0...additionalRenderTargets.length) {
attachments.push(SystemImpl.drawBuffers.COLOR_ATTACHMENT0_WEBGL + i + 1);
}
SystemImpl.gl2 ? untyped SystemImpl.gl.drawBuffers(attachments) : SystemImpl.drawBuffers.drawBuffersWEBGL(attachments);
}
}
}
public function beginFace(face: Int): Void {
if (current == null) {
current = this;
}
else {
throw "End before you begin";
}
SystemImpl.gl.enable(GL.BLEND);
SystemImpl.gl.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, renderTargetFrameBuffer);
SystemImpl.gl.framebufferTexture2D(GL.FRAMEBUFFER, isDepthAttachment ? GL.DEPTH_ATTACHMENT : GL.COLOR_ATTACHMENT0,
GL.TEXTURE_CUBE_MAP_POSITIVE_X + face, renderTargetTexture, 0);
SystemImpl.gl.viewport(0, 0, renderTarget.width, renderTarget.height);
}
public function beginEye(eye: Int): Void {
if (current == null) {
current = this;
}
else {
throw "End before you begin";
}
SystemImpl.gl.enable(GL.BLEND);
SystemImpl.gl.blendFunc(GL.SRC_ALPHA, GL.ONE_MINUS_SRC_ALPHA);
SystemImpl.gl.bindFramebuffer(GL.FRAMEBUFFER, null);
if (eye == 0) {
SystemImpl.gl.viewport(0, 0, Std.int(System.windowWidth() * 0.5), System.windowHeight());
}
else {
SystemImpl.gl.viewport(Std.int(System.windowWidth() * 0.5), 0, Std.int(System.windowWidth() * 0.5), System.windowHeight());
}
}
public function end(): Void {
if (current == this) {
current = null;
}
else {
throw "Begin before you end";
}
if (renderTargetMSAA != null) {
untyped SystemImpl.gl.bindFramebuffer(SystemImpl.gl.READ_FRAMEBUFFER, renderTargetFrameBuffer);
untyped SystemImpl.gl.bindFramebuffer(SystemImpl.gl.DRAW_FRAMEBUFFER, renderTargetMSAA);
untyped SystemImpl.gl.blitFramebuffer(0, 0, renderTarget.width, renderTarget.height, 0, 0, renderTarget.width, renderTarget.height,
GL.COLOR_BUFFER_BIT, GL.NEAREST);
}
#if (debug || kha_debug_html5)
var error = SystemImpl.gl.getError();
switch (error) {
case GL.NO_ERROR:
case GL.INVALID_ENUM:
trace("WebGL error: Invalid enum");
case GL.INVALID_VALUE:
trace("WebGL error: Invalid value");
case GL.INVALID_OPERATION:
trace("WebGL error: Invalid operation");
case GL.INVALID_FRAMEBUFFER_OPERATION:
trace("WebGL error: Invalid framebuffer operation");
case GL.OUT_OF_MEMORY:
trace("WebGL error: Out of memory");
case GL.CONTEXT_LOST_WEBGL:
trace("WebGL error: Context lost");
default:
trace("Unknown WebGL error");
}
#end
}
public function flush(): Void {}
public function vsynced(): Bool {
return true;
}
public function refreshRate(): Int {
return 60;
}
public function clear(?color: Color, ?depth: Float, ?stencil: Int): Void {
var clearMask: Int = 0;
if (color != null) {
clearMask |= GL.COLOR_BUFFER_BIT;
SystemImpl.gl.colorMask(true, true, true, true);
SystemImpl.gl.clearColor(color.R, color.G, color.B, color.A);
}
if (depth != null) {
clearMask |= GL.DEPTH_BUFFER_BIT;
SystemImpl.gl.enable(GL.DEPTH_TEST);
SystemImpl.gl.depthMask(true);
SystemImpl.gl.clearDepth(depth);
}
if (stencil != null) {
clearMask |= GL.STENCIL_BUFFER_BIT;
SystemImpl.gl.enable(GL.STENCIL_TEST);
SystemImpl.gl.stencilMask(0xff);
SystemImpl.gl.clearStencil(stencil);
}
SystemImpl.gl.clear(clearMask);
SystemImpl.gl.colorMask(colorMaskRed, colorMaskGreen, colorMaskBlue, colorMaskAlpha);
if (depthTest) {
SystemImpl.gl.enable(GL.DEPTH_TEST);
}
else {
SystemImpl.gl.disable(GL.DEPTH_TEST);
}
SystemImpl.gl.depthMask(depthMask);
}
public function viewport(x: Int, y: Int, width: Int, height: Int): Void {
if (renderTarget == null) {
SystemImpl.gl.viewport(x, System.windowHeight(0) - y - height, width, height);
}
else {
SystemImpl.gl.viewport(x, y, width, height);
}
}
public function scissor(x: Int, y: Int, width: Int, height: Int): Void {
SystemImpl.gl.enable(GL.SCISSOR_TEST);
if (renderTarget == null) {
SystemImpl.gl.scissor(x, System.windowHeight(0) - y - height, width, height);
}
else {
SystemImpl.gl.scissor(x, y, width, height);
}
}
public function disableScissor(): Void {
SystemImpl.gl.disable(GL.SCISSOR_TEST);
}
public function setDepthMode(write: Bool, mode: CompareMode): Void {
switch (mode) {
case Always:
write ? SystemImpl.gl.enable(GL.DEPTH_TEST) : SystemImpl.gl.disable(GL.DEPTH_TEST);
depthTest = write;
SystemImpl.gl.depthFunc(GL.ALWAYS);
case Never:
SystemImpl.gl.enable(GL.DEPTH_TEST);
depthTest = true;
SystemImpl.gl.depthFunc(GL.NEVER);
case Equal:
SystemImpl.gl.enable(GL.DEPTH_TEST);
depthTest = true;
SystemImpl.gl.depthFunc(GL.EQUAL);
case NotEqual:
SystemImpl.gl.enable(GL.DEPTH_TEST);
depthTest = true;
SystemImpl.gl.depthFunc(GL.NOTEQUAL);
case Less:
SystemImpl.gl.enable(GL.DEPTH_TEST);
depthTest = true;
SystemImpl.gl.depthFunc(GL.LESS);
case LessEqual:
SystemImpl.gl.enable(GL.DEPTH_TEST);
depthTest = true;
SystemImpl.gl.depthFunc(GL.LEQUAL);
case Greater:
SystemImpl.gl.enable(GL.DEPTH_TEST);
depthTest = true;
SystemImpl.gl.depthFunc(GL.GREATER);
case GreaterEqual:
SystemImpl.gl.enable(GL.DEPTH_TEST);
depthTest = true;
SystemImpl.gl.depthFunc(GL.GEQUAL);
}
SystemImpl.gl.depthMask(write);
depthMask = write;
}
static function getBlendFunc(factor: BlendingFactor): Int {
switch (factor) {
case BlendZero, Undefined:
return GL.ZERO;
case BlendOne:
return GL.ONE;
case SourceAlpha:
return GL.SRC_ALPHA;
case DestinationAlpha:
return GL.DST_ALPHA;
case InverseSourceAlpha:
return GL.ONE_MINUS_SRC_ALPHA;
case InverseDestinationAlpha:
return GL.ONE_MINUS_DST_ALPHA;
case SourceColor:
return GL.SRC_COLOR;
case DestinationColor:
return GL.DST_COLOR;
case InverseSourceColor:
return GL.ONE_MINUS_SRC_COLOR;
case InverseDestinationColor:
return GL.ONE_MINUS_DST_COLOR;
}
}
static function getBlendOp(op: BlendingOperation): Int {
switch (op) {
case Add:
return GL.FUNC_ADD;
case Subtract:
return GL.FUNC_SUBTRACT;
case ReverseSubtract:
return GL.FUNC_REVERSE_SUBTRACT;
case Min:
return 0x8007;
case Max:
return 0x8008;
}
}
public function setBlendingMode(source: BlendingFactor, destination: BlendingFactor, operation: BlendingOperation, alphaSource: BlendingFactor,
alphaDestination: BlendingFactor, alphaOperation: BlendingOperation): Void {
if (source == BlendOne && destination == BlendZero) {
SystemImpl.gl.disable(GL.BLEND);
}
else {
SystemImpl.gl.enable(GL.BLEND);
SystemImpl.gl.blendFuncSeparate(getBlendFunc(source), getBlendFunc(destination), getBlendFunc(alphaSource), getBlendFunc(alphaDestination));
SystemImpl.gl.blendEquationSeparate(getBlendOp(operation), getBlendOp(alphaOperation));
}
}
public function createVertexBuffer(vertexCount: Int, structure: VertexStructure, usage: Usage, canRead: Bool = false): kha.graphics4.VertexBuffer {
return new VertexBuffer(vertexCount, structure, usage);
}
public function setVertexBuffer(vertexBuffer: kha.graphics4.VertexBuffer): Void {
for (i in 0...useVertexAttributes) {
SystemImpl.gl.disableVertexAttribArray(i);
}
useVertexAttributes = vertexBuffer.set(0);
}
public function setVertexBuffers(vertexBuffers: Array<kha.graphics4.VertexBuffer>): Void {
for (i in 0...useVertexAttributes) {
SystemImpl.gl.disableVertexAttribArray(i);
}
var offset: Int = 0;
for (vertexBuffer in vertexBuffers) {
offset += vertexBuffer.set(offset);
}
useVertexAttributes = offset;
}
public function createIndexBuffer(indexCount: Int, usage: Usage, canRead: Bool = false): kha.graphics4.IndexBuffer {
return new IndexBuffer(indexCount, usage);
}
public function setIndexBuffer(indexBuffer: kha.graphics4.IndexBuffer): Void {
indicesCount = indexBuffer.count();
indexBuffer.set();
}
// public function maxTextureSize(): Int {
// return Sys.gl == null ? 8192 : Sys.gl.getParameter(Sys.gl.MAX_TEXTURE_SIZE);
// }
// public function supportsNonPow2Textures(): Bool {
// return false;
// }
public function setTexture(stage: kha.graphics4.TextureUnit, texture: kha.Image): Void {
if (texture == null) {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + (cast stage : TextureUnit).value);
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
}
else {
cast(texture, WebGLImage).set((cast stage : TextureUnit).value);
}
}
public function setTextureDepth(stage: kha.graphics4.TextureUnit, texture: kha.Image): Void {
cast(texture, WebGLImage).setDepth((cast stage : TextureUnit).value);
}
public function setTextureArray(unit: kha.graphics4.TextureUnit, texture: kha.Image): Void {
// not implemented yet.
}
public function setVideoTexture(unit: kha.graphics4.TextureUnit, texture: kha.Video): Void {
if (texture == null) {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + (cast unit : TextureUnit).value);
SystemImpl.gl.bindTexture(GL.TEXTURE_2D, null);
}
else {
cast((cast texture : kha.js.Video).texture, WebGLImage).set((cast unit : TextureUnit).value);
}
}
public function setImageTexture(unit: kha.graphics4.TextureUnit, texture: kha.Image): Void {}
public function setTextureParameters(texunit: kha.graphics4.TextureUnit, uAddressing: TextureAddressing, vAddressing: TextureAddressing,
minificationFilter: TextureFilter, magnificationFilter: TextureFilter, mipmapFilter: MipMapFilter): Void {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + (cast texunit : TextureUnit).value);
switch (uAddressing) {
case Clamp:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE);
case Repeat:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.REPEAT);
case Mirror:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.MIRRORED_REPEAT);
}
switch (vAddressing) {
case Clamp:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE);
case Repeat:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.REPEAT);
case Mirror:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.MIRRORED_REPEAT);
}
switch (minificationFilter) {
case PointFilter:
switch (mipmapFilter) {
case NoMipFilter:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
case PointMipFilter:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST_MIPMAP_NEAREST);
case LinearMipFilter:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST_MIPMAP_LINEAR);
}
case LinearFilter, AnisotropicFilter:
switch (mipmapFilter) {
case NoMipFilter:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
case PointMipFilter:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR_MIPMAP_NEAREST);
case LinearMipFilter:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR_MIPMAP_LINEAR);
}
if (minificationFilter == AnisotropicFilter) {
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, SystemImpl.anisotropicFilter.TEXTURE_MAX_ANISOTROPY_EXT, 4);
}
}
switch (magnificationFilter) {
case PointFilter:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
case LinearFilter, AnisotropicFilter:
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
}
}
public function setTexture3DParameters(texunit: kha.graphics4.TextureUnit, uAddressing: TextureAddressing, vAddressing: TextureAddressing,
wAddressing: TextureAddressing, minificationFilter: TextureFilter, magnificationFilter: TextureFilter, mipmapFilter: MipMapFilter): Void {}
public function setTextureCompareMode(texunit: kha.graphics4.TextureUnit, enabled: Bool) {
if (enabled) {
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL2.TEXTURE_COMPARE_MODE, GL2.COMPARE_REF_TO_TEXTURE);
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL2.TEXTURE_COMPARE_FUNC, GL.LEQUAL);
}
else {
SystemImpl.gl.texParameteri(GL.TEXTURE_2D, GL2.TEXTURE_COMPARE_MODE, GL.NONE);
}
}
public function setCubeMapCompareMode(texunit: kha.graphics4.TextureUnit, enabled: Bool) {
if (enabled) {
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL2.TEXTURE_COMPARE_MODE, GL2.COMPARE_REF_TO_TEXTURE);
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL2.TEXTURE_COMPARE_FUNC, GL.LEQUAL);
}
else {
SystemImpl.gl.texParameteri(GL.TEXTURE_CUBE_MAP, GL2.TEXTURE_COMPARE_MODE, GL.NONE);
}
}
public function setCubeMap(stage: kha.graphics4.TextureUnit, cubeMap: kha.graphics4.CubeMap): Void {
if (cubeMap == null) {
SystemImpl.gl.activeTexture(GL.TEXTURE0 + (cast stage : TextureUnit).value);
SystemImpl.gl.bindTexture(GL.TEXTURE_CUBE_MAP, null);
}
else {
cubeMap.set((cast stage : TextureUnit).value);
}
}
public function setCubeMapDepth(stage: kha.graphics4.TextureUnit, cubeMap: kha.graphics4.CubeMap): Void {
cubeMap.setDepth((cast stage : TextureUnit).value);
}
public function maxBoundTextures(): Int {
return SystemImpl.gl.getParameter(GL.MAX_TEXTURE_IMAGE_UNITS);
}
public function setCullMode(mode: CullMode): Void {
switch (mode) {
case None:
SystemImpl.gl.disable(GL.CULL_FACE);
case Clockwise:
SystemImpl.gl.enable(GL.CULL_FACE);
SystemImpl.gl.cullFace(GL.BACK);
case CounterClockwise:
SystemImpl.gl.enable(GL.CULL_FACE);
SystemImpl.gl.cullFace(GL.FRONT);
}
}
public function setPipeline(pipe: PipelineState): Void {
setCullMode(pipe.cullMode);
setDepthMode(pipe.depthWrite, pipe.depthMode);
if (pipe.stencilFrontMode == Always && pipe.stencilBackMode == Always && pipe.stencilFrontBothPass == Keep && pipe.stencilBackBothPass == Keep
&& pipe.stencilFrontDepthFail == Keep && pipe.stencilBackDepthFail == Keep && pipe.stencilFrontFail == Keep && pipe.stencilBackFail == Keep) {
SystemImpl.gl.disable(GL.STENCIL_TEST);
}
else {
SystemImpl.gl.enable(GL.STENCIL_TEST);
setStencilParameters(true, pipe.stencilFrontMode, pipe.stencilFrontBothPass, pipe.stencilFrontDepthFail, pipe.stencilFrontFail,
pipe.stencilReferenceValue, pipe.stencilReadMask, pipe.stencilWriteMask);
setStencilParameters(false, pipe.stencilBackMode, pipe.stencilBackBothPass, pipe.stencilBackDepthFail, pipe.stencilBackFail,
pipe.stencilReferenceValue, pipe.stencilReadMask, pipe.stencilWriteMask);
}
setBlendingMode(pipe.blendSource, pipe.blendDestination, pipe.blendOperation, pipe.alphaBlendSource, pipe.alphaBlendDestination,
pipe.alphaBlendOperation);
currentPipeline = pipe;
pipe.set();
colorMaskRed = pipe.colorWriteMaskRed;
colorMaskGreen = pipe.colorWriteMaskGreen;
colorMaskBlue = pipe.colorWriteMaskBlue;
colorMaskAlpha = pipe.colorWriteMaskAlpha;
}
public function setStencilReferenceValue(value: Int): Void {
SystemImpl.gl.stencilFuncSeparate(GL.FRONT, convertCompareMode(currentPipeline.stencilFrontMode), value, currentPipeline.stencilReadMask);
SystemImpl.gl.stencilFuncSeparate(GL.BACK, convertCompareMode(currentPipeline.stencilBackMode), value, currentPipeline.stencilReadMask);
}
public function setBool(location: kha.graphics4.ConstantLocation, value: Bool): Void {
SystemImpl.gl.uniform1i((cast location : ConstantLocation).value, value ? 1 : 0);
}
public function setInt(location: kha.graphics4.ConstantLocation, value: Int): Void {
SystemImpl.gl.uniform1i((cast location : ConstantLocation).value, value);
}
public function setInt2(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int): Void {
SystemImpl.gl.uniform2i((cast location : ConstantLocation).value, value1, value2);
}
public function setInt3(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int, value3: Int): Void {
SystemImpl.gl.uniform3i((cast location : ConstantLocation).value, value1, value2, value3);
}
public function setInt4(location: kha.graphics4.ConstantLocation, value1: Int, value2: Int, value3: Int, value4: Int): Void {
SystemImpl.gl.uniform4i((cast location : ConstantLocation).value, value1, value2, value3, value4);
}
public function setInts(location: kha.graphics4.ConstantLocation, values: Int32Array): Void {
var webglLocation = (cast location : ConstantLocation);
var rawValues = new js.lib.Int32Array(values.buffer, values.byteOffset, values.length);
switch (webglLocation.type) {
case GL.INT_VEC2:
SystemImpl.gl.uniform2iv(webglLocation.value, rawValues);
case GL.INT_VEC3:
SystemImpl.gl.uniform3iv(webglLocation.value, rawValues);
case GL.INT_VEC4:
SystemImpl.gl.uniform4iv(webglLocation.value, rawValues);
default:
SystemImpl.gl.uniform1iv(webglLocation.value, rawValues);
}
}
public function setFloat(location: kha.graphics4.ConstantLocation, value: FastFloat): Void {
SystemImpl.gl.uniform1f((cast location : ConstantLocation).value, value);
}
public function setFloat2(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat): Void {
SystemImpl.gl.uniform2f((cast location : ConstantLocation).value, value1, value2);
}
public function setFloat3(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat, value3: FastFloat): Void {
SystemImpl.gl.uniform3f((cast location : ConstantLocation).value, value1, value2, value3);
}
public function setFloat4(location: kha.graphics4.ConstantLocation, value1: FastFloat, value2: FastFloat, value3: FastFloat, value4: FastFloat): Void {
SystemImpl.gl.uniform4f((cast location : ConstantLocation).value, value1, value2, value3, value4);
}
public function setFloats(location: kha.graphics4.ConstantLocation, values: Float32Array): Void {
var webglLocation = (cast location : ConstantLocation);
var rawValues = new js.lib.Float32Array(values.buffer, values.byteOffset, values.length);
switch (webglLocation.type) {
case GL.FLOAT_VEC2:
SystemImpl.gl.uniform2fv(webglLocation.value, rawValues);
case GL.FLOAT_VEC3:
SystemImpl.gl.uniform3fv(webglLocation.value, rawValues);
case GL.FLOAT_VEC4:
SystemImpl.gl.uniform4fv(webglLocation.value, rawValues);
case GL.FLOAT_MAT4:
SystemImpl.gl.uniformMatrix4fv(webglLocation.value, false, rawValues);
default:
SystemImpl.gl.uniform1fv(webglLocation.value, rawValues);
}
}
public function setVector2(location: kha.graphics4.ConstantLocation, value: FastVector2): Void {
SystemImpl.gl.uniform2f((cast location : ConstantLocation).value, value.x, value.y);
}
public function setVector3(location: kha.graphics4.ConstantLocation, value: FastVector3): Void {
SystemImpl.gl.uniform3f((cast location : ConstantLocation).value, value.x, value.y, value.z);
}
public function setVector4(location: kha.graphics4.ConstantLocation, value: FastVector4): Void {
SystemImpl.gl.uniform4f((cast location : ConstantLocation).value, value.x, value.y, value.z, value.w);
}
static var matrixCache = new js.lib.Float32Array(16);
public inline function setMatrix(location: kha.graphics4.ConstantLocation, matrix: FastMatrix4): Void {
matrixCache[0] = matrix._00;
matrixCache[1] = matrix._01;
matrixCache[2] = matrix._02;
matrixCache[3] = matrix._03;
matrixCache[4] = matrix._10;
matrixCache[5] = matrix._11;
matrixCache[6] = matrix._12;
matrixCache[7] = matrix._13;
matrixCache[8] = matrix._20;
matrixCache[9] = matrix._21;
matrixCache[10] = matrix._22;
matrixCache[11] = matrix._23;
matrixCache[12] = matrix._30;
matrixCache[13] = matrix._31;
matrixCache[14] = matrix._32;
matrixCache[15] = matrix._33;
SystemImpl.gl.uniformMatrix4fv((cast location : ConstantLocation).value, false, matrixCache);
}
static var matrix3Cache = new js.lib.Float32Array(9);
public inline function setMatrix3(location: kha.graphics4.ConstantLocation, matrix: FastMatrix3): Void {
matrix3Cache[0] = matrix._00;
matrix3Cache[1] = matrix._01;
matrix3Cache[2] = matrix._02;
matrix3Cache[3] = matrix._10;
matrix3Cache[4] = matrix._11;
matrix3Cache[5] = matrix._12;
matrix3Cache[6] = matrix._20;
matrix3Cache[7] = matrix._21;
matrix3Cache[8] = matrix._22;
SystemImpl.gl.uniformMatrix3fv((cast location : ConstantLocation).value, false, matrix3Cache);
}
public function drawIndexedVertices(start: Int = 0, count: Int = -1): Void {
var type = SystemImpl.elementIndexUint == null ? GL.UNSIGNED_SHORT : GL.UNSIGNED_INT;
var size = type == GL.UNSIGNED_SHORT ? 2 : 4;
SystemImpl.gl.drawElements(GL.TRIANGLES, count == -1 ? indicesCount : count, type, start * size);
}
function convertStencilAction(action: StencilAction) {
switch (action) {
case StencilAction.Decrement:
return GL.DECR;
case StencilAction.DecrementWrap:
return GL.DECR_WRAP;
case StencilAction.Increment:
return GL.INCR;
case StencilAction.IncrementWrap:
return GL.INCR_WRAP;
case StencilAction.Invert:
return GL.INVERT;
case StencilAction.Keep:
return GL.KEEP;
case StencilAction.Replace:
return GL.REPLACE;
case StencilAction.Zero:
return GL.ZERO;
}
}
function convertCompareMode(compareMode: CompareMode) {
switch (compareMode) {
case Always:
return GL.ALWAYS;
case Equal:
return GL.EQUAL;
case Greater:
return GL.GREATER;
case GreaterEqual:
return GL.GEQUAL;
case Less:
return GL.LESS;
case LessEqual:
return GL.LEQUAL;
case Never:
return GL.NEVER;
case NotEqual:
return GL.NOTEQUAL;
}
}
public function setStencilParameters(front: Bool, compareMode: CompareMode, bothPass: StencilAction, depthFail: StencilAction, stencilFail: StencilAction,
referenceValue: StencilValue, readMask: Int = 0xff, writeMask: Int = 0xff): Void {
var stencilFunc = convertCompareMode(compareMode);
SystemImpl.gl.stencilMaskSeparate(front ? GL.FRONT : GL.BACK, writeMask);
SystemImpl.gl.stencilOpSeparate(front ? GL.FRONT : GL.BACK, convertStencilAction(stencilFail), convertStencilAction(depthFail),
convertStencilAction(bothPass));
switch (referenceValue) {
case Static(value):
SystemImpl.gl.stencilFuncSeparate(front ? GL.FRONT : GL.BACK, stencilFunc, value, readMask);
case Dynamic:
SystemImpl.gl.stencilFuncSeparate(front ? GL.FRONT : GL.BACK, stencilFunc, 0, readMask);
}
}
public function drawIndexedVerticesInstanced(instanceCount: Int, start: Int = 0, count: Int = -1) {
if (instancedRenderingAvailable()) {
var type = SystemImpl.elementIndexUint == null ? GL.UNSIGNED_SHORT : GL.UNSIGNED_INT;
var typeSize = SystemImpl.elementIndexUint == null ? 2 : 4;
if (SystemImpl.gl2) {
untyped SystemImpl.gl.drawElementsInstanced(GL.TRIANGLES, count == -1 ? indicesCount : count, type, start * typeSize, instanceCount);
}
else {
instancedExtension.drawElementsInstancedANGLE(GL.TRIANGLES, count == -1 ? indicesCount : count, type, start * typeSize, instanceCount);
}
}
}
public function instancedRenderingAvailable(): Bool {
return instancedExtension;
}
}

View File

@ -0,0 +1,25 @@
package kha.js.graphics4;
import js.html.webgl.GL;
import kha.Color;
class Graphics2 extends kha.graphics4.Graphics2 {
public function new(canvas: Canvas) {
super(canvas);
}
override public function drawVideoInternal(video: kha.Video, x: Float, y: Float, width: Float, height: Float): Void {
var v = cast(video, Video);
drawScaledSubImage(v.texture, 0, 0, v.texture.width, v.texture.height, x, y, width, height);
}
override public function begin(clear: Bool = true, clearColor: Color = null): Void {
SystemImpl.gl.colorMask(true, true, true, true);
// Disable depth test so that everything is just overpainted as determined by the order of function calls2
SystemImpl.gl.disable(GL.DEPTH_TEST);
SystemImpl.gl.depthFunc(GL.ALWAYS);
super.begin(clear, clearColor);
}
}

View File

@ -0,0 +1,9 @@
package kha.js.graphics4;
class TextureUnit implements kha.graphics4.TextureUnit {
public var value: Int;
public function new(value: Int) {
this.value = value;
}
}

View File

@ -0,0 +1,249 @@
package kha.js.vr;
import js.Syntax;
import js.lib.Float32Array;
import kha.vr.Pose;
import kha.vr.PoseState;
import kha.vr.SensorState;
import kha.vr.TimeWarpParms;
import kha.math.FastMatrix4;
import kha.math.Vector3;
import kha.math.Quaternion;
import kha.SystemImpl;
class VrInterface extends kha.vr.VrInterface {
var vrEnabled: Bool = false;
var vrDisplay: Dynamic;
var frameData: Dynamic;
var leftProjectionMatrix: FastMatrix4 = FastMatrix4.identity();
var rightProjectionMatrix: FastMatrix4 = FastMatrix4.identity();
var leftViewMatrix: FastMatrix4 = FastMatrix4.identity();
var rightViewMatrix: FastMatrix4 = FastMatrix4.identity();
var width: Int = 0;
var height: Int = 0;
var vrWidth: Int = 0;
var vrHeight: Int = 0;
public function new() {
super();
#if kha_webvr
var displayEnabled: Bool = Syntax.code("navigator.getVRDisplays");
#else
var displayEnabled = false;
#end
if (displayEnabled) {
vrEnabled = true;
getVRDisplays();
trace("Display enabled.");
}
}
function getVRDisplays() {
var vrDisplayInstance = Syntax.code("navigator.getVRDisplays()");
vrDisplayInstance.then(function(displays) {
if (displays.length > 0) {
frameData = Syntax.code("new VRFrameData()");
vrDisplay = Syntax.code("displays[0]");
vrDisplay.depthNear = 0.1;
vrDisplay.depthFar = 1024.0;
var leftEye = vrDisplay.getEyeParameters("left");
var rightEye = vrDisplay.getEyeParameters("right");
width = SystemImpl.khanvas.width;
height = SystemImpl.khanvas.height;
vrWidth = Std.int(Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2);
vrHeight = Std.int(Math.max(leftEye.renderHeight, rightEye.renderHeight));
}
else {
trace("There are no VR displays connected.");
}
});
}
public override function onVRRequestPresent() {
try {
vrDisplay.requestPresent([{source: SystemImpl.khanvas}]).then(function() {
onResize();
vrDisplay.requestAnimationFrame(onAnimationFrame);
});
}
catch (err:Dynamic) {
trace("Failed to requestPresent.");
trace(err);
}
}
public override function onVRExitPresent() {
try {
vrDisplay.exitPresent([{source: SystemImpl.khanvas}]).then(function() {
onResize();
});
}
catch (err:Dynamic) {
trace("Failed to exitPresent.");
trace(err);
}
}
public override function onResetPose() {
try {
vrDisplay.resetPose();
}
catch (err:Dynamic) {
trace("Failed to resetPose");
trace(err);
}
}
function onAnimationFrame(timestamp: Float): Void {
if (vrDisplay != null && vrDisplay.isPresenting) {
vrDisplay.requestAnimationFrame(onAnimationFrame);
vrDisplay.getFrameData(frameData);
leftProjectionMatrix = createMatrixFromArray(untyped frameData.leftProjectionMatrix);
leftViewMatrix = createMatrixFromArray(untyped frameData.leftViewMatrix);
rightProjectionMatrix = createMatrixFromArray(untyped frameData.rightProjectionMatrix);
rightViewMatrix = createMatrixFromArray(untyped frameData.rightViewMatrix);
// Submit the newly rendered layer to be presented by the VRDisplay
vrDisplay.submitFrame();
}
}
function onResize() {
if (vrDisplay != null && vrDisplay.isPresenting) {
SystemImpl.khanvas.width = vrWidth;
SystemImpl.khanvas.height = vrHeight;
}
else {
SystemImpl.khanvas.width = width;
SystemImpl.khanvas.height = height;
}
}
public override function GetSensorState(): SensorState {
return GetPredictedSensorState(0.0);
}
public override function GetPredictedSensorState(time: Float): SensorState {
var result: SensorState = new SensorState();
result.Predicted = new PoseState();
result.Recorded = result.Predicted;
result.Predicted.AngularAcceleration = new Vector3();
result.Predicted.AngularVelocity = new Vector3();
result.Predicted.LinearAcceleration = new Vector3();
result.Predicted.LinearVelocity = new Vector3();
result.Predicted.TimeInSeconds = time;
result.Predicted.Pose = new Pose();
result.Predicted.Pose.Orientation = new Quaternion();
result.Predicted.Pose.Position = new Vector3();
var mPose = frameData.pose; // predicted pose of the vrDisplay
if (mPose != null) {
result.Predicted.AngularVelocity = createVectorFromArray(untyped mPose.angularVelocity);
result.Predicted.AngularAcceleration = createVectorFromArray(untyped mPose.angularAcceleration);
result.Predicted.LinearVelocity = createVectorFromArray(untyped mPose.linearVelocity);
result.Predicted.LinearAcceleration = createVectorFromArray(untyped mPose.linearAcceleration);
result.Predicted.Pose.Orientation = createQuaternion(untyped mPose.orientation);
result.Predicted.Pose.Position = createVectorFromArray(untyped mPose.position);
}
return result;
}
// Sends a black image to the warp swap thread
public override function WarpSwapBlack(): Void {
// TODO: Implement
}
// Sends the Oculus loading symbol to the warp swap thread
public override function WarpSwapLoadingIcon(): Void {
// TODO: Implement
}
// Sends the set of images to the warp swap thread
public override function WarpSwap(parms: TimeWarpParms): Void {
// TODO: Implement
}
public override function IsPresenting(): Bool {
if (vrDisplay != null)
return vrDisplay.isPresenting;
return false;
}
public override function IsVrEnabled(): Bool {
return vrEnabled;
}
public override function GetTimeInSeconds(): Float {
return Scheduler.time();
}
public override function GetProjectionMatrix(eye: Int): FastMatrix4 {
if (eye == 0) {
return leftProjectionMatrix;
}
else {
return rightProjectionMatrix;
}
}
public override function GetViewMatrix(eye: Int): FastMatrix4 {
if (eye == 0) {
return leftViewMatrix;
}
else {
return rightViewMatrix;
}
}
function createMatrixFromArray(array: Float32Array): FastMatrix4 {
var matrix: FastMatrix4 = FastMatrix4.identity();
matrix._00 = array[0];
matrix._01 = array[1];
matrix._02 = array[2];
matrix._03 = array[3];
matrix._10 = array[4];
matrix._11 = array[5];
matrix._12 = array[6];
matrix._13 = array[7];
matrix._20 = array[8];
matrix._21 = array[9];
matrix._22 = array[10];
matrix._23 = array[11];
matrix._30 = array[12];
matrix._31 = array[13];
matrix._32 = array[14];
matrix._33 = array[15];
return matrix;
}
function createVectorFromArray(array: Float32Array): Vector3 {
var vector: Vector3 = new Vector3(0, 0, 0);
if (array != null) {
vector.x = array[0];
vector.y = array[1];
vector.z = array[2];
}
return vector;
}
function createQuaternion(array: Float32Array): Quaternion {
var quaternion: Quaternion = new Quaternion(0, 0, 0, 0);
if (array != null) {
quaternion.x = array[0];
quaternion.y = array[1];
quaternion.z = array[2];
quaternion.w = array[3];
}
return quaternion;
}
}

View File

@ -0,0 +1,68 @@
package kha.netsync;
import haxe.io.Bytes;
import js.html.BinaryType;
import js.html.WebSocket;
class Network {
var socket: WebSocket;
var open: Bool = false;
public function new(url: String, port: Int, errorCallback: Void->Void, closeCallback: Void->Void) {
socket = new WebSocket("ws://" + url + ":" + port);
socket.onerror = function(error) {
trace("Network error.");
errorCallback();
}
socket.binaryType = BinaryType.ARRAYBUFFER;
socket.onopen = function() {
open = true;
};
socket.onclose = function(event) {
trace("Network connection closed. " + webSocketCloseReason(event.code) + " (" + event.reason + ").");
closeCallback();
}
}
static function webSocketCloseReason(code: Int): String {
switch (code) {
case 1000:
return "Normal Closure";
case 1001:
return "Going Away";
case 1002:
return "Protocol error";
case 1003:
return "Unsupported Data";
case 1005:
return "No Status Rcvd";
case 1006:
return "Abnormal Closure";
case 1007:
return "Invalid frame";
case 1008:
return "Policy Violation";
case 1009:
return "Message Too Big";
case 1010:
return "Mandatory Ext.";
case 1011:
return "Internal Server Error";
case 1015:
return "TLS handshake";
default:
return "";
}
}
public function send(bytes: Bytes, mandatory: Bool): Void {
if (open)
socket.send(bytes.getData());
}
public function listen(listener: Bytes->Void): Void {
socket.onmessage = function(message) {
listener(Bytes.ofData(message.data));
};
}
}

View File

@ -0,0 +1,40 @@
package kha.network;
import js.html.XMLHttpRequest;
class Http {
static function methodToString(method: HttpMethod): String {
switch (method) {
case Get:
return "GET";
case Post:
return "POST";
case Put:
return "PUT";
case Delete:
return "DELETE";
}
}
public static function request(url: String, path: String, data: String, port: Int, secure: Bool, method: HttpMethod, headers: Map<String, String>,
callback: Int->Int->String->Void /*error, response, body*/): Void {
var req = new XMLHttpRequest("");
var completeUrl = (secure ? "https://" : "http://") + url + ":" + port + "/" + path;
req.open(methodToString(method), completeUrl, true);
if (headers != null) {
for (key in headers.keys()) {
req.setRequestHeader(key, headers[key]);
}
}
req.onreadystatechange = function() {
if (req.readyState != 4)
return;
if (req.status != 200) {
callback(1, req.status, null);
return;
}
callback(0, req.status, req.responseText);
}
req.send(data);
}
}

View File

@ -0,0 +1,5 @@
package java.lang;
extern interface Runnable {
function run(): Void;
}

View File

@ -0,0 +1,3 @@
package kha;
typedef Blob = kha.internal.BytesBlob;

View File

@ -0,0 +1,75 @@
package kha;
class Display {
static var instance: Display = new Display();
function new() {}
public static function init(): Void {}
public static var primary(get, never): Display;
static function get_primary(): Display {
return instance;
}
public static var all(get, never): Array<Display>;
static function get_all(): Array<Display> {
return [primary];
}
public var available(get, never): Bool;
function get_available(): Bool {
return true;
}
public var name(get, never): String;
function get_name(): String {
return "Display";
}
public var x(get, never): Int;
function get_x(): Int {
return 0;
}
public var y(get, never): Int;
function get_y(): Int {
return 0;
}
public var width(get, never): Int;
function get_width(): Int {
return 1920;
}
public var height(get, never): Int;
function get_height(): Int {
return 1080;
}
public var frequency(get, never): Int;
function get_frequency(): Int {
return 60;
}
public var pixelsPerInch(get, never): Int;
function get_pixelsPerInch(): Int {
return 96;
}
public var modes(get, never): Array<DisplayMode>;
function get_modes(): Array<DisplayMode> {
return [];
}
}

Some files were not shown because too many files have changed in this diff Show More