diff --git a/application.xml b/application.xml new file mode 100755 index 0000000..ba0e2dc --- /dev/null +++ b/application.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/TileMap.tmx b/assets/TileMap.tmx new file mode 100755 index 0000000..51e3eff --- /dev/null +++ b/assets/TileMap.tmx @@ -0,0 +1,63 @@ + + + + + + + +30,30,30,25,26,26,26,26,26,26,26,26,26,26,26,27,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,48,33,36,42,42,42,42,42,42,42,42,42,37,35,47,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,33,35,30,30,30,30,30,30,30,30,30,33,35,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +48,30,30,33,35,30,30,30,30,30,30,30,30,30,33,35,30,47,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,33,44,26,27,30,30,30,25,26,26,26,45,35,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,40,30,41,42,42,43,6,7,8,41,42,42,42,42,43,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,40,30,46,14,15,16,30,40,40,40,40,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +7,7,7,7,7,7,7,13,15,12,7,7,7,7,7,8,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,40,40,40,40,40,40,40,40,40,40,40,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,32,32,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,32,32,32,32,32,30,30,30,30,30,30,30,32,32,32,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +20,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,21,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,30,30,30,30,30,15,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,30,30,30,30,30,30,46,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,30,30,30,20,30,30,18,18,18,18,18,18,18,18,18,18,21,18,18,18,18,18,18,18,18,18,18,18,18,18,18,21, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,2,2,2,11,30,30,30,30,30,30,30,30,30,30,30,30,9,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,9,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,30,30,30,28,2,2,2,2,2,2,2,2,2,2,30,30,9,30,30,18,18,18,18,18,18,18,18,18,18,18,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,30,30,30,30,30,30,30,30,30,30,30,30,30,9,30,30,9,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,30,30,30,30,30,30,30,30,30,30,30,30,30,9,30,30,9,30,30,30,30,2,2,2,2,2,2,2,2,2,2,29, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,9,30,30,2,2,2,2,2,2,2,2,11,30,30,9,30,30,9,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,9,30,30,9,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,30,30,17,18,18,18,18,18,18,18,18,18,18,18,30,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,18,18,18,18,18,18,20,18,18,18,18,18,18,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,18,18,18,18,18,18,18,18,20,18,18,18,18,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,30,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,30,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,11,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,30,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,30,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,30,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,30,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,30,30,30,11,30,30,9, +11,30,30,11,30,30,30,11,30,30,30,30,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,30,30,30,30,11,30,30,30,11,30,30,30,11,30,30,30,30,30,30,11,30,30,9, +11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +11,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,9, +28,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,29 + + + + + + diff --git a/assets/desert.tmx b/assets/desert.tmx new file mode 100755 index 0000000..7670483 --- /dev/null +++ b/assets/desert.tmx @@ -0,0 +1,1632 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/hxlogo.png b/assets/hxlogo.png new file mode 100755 index 0000000..dc6895c Binary files /dev/null and b/assets/hxlogo.png differ diff --git a/assets/map.tmx b/assets/map.tmx new file mode 100755 index 0000000..121b3c2 --- /dev/null +++ b/assets/map.tmx @@ -0,0 +1,610 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/mapxml.tmx b/assets/mapxml.tmx new file mode 100755 index 0000000..121b3c2 --- /dev/null +++ b/assets/mapxml.tmx @@ -0,0 +1,610 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/openfl.svg b/assets/openfl.svg new file mode 100755 index 0000000..cd02515 --- /dev/null +++ b/assets/openfl.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + diff --git a/assets/player.png b/assets/player.png new file mode 100755 index 0000000..b69ff23 Binary files /dev/null and b/assets/player.png differ diff --git a/assets/scrol.tmx b/assets/scrol.tmx new file mode 100755 index 0000000..0aab014 --- /dev/null +++ b/assets/scrol.tmx @@ -0,0 +1,2515 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/sewer_tileset.png b/assets/sewer_tileset.png new file mode 100755 index 0000000..9455c8e Binary files /dev/null and b/assets/sewer_tileset.png differ diff --git a/assets/sewers.tmx b/assets/sewers.tmx new file mode 100755 index 0000000..baf33c5 --- /dev/null +++ b/assets/sewers.tmx @@ -0,0 +1,2515 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/sprites.png b/assets/sprites.png new file mode 100755 index 0000000..f6b051f Binary files /dev/null and b/assets/sprites.png differ diff --git a/assets/texture.png b/assets/texture.png new file mode 100755 index 0000000..19bfb80 Binary files /dev/null and b/assets/texture.png differ diff --git a/assets/tiles.png b/assets/tiles.png new file mode 100755 index 0000000..6aed983 Binary files /dev/null and b/assets/tiles.png differ diff --git a/assets/tmw_desert_spacing.png b/assets/tmw_desert_spacing.png new file mode 100755 index 0000000..4e9995c Binary files /dev/null and b/assets/tmw_desert_spacing.png differ diff --git a/assets/zazaka.png b/assets/zazaka.png new file mode 100755 index 0000000..52e4969 Binary files /dev/null and b/assets/zazaka.png differ diff --git a/glframework.hxproj b/glframework.hxproj new file mode 100755 index 0000000..c1aff2a --- /dev/null +++ b/glframework.hxproj @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/openfl-readme.txt b/openfl-readme.txt new file mode 100755 index 0000000..3239f7b --- /dev/null +++ b/openfl-readme.txt @@ -0,0 +1,68 @@ +About OpenFL + + OpenFL is the successor of NME, for Haxe 3+. + + Building a game or application with OpenFL is almost like writing for a single platform. However, + when you are ready to publish your application, you can choose between targets like iOS, webOS, + Android, Windows, Mac, Linux and Flash Player. + + Instead of using the lowest common denominator between platforms with a "universal" runtime, + OpenFL projects are compiled as SWF bytecode or C++ applications, using the Haxe language compiler + and the standard C++ compiler toolchain for each platform. + + Read more: + http://openfl.org/ + +Project configuration, libraries, classpaths + + OpenFL configuration is based on a XML file - it allows you very complex + configurations depending on the target platform. There is no GUI for it. + + DO NOT modify FlashDevelop project properties as they will automatically be synchronized with the + XML when you modify it. + +Development + + OpenFL is encouraging to develop using the Flash API (ie. flash.display.Sprite) as in ActionScript 3. + + Just code like you would code a Flash application, with the limitation that you can only use + the drawing API, bitmaps (see below) and TextFields. + + However test often all the platforms you plan to target! + + In OpenFL 3.x, SWFs and videos aren't supported yet. + +Assets + + Place all your images, sounds, fonts in /assets and access them in your code using the + global Assets class which abstracts assets management for all platforms: + + var img = new Bitmap(Assets.getBitmapData("assets/my-image.png")); + addChild(img); + + Tutorials: + https://github.com/openfl/openfl/wiki/Get-Started + +Debugging + + By default your project targets Flash so you'll be able to add breakpoints and debug your app + like any AS3 project. + HTML5 target can be debugged in the browser - some browsers, like Chrome, support "script maps" + which let you interactively debug .hx code directly instead of the generated JS. + There is however no interactive debugger yet for native targets. + +Changing target platform + + For OpenFL projects, an additional drop-down menu appears in the main toolbar where you can choose + a supported targets on Windows: flash, html5, windows, neko, android, webos, blackberry. + You can also manually enter a custom target not in the list. + + Attention, for native targets you'll need to install additional compilers & SDKs. The compiler + will tell you in the Output panel what command to execute for that. More information here: + https://github.com/openfl/openfl/wiki/Get-Started + +Tips: + - in C++ expect first compilation to be very long as it first compiles the whole OpenFL API, + - if a change is not taken in account, delete everything in /bin to start a fresh compilation, + - on mobile, Bitmap blitting is NOT performant, + - use spritesheets and Tilesheet.drawTiles for optimal rendering performance. diff --git a/src/Main.hx b/src/Main.hx new file mode 100755 index 0000000..a0f5cb8 --- /dev/null +++ b/src/Main.hx @@ -0,0 +1,64 @@ +package ; + +import flash.display.Sprite; +import flash.events.Event; +import flash.Lib; + +/** + * ... + * @author djoker + */ + +class Main extends Sprite +{ + var inited:Bool; + + /* ENTRY POINT */ + + function resize(e) + { + if (!inited) init(); + // else (resize or orientation change) + } + + function init() + { + if (inited) return; + inited = true; + + // (your code here) + + // Stage: + // stage.stageWidth x stage.stageHeight @ stage.dpiScale + + // Assets: + // nme.Assets.getBitmapData("img/assetname.jpg"); + } + + /* SETUP */ + + public function new() + { + super(); + addEventListener(Event.ADDED_TO_STAGE, added); + } + + function added(e) + { + removeEventListener(Event.ADDED_TO_STAGE, added); + stage.addEventListener(Event.RESIZE, resize); + #if ios + haxe.Timer.delay(init, 100); // iOS 6 + #else + init(); + #end + } + + public static function main() + { + // static entry point + Lib.current.stage.align = flash.display.StageAlign.TOP_LEFT; + Lib.current.stage.scaleMode = flash.display.StageScaleMode.NO_SCALE; + Lib.current.addChild(new Main()); + } +} diff --git a/src/com/djoker/glteste/FPS.hx b/src/com/djoker/glteste/FPS.hx new file mode 100755 index 0000000..c2d10a0 --- /dev/null +++ b/src/com/djoker/glteste/FPS.hx @@ -0,0 +1,44 @@ +package ; + +import flash.Lib; +import flash.text.TextField; +import flash.text.TextFormat; +import flash.events.Event; + +/** + * ... + * @author djoker + */ + +class FPS extends TextField +{ + var times:Array; + + public function new(inX:Float=10.0, inY:Float=10.0, inCol:Int = 0x000000) + { + super(); + x = inX; + y = inY; + selectable = false; + defaultTextFormat = new TextFormat("_sans", 20, 0, true); + text = "FPS:"; + textColor = inCol; + backgroundColor = 0xFFFFFF; + width = 150; + times = []; + addEventListener(Event.ENTER_FRAME, onEnter); + } + + public function onEnter(_) + { + var now = Lib.getTimer () / 1000; + times.push(now); + while(times[0]; + public var vertexStrideSize:Int; + + private var size:Int; + private var vertSize:Int; + private var numVerts:Int; + private var numIndices:Int; + private var idx:Int=0; + +private var rectangleCount:Int = 100; +private var primitiveIndex:Int = 0; +private var colorIndex:Int = 0; +private var primitiveCount:Int = 0; + + + + public function RenderNormal( x:Float, y:Float,w:Float,h:Float) +{ + + + var u:Float = 0; + var v:Float = 1; + var u2:Float = 1; + var v2:Float = 0; + + var fx2:Float = x + w; + var fy2:Float = y + h; + +/* +var index:Int = primitiveCount * vertexStrideSize; + +vertices[index++] = x; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = x; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; +*/ + +vertices[idx++] = x; +vertices[idx++] = y; +vertices[idx++] = 0; +vertices[idx++] = u;vertices[idx++] = v; +vertices[idx++] = 1;vertices[idx++] = 1;vertices[idx++] = 1;vertices[idx++] = 1; + +vertices[idx++] = x; +vertices[idx++] = fy2; +vertices[idx++] = 0; +vertices[idx++] = u;vertices[idx++] = v2; +vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; + +vertices[idx++] = fx2; +vertices[idx++] = fy2; +vertices[idx++] = 0; +vertices[idx++] = u2;vertices[idx++] = v2; +vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; + +vertices[idx++] = fx2; +vertices[idx++] = y; +vertices[idx++] = 0; +vertices[idx++] = u2;vertices[idx++] = v; +vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; + + +primitiveCount++; + +} + public static function getColorValue(color:Int):Float + { + var h:Int = (color >> 16) & 0xFF; + var s:Int = (color >> 8) & 0xFF; + var v:Int = color & 0xFF; + + return Std.int(Math.max(h, Math.max(s, v))) / 255; + } + +public function new() { +super(); +if (OpenGLView.isSupported) { +view = new OpenGLView(); + +Tex = new Texture("assets/openfl.png",true); +batch = new SpriteBatch(); + + +createProgram(); + + size = 1000; + vertSize = 6; + numVerts = size * 4 * vertSize; + numIndices = size * 6; + +vertices = new Float32Array(numVerts); + + +var indices:Int16Array = new Int16Array(numIndices); +var j:Int = 0; +var i:Int = 0; + for (count in 0...numIndices) + { + indices[i] = j + 0; i++; + indices[i] = j + 1; i++; + indices[i] = j + 2; i++; + indices[i] = j + 2; i++; + indices[i] = j + 3; i++; + indices[i] = j + 0; i++; + + j += 4; + } + + +/* + var indices:Array = []; + var index:Int = 0; + for (count in 0...numIndices) + { + indices.push(index); + indices.push(index + 1); + indices.push(index + 2); + indices.push(index); + indices.push(index + 2); + indices.push(index + 3); + index += 4; + } +*/ + + +primitiveCount = 0; +primitiveIndex = 0; + + + + //vertexDeclaration = [3, 2, 4]; + //vertexStrideSize = 9 * 4; // 9 floats (x, y, z,u,v, r, g, b, a) + vertexDeclaration = [3, 2,4]; + vertexStrideSize = 9 * 4; // 9 floats (x, y, z,u,v, r, g, b, a) + trace("size:" + vertexStrideSize); + + var offset:Int = 0; + + + + + + + + +vertexBuffer = GL.createBuffer(); +GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); +GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.DYNAMIC_DRAW); +GL.bindBuffer(GL.ARRAY_BUFFER, null); + + indexBuffer= GL.createBuffer(); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer); + //GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, new Int16Array(indices), GL.STATIC_DRAW); + GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, indices, GL.STATIC_DRAW); + + + +view.render = renderView; +addChild(view); +addChild(new FPS(10,10,0xff0ff)); +} +} + + + + +private function createProgram():Void { + + + GL.disable(GL.DEPTH_TEST); + GL.disable(GL.CULL_FACE); + + GL.enable(GL.BLEND); + GL.colorMask(true, true, true, true); + + var vertexShaderSource = + + " + uniform mat4 modelViewMatrix; + uniform mat4 projectionMatrix; + attribute vec3 a_position; + attribute vec2 a_texCoord; + attribute vec4 a_color; + varying vec2 v_texCoord; + varying vec4 vColor; + void main() + { + vColor = a_color; + v_texCoord = a_texCoord; + //gl_Position = u_projection * vec4(a_position, 0.0, 1.0); + gl_Position = projectionMatrix * modelViewMatrix * vec4(a_position, 1.0); + + gl_PointSize = 1.0; + }"; + +var vertexShader = GL.createShader(GL.VERTEX_SHADER); +GL.shaderSource(vertexShader, vertexShaderSource); +GL.compileShader(vertexShader); + +if (GL.getShaderParameter(vertexShader, GL.COMPILE_STATUS) == 0) { +throw throw(GL.getShaderInfoLog(vertexShader)); + +} + + var fragmentShaderSource = +" +varying vec2 v_texCoord; +varying vec4 vColor; +uniform sampler2D u_texture; +void main() +{ + vec4 texColor = texture2D(u_texture, v_texCoord); + // gl_FragColor = vColor * texColor; + // gl_FragColor = texColor *vec4(1.0, 1.0, 1.0, 1.0); + +gl_FragColor = texture2D (u_texture, v_texCoord); + + + + //gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); +}"; + + + + + +var fragmentShader = GL.createShader (GL.FRAGMENT_SHADER); + +GL.shaderSource(fragmentShader, fragmentShaderSource); +GL.compileShader(fragmentShader); + + +if (GL.getShaderParameter(fragmentShader, GL.COMPILE_STATUS) == 0) { + throw(GL.getShaderInfoLog(fragmentShader)); + +} + +shaderProgram = GL.createProgram(); +GL.attachShader(shaderProgram, vertexShader); +GL.attachShader(shaderProgram, fragmentShader); +GL.linkProgram(shaderProgram); + +if (GL.getProgramParameter(shaderProgram, GL.LINK_STATUS) == 0) +{ + throw(GL.getShaderInfoLog(fragmentShader)); +} + +vertexAttribute = GL.getAttribLocation(shaderProgram, "a_position"); +textureAttribute = GL.getAttribLocation(shaderProgram, "a_texCoord"); +colorAttribute = GL.getAttribLocation(shaderProgram, "a_color"); +imageUniform = GL.getUniformLocation (shaderProgram, "u_texture"); + + +} + + +private function renderView(rect:Rectangle):Void { +GL.viewport(Std.int(rect.x), Std.int(rect.y), Std.int(rect.width), Std.int(rect.height)); + +GL.clearColor(0,0,0.4, 1); +GL.clear(GL.COLOR_BUFFER_BIT); + +var positionX = 0;// rect.width / 2; +var positionY = 0;// rect.height / 2; + + +/* + +primitiveCount = 0; +primitiveIndex = 0; +idx = 0; + + + +RenderNormal(0, 0, 100, 100); +RenderNormal(100, 100, 400, 400); + + + + +var projMatrix:Matrix = Matrix.OrthoOffCenterLH(0, rect.width, rect.height, 0, 1000, -1000); +var modelViewMatrix = Matrix.create2D(positionX, positionY, 1, 0); + + + +var projectionMatrixUniform = GL.getUniformLocation(shaderProgram, "projectionMatrix"); +var modelViewMatrixUniform = GL.getUniformLocation(shaderProgram, "modelViewMatrix"); + + +GL.useProgram(shaderProgram); +GL.enableVertexAttribArray(vertexAttribute); +GL.enableVertexAttribArray(textureAttribute); +GL.enableVertexAttribArray(colorAttribute); + +GL.enable (GL.TEXTURE_2D); +GL.activeTexture(GL.TEXTURE0); +Tex.Bind(); + +GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); +GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer); + + + + +GL.vertexAttribPointer(vertexAttribute, 3, GL.FLOAT, false, vertexStrideSize,0); +GL.vertexAttribPointer(textureAttribute,2, GL.FLOAT, false, vertexStrideSize,3*4); +GL.vertexAttribPointer(colorAttribute ,4, GL.FLOAT, false, vertexStrideSize,(3+2)*4); + + + + +GL.uniformMatrix4fv(projectionMatrixUniform, false, new Float32Array(projMatrix.toArray())); +GL.uniformMatrix4fv(modelViewMatrixUniform, false, new Float32Array(modelViewMatrix.toArray())); +GL.uniform1i (imageUniform, 0); + + +GL.bufferSubData(GL.ARRAY_BUFFER, 0, vertices); +GL.drawElements(GL.TRIANGLES, primitiveCount * 6, GL.UNSIGNED_SHORT, 0); + + +GL.bindBuffer (GL.ARRAY_BUFFER, null); +GL.disableVertexAttribArray (vertexAttribute); +GL.disableVertexAttribArray (colorAttribute); +GL.disableVertexAttribArray(textureAttribute); +GL.useProgram (null); +*/ + + + +var projMatrix:Matrix = Matrix.OrthoOffCenterLH(0, rect.width, rect.height, 0, 1000, -1000); +var modelViewMatrix = Matrix.create2D(positionX, positionY, 1, 0); + + +batch.shader.projMatrix = projMatrix; +batch.shader.modelViewMatrix = modelViewMatrix; + +batch.Begin(); + +batch.Render(Tex, 100, 100, 0, 0, 120, 120, 0); + +batch.RenderNormal(Tex, 0, 0, 0); + +batch.End(); + +} +} \ No newline at end of file diff --git a/src/com/djoker/glteste/Main5.hx b/src/com/djoker/glteste/Main5.hx new file mode 100755 index 0000000..9b11c0e --- /dev/null +++ b/src/com/djoker/glteste/Main5.hx @@ -0,0 +1,142 @@ +package com.djoker.glteste; + +import flash.display.Sprite; +import flash.geom.Rectangle; +import flash.geom.Matrix3D; +import flash.text.TextField; +import flash.text.TextFormat; +import flash.events.MouseEvent; + + + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; + + +import com.engine.render.SpriteBatch; +import com.engine.render.Texture; +import com.engine.render.OrthoCamera; +import com.engine.Game.Game; + +import flash.text.TextField; +import flash.text.TextFormat; + +class Main extends Sprite { + +private var view:OpenGLView; +private var Tex :Texture; +private var tex2:Texture; + +private var batch:SpriteBatch; +var camera:OrthoCamera; + //http://djoker-games.co.nf/haxe/batch/index.html + + + + var particles : Array; + + var stats:TextField; + + +public function addParticle() +{ + var particle:Particle = new Particle(tex2); + particle.Init(); + particles.push(particle); +} +public function addParticle2(x:Float,y:Float) +{ + var particle:Particle = new Particle(tex2); + particle.Init(); + particle.x = x; + particle.y=y; + + particles.push(particle); +} + +public function new() { +super(); +if (OpenGLView.isSupported) +{ + +view = new OpenGLView(); + + +tex2 = new Texture("assets/texture.png", true); + +camera= new OrthoCamera(stage.stageWidth,stage.stageHeight); + +batch = new SpriteBatch(camera); + +particles = []; + for(i in 0...200) + addParticle(); + + + GL.disable(GL.DEPTH_TEST); + GL.disable(GL.CULL_FACE); + + GL.enable(GL.BLEND); + GL.colorMask(true, true, true, true); + GL.clearColor(0,0,0.4, 1); + + + + + +view.render = renderView; +addChild(view); +addChild(new FPS(10, 10, 0xff0ff)); + +stats = new TextField(); +stats.text = "trace"; +stats.x = 10; +stats.y = 20; +stats.width = 200; + +stats.defaultTextFormat = new TextFormat ("_sans", 12, 0xff00ff); + +addChild(stats); + +stage.addEventListener (MouseEvent.MOUSE_DOWN, onMouseDown); + + + +} +} + +private function onMouseDown (event:MouseEvent):Void +{ + addParticle2(event.localX,event.localY); +} + + + + +private function renderView(rect:Rectangle):Void +{ +GL.viewport(Std.int(rect.x), Std.int(rect.y), Std.int(rect.width), Std.int(rect.height)); +GL.clear(GL.COLOR_BUFFER_BIT); + +camera.Update(); + + +batch.Begin(); + + for(p in particles) + { + p.move(); + batch.drawImage(p); + } + +batch.End(); +//stats.text = Std.string("Bl:" + batch.numBlend +"- Tx:" + batch.numTex +" - Sp:"); + + +} +} \ No newline at end of file diff --git a/src/com/djoker/glteste/Movable.hx b/src/com/djoker/glteste/Movable.hx new file mode 100755 index 0000000..32c17bc --- /dev/null +++ b/src/com/djoker/glteste/Movable.hx @@ -0,0 +1,79 @@ +package com.djoker.glteste; +import flash.display.Bitmap; + +/** + * ... + * @author djoker + */ +class Movable extends Bitmap +{ + + var dx:Float; + var dy:Float; + var da:Float; + // var x:Float; + // var y:Float; + + + public function init() + { + + x = 320; + y = 240; + this.rotation = 0; + dx = Math.random()*200.0 - 100.0; + dy = Math.random()*200.0 - 100.0; + da = Math.random() * 360.2 - 180.1; + + + + + // red =1; Math.random(); + // green = Math.random(); + // blue = Math.random(); + alpha = Math.random(); + + + scaleX = Math.random() * 1.1 + 0.1; + scaleY = Math.random() * 1.1 + 0.1; + } + + + + + + + + public function move(dt:Float) + { + var rad = 30 * scaleX; + + x+=dx*dt; + if (x640-rad) + { + x = 640-rad; + dx = -dx; + } + + y+=dy*dt; + if (y480-rad) + { + y = 480-rad; + dy = -dy; + } + + this.rotation += da; + + + } +} \ No newline at end of file diff --git a/src/com/djoker/glteste/Particle.hx b/src/com/djoker/glteste/Particle.hx new file mode 100755 index 0000000..c01b33c --- /dev/null +++ b/src/com/djoker/glteste/Particle.hx @@ -0,0 +1,97 @@ +package com.djoker.glteste; +import com.engine.render.Image; + +/** + * ... + * @author djoker + */ + +class Particle extends Image +{ + + var dx:Float; + var dy:Float; + var da:Float; + + + public function Init() + { + + x = 320; + y = 240; + angle = 0; + dx = Math.random()*200.0 - 100.0; + dy = Math.random()*200.0 - 100.0; + da = Math.random() * 0.2 - 0.1; + + var frame:Int = Std.random(4*4); + var columns:Int = 4; + + var w:Int = 32; + var h:Int = 32; + + + //_rect.x = _rect.width * (frame % _columns); + //_rect.y = _rect.height * Std.int(frame / columns); + + + //var tx:Int = x * tileWidth; + //var ty:Int = y * tileHeight; + //var u:Number = (tid % columns) * uvWidth; + //var v:Number = Math.floor(tid / columns) * uvHeight; + + //clip.width = 32; + //clip.height = 32; + + // clip.right = 30 * (frame % columns); + // clip.bottom = 20 * Std.int(frame / columns); + + clip.set(w * (frame % columns), h * Std.int(frame / columns), w, h); + + + red =1; Math.random(); + green = Math.random(); + blue = Math.random(); + alpha = Math.random(); + + scaleX = 0.2;// Math.random() * 1.1 + 0.1; + scaleY = 0.2;// Math.random() * 1.1 + 0.1; + } + + + + + + public function move(dt:Float) + { + var rad = 30 * scaleX; + + x+=dx*dt; + if (x640-rad) + { + x = 640-rad; + dx = -dx; + } + + y+=dy*dt; + if (y480-rad) + { + y = 480-rad; + dy = -dy; + } + + angle += da; + + + } +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TestBatch2.hx b/src/com/djoker/glteste/TestBatch2.hx new file mode 100755 index 0000000..070198a --- /dev/null +++ b/src/com/djoker/glteste/TestBatch2.hx @@ -0,0 +1,88 @@ +package com.djoker.glteste; + +import com.engine.game.Screen; +import com.engine.game.Screen; +import com.engine.render.Batch; +import com.engine.render.Texture; +import com.engine.render.OrthoCamera; +/** + * ... + * @author djoker + */ +class TesteBatch2 extends Screen +{ + + + var tex :Texture; + var batch:Batch; + var camera:OrthoCamera; + + + + var particles : Array; + + + override public function show() + { + + tex = new Texture("assets/texture.png"); + camera = new OrthoCamera(640,480); + batch = new Batch(tex,camera,500); + particles = []; + for(i in 0...100) + addParticle(); + + } + override public function hide() + { } + override public function render(dt:Float) + { + camera.Update(); + batch.Begin(); + + // for(p in particles) + // { + // p.move(dt); + // batch.drawImage(p); + // } + + for(i in 0...particles.length) + { + var p:Particle = particles[i]; + p.move(dt); + batch.drawImage(p); + } + + batch.End(); + } + override public function resize(width:Int, height:Int) + { + game.setViewPort(0, 0, width, height); + } + + + + +public function addParticle() +{ + var particle:Particle = new Particle(tex); + particle.Init(); + particles.push(particle); +} +public function addParticle2(x:Float,y:Float) +{ + var particle:Particle = new Particle(tex); + particle.Init(); + particle.x = x; + particle.y=y; + particles.push(particle); +} + +override public function mouseDown(mousex:Float, mousey:Float) +{ + addParticle2(mousex, mousey); +} + + + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TesteAtlas.hx b/src/com/djoker/glteste/TesteAtlas.hx new file mode 100755 index 0000000..44d43cd --- /dev/null +++ b/src/com/djoker/glteste/TesteAtlas.hx @@ -0,0 +1,90 @@ +package com.djoker.glteste; + +import com.engine.game.Screen; +import com.engine.render.SpriteAtlas; +import com.engine.render.Texture; +import com.engine.render.OrthoCamera; + +import flash.events.Event; +import flash.text.TextField; +import flash.text.TextFormat; + +/** + * ... + * @author djoker + */ +class TesteAtlas extends Screen +{ + + + var tex :Texture; + var batch:SpriteAtlas; + var camera:OrthoCamera; + + + + var particles : Array; + + + override public function show() + { + + tex = new Texture("assets/texture.png"); + camera = new OrthoCamera(640,480); + batch = new SpriteAtlas(tex,camera,500); + particles = []; + for(i in 0...200) + addParticle(); + var caption:TextField = new TextField(); + caption.x = game.screnWidth / 2-100; + caption.y = 20; + caption.width = 200; + caption.defaultTextFormat = new TextFormat ("_sans", 12, 0xffff00); + caption.text = " Test 200 sprites with SpriteAtlas"; + game.addChild(caption); + + } + + override public function render(dt:Float) + { + camera.Update(); + batch.Begin(); + + for(p in particles) + { + p.move(dt); + batch.drawImage(p); + } + batch.End(); + } + override public function resize(width:Int, height:Int) + { + game.setViewPort(0, 0, width, height); + } + + + + +public function addParticle() +{ + var particle:Particle = new Particle(tex); + particle.Init(); + particles.push(particle); +} +public function addParticle2(x:Float,y:Float) +{ + var particle:Particle = new Particle(tex); + particle.Init(); + particle.x = x; + particle.y=y; + particles.push(particle); +} + +override public function mouseDown(mousex:Float, mousey:Float) +{ + addParticle2(mousex, mousey); +} + + + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TesteBatch.hx b/src/com/djoker/glteste/TesteBatch.hx new file mode 100755 index 0000000..19ac6f1 --- /dev/null +++ b/src/com/djoker/glteste/TesteBatch.hx @@ -0,0 +1,93 @@ +package com.djoker.glteste; + +import com.engine.game.Screen; +import com.engine.render.SpriteBatch; +import com.engine.render.Texture; +import com.engine.render.OrthoCamera; + +import flash.events.Event; +import flash.text.TextField; +import flash.text.TextFormat; + +/** + * ... + * @author djoker + */ +class TesteBatch extends Screen +{ + + var tex :Texture; + var batch:SpriteBatch; + var camera:OrthoCamera; + + + + var particles : Array; + + + override public function show() + { + + tex = new Texture("assets/texture.png"); + camera = new OrthoCamera(640,480); + batch = new SpriteBatch(camera,500); + particles = []; + for(i in 0...200) + addParticle(); + + + var caption:TextField = new TextField(); + caption.x = game.screnWidth / 2-100; + caption.y = 20; + caption.width = 200; + caption.defaultTextFormat = new TextFormat ("_sans", 12, 0xffff00); + caption.text = "Test 200 sprites with SpriteBatch "; + game.addChild(caption); + + + } + + override public function render(dt:Float) + { + //camera.Update(); + batch.Begin(); + + for(p in particles) + { + p.move(dt); + //batch.RenderNormal(p.texture,p.x, p.y,p.blendMode); + batch.drawImage(p); + } + batch.End(); + } + override public function resize(width:Int, height:Int) + { + game.setViewPort(0, 0, width, height); + } + + + + +public function addParticle() +{ + var particle:Particle = new Particle(tex); + particle.Init(); + particles.push(particle); +} +public function addParticle2(x:Float,y:Float) +{ + var particle:Particle = new Particle(tex); + particle.Init(); + particle.x = x; + particle.y=y; + particles.push(particle); +} + +override public function mouseDown(mousex:Float, mousey:Float) +{ + addParticle2(mousex, mousey); +} + + + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TesteBatchTiles.hx b/src/com/djoker/glteste/TesteBatchTiles.hx new file mode 100755 index 0000000..5f11b74 --- /dev/null +++ b/src/com/djoker/glteste/TesteBatchTiles.hx @@ -0,0 +1,244 @@ +package com.djoker.glteste; + +import com.engine.render.Clip; +import flash.display.Bitmap; +import flash.events.Event; +import flash.text.TextField; +import flash.text.TextFormat; + +import openfl.Assets; +import flash.Lib; +import com.engine.game.Screen; +import com.engine.game.Game; +import com.engine.render.SpriteBatch; +import com.engine.render.BatchPrimitives; +import com.engine.render.Texture; +import com.engine.render.TileMap; +import com.engine.misc.Util; + +import com.engine.math.Vector2; +import com.engine.math.Vector3; + + + +/** + * ... + * @author djoker + */ +class TesteBatchTiles extends Screen +{ + + + var batch:SpriteBatch; + var primitives:BatchPrimitives; + var tilemap:TileMap; + var lastmouseX:Float; + var lastmouseY:Float; + var mouseX:Float; + var mouseY:Float; + var toutch:Bool; + var distx:Float; + var disty:Float; + var Toutch:Vector3 ; + var lastToutch:Vector3; + var position:Vector3; + var scroll:Int = 0; + + override public function show() + { + + + primitives = new BatchPrimitives( 100); + //tilemap = new TileMap(Assets.getText ("assets/scrol.tmx")); + tilemap = new TileMap(Assets.getText ("assets/map.tmx")); + //tilemap = new TileMap(Assets.getText ("assets/sewers.tmx")); + //tilemap = new TileMap(Assets.getText ("assets/desert.tmx")); + + batch = new SpriteBatch( 3000); + //trace( "map : w" + tilemap.widthInTiles + " h:" + tilemap.heightInTiles); + + + + var caption:TextField = new TextField(); + caption.x = game.screenWidth / 2-100; + caption.y = 20; + caption.width = 200; + caption.defaultTextFormat = new TextFormat ("_sans", 12, 0xffff00); + caption.text = "Test statics sprites "; + game.addChild(caption); + + Toutch = new Vector3(0, 0); + lastToutch = new Vector3(0, 0); + + position = new Vector3(0, 0, 0); + + + } + + public function renderTiles( x:Float , y:Float , sx:Int , sy:Int , width:Int , height:Int) + { + + for (ty in 0...height) + { + renderTile(x,y,sx,sy,width,ty); + } + + + } + public function renderTile( x:Float , y:Float , sx:Int , sy:Int , width:Int , ty:Int ) + { + var tw:Int = tilemap.tileWidth; + var th:Int = tilemap.tileHeight; + + for ( tx in 0...width) + { + if ((sx+tx < 0) || (sy+ty < 0)) + { + continue; + } + if ((sx+tx >= tilemap.widthInTiles) || (sy+ty >= tilemap.heightInTiles)) { + continue; + } + + var id = tilemap.getCell(sx+tx, sy+ty); + if (id >= 1) + { + var t:Clip = tilemap.getClip(id - 1); + + var x:Float = x+(tx*tw); + var y:Float = y+(ty*(th)); + batch.RenderTile(tilemap.image,x,y,tw,th,t, false, true,0); + } + + } + } + + + + public function draw_orthogonal( sx:Float, sy:Float, sw:Float, sh:Float, dx:Float, dy:Float) + { + var tw:Int = tilemap.tileWidth; + var th:Int = tilemap.tileHeight; + + var mx, my:Int=0; + var ystart:Int = Std.int(sy / th); + var yend:Int = Std.int((sy + sh) / th); + var xstart:Int = Std.int(sx / tw); + var xend:Int = Std.int((sx + sw) / th); + + + for (my in ystart...yend) + { + for (mx in xstart...xend) + { + + + var id = tilemap.getCell(mx, my); + if (id >= 1) + { + var t:Clip = tilemap.getClip(id - 1); + + var x:Float = mx*tw - sx + dx; + var y:Float = my*th - sy + dy; + batch.RenderTile(tilemap.image,x,y,tw,th,t, false, true,0); + } + } + } +} + override public function render(dt:Float) + { + + var tw:Int = tilemap.tileWidth; + var th:Int = tilemap.tileHeight; + + + batch.Begin(); + + draw_orthogonal(scroll, 0, 480,320, 20, 20); + //scroll++; +// renderTiles(0,0, scroll,5, 22,22); + +/* + for (y in 0...tilemap.heightInTiles) + { + for (x in 0...tilemap.widthInTiles) + { + + + var id = tilemap.getCell(x, y); + if (id >= 1) + { + //id = 2; + var t:Clip = tilemap.getClip(id - 1); + //var t:Clip = tilemap.getClipNum(id - 1); + + + var DrawX:Int =Std.int(position.x+ (x * tw)); + var DrawY:Int =Std.int(position.y+ (y * th)); + + var dst:Clip = new Clip(DrawX, DrawY, tw, th); + + // batch.RenderTile(tilemap.image,x*tw-0.5,y*th-0.5,tw,th,t, false, true,0); + batch.Blt(tilemap.image, dst,t, false, true, 0); + //batch.RenderClip(tilemap.image, x*tw,y*th, t, false, true, 0); + } + } + } + */ + + batch.End(); + + + primitives.begin(); + primitives.renderMode(false); + + primitives.line(lastToutch.x, lastToutch.y, Toutch.x, Toutch.y, 1, 0, 0); + + primitives.render(); + primitives.end; + + } + + override public function keyDown(key:Int) + { + if (key == 65) scroll--; + if (key == 68) scroll++; + + } + + override public function mouseDown(mousex:Float, mousey:Float) + { + toutch = true; + lastToutch.x = mousex; + lastToutch.y = mousey; + //lastToutch=camera.unproject(lastToutch); + + + } + override public function mouseMove(mousex:Float, mousey:Float) + { + + if (toutch==true) + { + + Toutch.x = mousex; + Toutch.y = mousey; + // Toutch=camera.unproject(Toutch); + + + var dir:Vector3 = Vector3.Sub(Toutch, lastToutch); + dir.normalize(); + + //camera.position = Vector3.Add(camera.position, dir); + position.x += (dir.x * game.deltaTime*1000); + position.y += (dir.y * game.deltaTime*1000); + + } + } + override public function mouseUp(mousex:Float, mousey:Float) + { + toutch = false; + } + + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TesteBitmap.hx b/src/com/djoker/glteste/TesteBitmap.hx new file mode 100755 index 0000000..c8da58f --- /dev/null +++ b/src/com/djoker/glteste/TesteBitmap.hx @@ -0,0 +1,51 @@ +package com.djoker.glteste; + +import openfl.Assets; + +import flash.display.Bitmap; +import flash.display.BitmapData; +import flash.utils.ByteArray; +import flash.Lib; + + + +import com.engine.game.Screen; + +/** + * ... + * @author djoker + */ +class TesteBitmap extends Screen +{ + + var particles : Array; + var bitmapData:BitmapData; + + + +public function addParticle() +{ + var particle:Movable = new Movable(bitmapData); + particle.init(); + particles.push(particle); + Lib.current.stage.addChild(particle); +} + + override public function show() + { + bitmapData = Assets.getBitmapData("assets/zazaka.png"); + particles = []; + for(i in 0...200) + addParticle(); + } + + override public function render(dt:Float) + { + for(p in particles) + { + p.move(dt); + } + + } + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TesteCloud.hx b/src/com/djoker/glteste/TesteCloud.hx new file mode 100755 index 0000000..f890461 --- /dev/null +++ b/src/com/djoker/glteste/TesteCloud.hx @@ -0,0 +1,72 @@ +package com.djoker.glteste; + +import flash.events.Event; +import flash.text.TextField; +import flash.text.TextFormat; +import openfl.Assets; + +import com.engine.game.Screen; +import com.engine.game.Game; +import com.engine.render.SpriteCloud; +import com.engine.render.Texture; + +import com.engine.render.TileMap; +import com.engine.misc.Util; + + +/** + * ... + * @author djoker + */ +class TesteCloud extends Screen +{ + + var tex :Texture; + var batch:SpriteCloud; + + var tilemap:TileMap; + + + override public function show() + { + + tex = new Texture("assets/texture.png"); + + batch = new SpriteCloud(tex,500); + for (i in 0...1000) + { + var particle:Particle = new Particle(tex); + particle.Init(); + particle.x = Util.randf(10, 630); + particle.y = Util.randf(10, 470); + batch.addImage(particle); + } + + + var caption:TextField = new TextField(); + caption.x = Game.viewWidth / 2-100; + caption.y = 20; + caption.width = 200; + caption.defaultTextFormat = new TextFormat ("_sans", 12, 0xffff00); + caption.text = "Test 1000 statics sprites "; + game.addChild(caption); + + + tilemap= new TileMap(Assets.getText ("assets/map.tmx")); + + } + + override public function render(dt:Float) + { + + batch.render(); + } + + + + + + + + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TesteCloudTiles.hx b/src/com/djoker/glteste/TesteCloudTiles.hx new file mode 100755 index 0000000..5a0071c --- /dev/null +++ b/src/com/djoker/glteste/TesteCloudTiles.hx @@ -0,0 +1,151 @@ +package com.djoker.glteste; + +import com.engine.render.Clip; +import flash.display.Bitmap; +import flash.events.Event; +import flash.text.TextField; +import flash.text.TextFormat; + +import openfl.Assets; +import flash.Lib; +import com.engine.game.Screen; +import com.engine.game.Game; +import com.engine.render.SpriteCloud; +import com.engine.render.BatchPrimitives; +import com.engine.render.Texture; +import com.engine.render.TileMap; +import com.engine.misc.Util; + +import com.engine.math.Vector2; +import com.engine.math.Vector3; + + + +/** + * ... + * @author djoker + */ +class TesteCloudTiles extends Screen +{ + + + var batch:SpriteCloud; + var primitives:BatchPrimitives; + + var tilemap:TileMap; + var lastmouseX:Float; + var lastmouseY:Float; + var mouseX:Float; + var mouseY:Float; + var toutch:Bool; + var distx:Float; + var disty:Float; + var Toutch:Vector3 ; + var lastToutch:Vector3; + + + override public function show() + { + + + + primitives = new BatchPrimitives( 100); + //tilemap = new TileMap(Assets.getText ("assets/scrol.tmx")); + //tilemap = new TileMap(Assets.getText ("assets/map.tmx")); + //tilemap = new TileMap(Assets.getText ("assets/sewers.tmx")); + tilemap = new TileMap(Assets.getText ("assets/desert.tmx")); + + batch = new SpriteCloud(tilemap.image, 3000); + //trace( "map : w" + tilemap.widthInTiles + " h:" + tilemap.heightInTiles); + + + var tw:Int = tilemap.tileWidth; + var th:Int = tilemap.tileHeight; + + + for (y in 0...tilemap.heightInTiles) + { + for (x in 0...tilemap.widthInTiles) + { + + + var id = tilemap.getCell(x, y); + if (id >= 1) + { + var t:Clip = tilemap.getClip(id - 1); + batch.addTile(x*tw,y*th,tw,th,t, false, true); + } + } + } + + + + var caption:TextField = new TextField(); + caption.x = game.screenWidth / 2-100; + caption.y = 20; + caption.width = 200; + caption.defaultTextFormat = new TextFormat ("_sans", 12, 0xffff00); + caption.text = "Test "+batch.currentBatchSize+" statics sprites "; + game.addChild(caption); + + Toutch = new Vector3(0, 0); + lastToutch = new Vector3(0, 0); + + + } + + override public function render(dt:Float) + { + // lastToutch = Toutch; + + + + batch.render(); + + primitives.begin(); + primitives.renderMode(false); + + primitives.line(lastToutch.x, lastToutch.y, Toutch.x, Toutch.y, 1, 0, 0); + + primitives.render(); + primitives.end; + } + + + + override public function mouseDown(mousex:Float, mousey:Float) + { + toutch = true; + lastToutch.x = mousex; + lastToutch.y = mousey; + //lastToutch=camera.unproject(lastToutch); + + + } + override public function mouseMove(mousex:Float, mousey:Float) + { + + if (toutch==true) + { + + Toutch.x = mousex; + Toutch.y = mousey; + // Toutch=camera.unproject(Toutch); + + + var dir:Vector3 = Vector3.Sub(Toutch, lastToutch); + dir.normalize(); + + //camera.position = Vector3.Add(camera.position, dir); + batch.position.x += (dir.x * game.deltaTime*1000); + batch.position.y += (dir.y * game.deltaTime*1000); + + } + } + override public function mouseUp(mousex:Float, mousey:Float) + { + toutch = false; + } + + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TesteDraTiles.hx b/src/com/djoker/glteste/TesteDraTiles.hx new file mode 100755 index 0000000..b957855 --- /dev/null +++ b/src/com/djoker/glteste/TesteDraTiles.hx @@ -0,0 +1,122 @@ +package com.djoker.glteste; + +import com.engine.game.Screen; +import flash.geom.Rectangle; + +import openfl.Assets; + +import flash.display.Bitmap; +import flash.display.BitmapData; +import flash.utils.ByteArray; +import flash.Lib; + +import com.engine.direct.TileBatch; +import com.engine.direct.TileImage; + + +class MoveSprite extends TileImage +{ + var dx:Float; + var dy:Float; + var da:Float; + + + + public function init() + { + + x = 320; + y = 240; + this.Rotation = 0; + dx = Math.random()*200.0 - 100.0; + dy = Math.random()*200.0 - 100.0; + da = Math.random() * 10.2 - 12.1; + + + + + Red = Math.random(); + Green = Math.random(); + Blue = Math.random(); + Alpha = Math.random(); + + + ScaleX = Math.random() * 1.1 + 0.1; + ScaleY = Math.random() * 1.1 + 0.1; + } + + + + override public function update():Void + { + move(0.03); + } + + + public function move(dt:Float) + { + var rad = 30 * ScaleX; + + x+=dx*dt; + if (x640-rad) + { + x = 640-rad; + dx = -dx; + } + + y+=dy*dt; + if (y480-rad) + { + y = 480-rad; + dy = -dy; + } + + this.Rotation += da; + + + } +} + + +/** + * ... + * @author djoker + */ +class TesteDraTiles extends Screen +{ + var bitmapData:BitmapData; + var batch:TileBatch; + + + override public function show() + { + bitmapData = Assets.getBitmapData("assets/zazaka.png"); + batch = new TileBatch(bitmapData); + batch.addTileRect(new Rectangle(0, 0, 64, 64)); + for (i in 0...200) + { + var spr = new MoveSprite(0, 0, 0); + spr.init(); + batch.add(spr); + } + Lib.current.stage.addChild(batch); + + + } + + override public function render(dt:Float) + { + // batch.render(); + } + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TestePrimitives.hx b/src/com/djoker/glteste/TestePrimitives.hx new file mode 100755 index 0000000..15e2b06 --- /dev/null +++ b/src/com/djoker/glteste/TestePrimitives.hx @@ -0,0 +1,83 @@ +package com.djoker.glteste; + +import com.engine.game.Screen; + +import com.engine.render.BatchPrimitives; +import com.engine.render.Texture; +import com.engine.render.OrthoCamera; + +import flash.events.Event; +import flash.text.TextField; +import flash.text.TextFormat; + +/** + * ... + * @author djoker + */ +class TestePrimitives extends Screen +{ + + + var batch:BatchPrimitives; + var camera:OrthoCamera; + + + + + + + override public function show() + { + + + camera = new OrthoCamera(640, 480); + batch = new BatchPrimitives(camera, 500); + + + var caption:TextField = new TextField(); + caption.x = game.screnWidth / 2-100; + caption.y = 20; + caption.width = 200; + caption.defaultTextFormat = new TextFormat ("_sans", 12, 0xaa00ff); + caption.text = "Teste Primitives Batch"; + game.addChild(caption); + + + } + + override public function render(dt:Float) + { + camera.Update(); + + + batch.begin(); + + batch.renderMode(false); + batch.line(10, 10, 100, 100, 1, 0, 1); + batch.rect(100, 100, 90, 120, 1, 1, 1); + batch.circle(100, 100, 12, 8, 1, 1, 1, 1); + batch.ellipse(300, 90, 55, 15, 8, 1, 1, 1, 1); + batch.render(); + + batch.renderMode(true); + batch.fillrect(200, 200, 50, 50, 1, 0, 0, 1); + batch.fillrect(280, 200, 50, 50, 1, 0, 1, 1); + batch.fillcircle(200, 100, 8, 18, 1, 1, 1, 1); + batch.fillellipse(300, 100, 55, 15, 8, 1, 1, 1, 1); + batch.render(); + + batch.end(); + + } + override public function resize(width:Int, height:Int) + { + game.setViewPort(0, 0, width, height); + } + + + + + + + +} \ No newline at end of file diff --git a/src/com/djoker/glteste/TesteTiles.hx b/src/com/djoker/glteste/TesteTiles.hx new file mode 100755 index 0000000..6631424 --- /dev/null +++ b/src/com/djoker/glteste/TesteTiles.hx @@ -0,0 +1,147 @@ +package com.djoker.glteste; + +import com.engine.render.Clip; +import flash.display.Bitmap; +import flash.events.Event; +import flash.text.TextField; +import flash.text.TextFormat; + +import openfl.Assets; +import flash.Lib; +import com.engine.game.Screen; +import com.engine.game.Game; +import com.engine.render.SpriteBatch; +import com.engine.render.BatchPrimitives; +import com.engine.render.Texture; +import com.engine.render.TileMap; +import com.engine.misc.Util; + +import com.engine.math.Vector2; +import com.engine.math.Vector3; + + + +/** + * ... + * @author djoker + */ +class TesteTiles extends Screen +{ + + + var batch:SpriteBatch; + var primitives:BatchPrimitives; + var tilemap:TileMap; + var lastmouseX:Float; + var lastmouseY:Float; + var mouseX:Float; + var mouseY:Float; + var toutch:Bool; + var distx:Float; + var disty:Float; + var Toutch:Vector3 ; + var lastToutch:Vector3; + var position:Vector3; + var scroll:Int = 0; + + + + + + override public function show() + { + + position = new Vector3(0, 0, 0); + + + primitives = new BatchPrimitives( 100); + //tilemap = new TileMap(Assets.getText ("assets/scrol.tmx")); + tilemap = new TileMap(Assets.getText ("assets/map.tmx")); + //tilemap = new TileMap(Assets.getText ("assets/sewers.tmx")); + //tilemap = new TileMap(Assets.getText ("assets/desert.tmx")); + + // batch = new SpriteBatch( camera, 3000); + //trace( "map : w" + tilemap.widthInTiles + " h:" + tilemap.heightInTiles); + + + + var caption:TextField = new TextField(); + caption.x = game.screenWidth / 2-100; + caption.y = 20; + caption.width = 200; + caption.defaultTextFormat = new TextFormat ("_sans", 12, 0xffff00); + caption.text = "Test statics sprites "; + game.addChild(caption); + + Toutch = new Vector3(0, 0); + lastToutch = new Vector3(0, 0); + + + } + + + override public function keyDown(key:Int) + { + if (key == 65) scroll--; + if (key == 68) scroll++; + + } + + override public function render(dt:Float) + { + + + //tilemap.render(); + tilemap.renderDinamic(scroll,0); + //tilemap.renderStatic(); + + + + primitives.begin(); + primitives.renderMode(false); + + primitives.line(lastToutch.x, lastToutch.y, Toutch.x, Toutch.y, 1, 0, 0); + + primitives.render(); + primitives.end; + + } + + + + override public function mouseDown(mousex:Float, mousey:Float) + { + toutch = true; + lastToutch.x = mousex; + lastToutch.y = mousey; + //lastToutch=camera.unproject(lastToutch); + + + } + override public function mouseMove(mousex:Float, mousey:Float) + { + + if (toutch==true) + { + + Toutch.x = mousex; + Toutch.y = mousey; + // Toutch=camera.unproject(Toutch); + + + var dir:Vector3 = Vector3.Sub(Toutch, lastToutch); + dir.normalize(); + + //camera.position = Vector3.Add(camera.position, dir); + tilemap.position.x += (dir.x * game.deltaTime*1000); + tilemap.position.y += (dir.y * game.deltaTime*1000); + + } + } + override public function mouseUp(mousex:Float, mousey:Float) + { + toutch = false; + } + + +} \ No newline at end of file diff --git a/src/com/engine/Stats.hx b/src/com/engine/Stats.hx new file mode 100755 index 0000000..32ebf9b --- /dev/null +++ b/src/com/engine/Stats.hx @@ -0,0 +1,181 @@ +/** + * Hi-ReS! Stats + * + * Released under MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * How to use: + * + * addChild( new Stats() ); + * + * or + * + * addChild( new Stats( { bg: 0xffffff } ); + * + * version log: + * + * 09.03.28 2.1 Mr.doob + Theme support. + * 09.02.21 2.0 Mr.doob + Removed Player version, until I know if it's really needed. + * + Added MAX value (shows Max memory used, useful to spot memory leaks) + * + Reworked text system / no memory leak (original reason unknown) + * + Simplified + * 09.02.07 1.5 Mr.doob + onRemovedFromStage() (thx huihuicn.xu) + * 08.12.14 1.4 Mr.doob + Code optimisations and version info on MOUSE_OVER + * 08.07.12 1.3 Mr.doob + Some speed and code optimisations + * 08.02.15 1.2 Mr.doob + Class renamed to Stats (previously FPS) + * 08.01.05 1.2 Mr.doob + Click changes the fps of flash (half up increases, half down decreases) + * 08.01.04 1.1 Mr.doob + Shameless ripoff of Alternativa's FPS look :P + * Theo + Log shape for MEM + * + More room for MS + * 07.12.13 1.0 Mr.doob + First version + **/ + +package engine; + + +import flash.display.Bitmap; +import flash.display.BitmapData; +import flash.display.Sprite; +import flash.events.Event; +import flash.events.MouseEvent; +import flash.geom.Rectangle; +import flash.system.System; +import flash.text.StyleSheet; +import flash.text.TextField; +import flash.Lib; +import flash.xml.XML; + +/** +* Hi-ReS! Stats FPS, MS and MEM, all in one. +*/ +typedef Theme = { bg: UInt, fps: UInt, ms: UInt, mem: UInt, memmax: UInt } + +class Stats extends Sprite +{ + private var _xml : XML; + + private var _text : TextField; + private var _style : StyleSheet; + + private var _timer : Int; + private var _fps : Int; + private var _ms : Int; + private var _ms_prev : Int; + private var _mem : Float; + private var _mem_max : Float; + + private var _graph : BitmapData; + private var _rectangle : Rectangle; + + private var _fps_graph : UInt; + private var _mem_graph : UInt; + private var _mem_max_graph : UInt; + + private var _theme : Theme; + + /** + * Hi-ReS! Stats FPS, MS and MEM, all in one. + * + * @param theme Example: { bg: 0x202020, fps: 0xC0C0C0, ms: 0x505050, mem: 0x707070, memmax: 0xA0A0A0 } + */ + public function new( ?theme : Theme ) : Void + { + super(); + _theme = { bg: 0x000033, fps: 0xffff00, ms: 0x00ff00, mem: 0x00ffff, memmax: 0xff0070 } + if (theme != null) + { + _theme = theme; + } + + addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true); + } + + private function init(e : Event) : Void + { + removeEventListener(Event.ADDED_TO_STAGE, init); + + graphics.beginFill(_theme.bg); + graphics.drawRect(0, 0, 70, 50); + graphics.endFill(); + + _mem_max = 0; + + _xml = new XML('FPS:MS:MEM:MAX:'); + + _style = new StyleSheet(); + _style.setStyle("xml", {fontSize:'9px', fontFamily:'_sans', leading:'-2px'}); + _style.setStyle("fps", {color: hex2css(_theme.fps)}); + _style.setStyle("ms", {color: hex2css(_theme.ms)}); + _style.setStyle("mem", {color: hex2css(_theme.mem)}); + _style.setStyle("memMax", {color: hex2css(_theme.memmax)}); + + _text = new TextField(); + _text.width = 70; + _text.height = 50; + _text.styleSheet = _style; + _text.condenseWhite = true; + _text.selectable = false; + _text.mouseEnabled = false; + addChild(_text); + + var bitmap : Bitmap = new Bitmap( _graph = new BitmapData(70, 50, false, _theme.bg) ); + bitmap.y = 50; + addChild(bitmap); + + _rectangle = new Rectangle( 0, 0, 1, _graph.height ); + + addEventListener(MouseEvent.CLICK, onClick); + addEventListener(Event.ENTER_FRAME, update); + } + + private function update(e : Event) : Void + { + _timer = Lib.getTimer(); + + if( _timer - 1000 > _ms_prev ) + { + _ms_prev = _timer; + _mem = cast ((System.totalMemory * 0.000000954)/*.toFixed(3)*/); + _mem_max = _mem_max > _mem ? _mem_max : _mem; + + _fps_graph = Std.int(Math.min( 50, ( _fps / stage.frameRate ) * 50 )); + _mem_graph = Std.int(Math.min( 50, Math.sqrt( Math.sqrt( _mem * 5000 ) ) ) ) - 2; + _mem_max_graph = Std.int(Math.min( 50, Math.sqrt( Math.sqrt( _mem_max * 5000 ) ) ) ) - 2; + + _graph.scroll( 1, 0 ); + + _graph.fillRect( _rectangle , _theme.bg ); + _graph.setPixel( 0, _graph.height - _fps_graph, _theme.fps); + _graph.setPixel( 0, _graph.height - ( ( _timer - _ms ) >> 1 ), _theme.ms ); + _graph.setPixel( 0, _graph.height - _mem_graph, _theme.mem); + _graph.setPixel( 0, _graph.height - _mem_max_graph, _theme.memmax); + + untyped _xml.fps = "FPS: " + _fps + " / " + stage.frameRate; + untyped _xml.mem = "MEM: " + _mem; + untyped _xml.memMax = "MAX: " + _mem_max; + + _fps = 0; + } + + _fps++; + + untyped _xml.ms = "MS: " + (_timer - _ms); + _ms = _timer; + + _text.htmlText = _xml.toXMLString(); + } + + private function onClick(e : MouseEvent) : Void + { + mouseY / height > .5 ? stage.frameRate-- : stage.frameRate++; + untyped _xml.fps = "FPS: " + _fps + " / " + stage.frameRate; + _text.htmlText = _xml.toXMLString(); + } + + // .. Utils + + private function hex2css( color : Int ) : String + { + return "#" + StringTools.hex(color); + } +} \ No newline at end of file diff --git a/src/com/engine/direct/Animation.hx b/src/com/engine/direct/Animation.hx new file mode 100755 index 0000000..d0b1c13 --- /dev/null +++ b/src/com/engine/direct/Animation.hx @@ -0,0 +1,33 @@ +package com.engine.direct ; + + +class Animation +{ + + public function new(name:String, frames:Array, frameRate:Float = 0, loop:Bool = true) + { + this.name = name; + this.frames = frames; + this.frameRate = frameRate; + this.loop = loop; + this.frameCount = frames.length; + } + + + + + + + public var name(default, null):String; + + public var frames(default, null):Array; + + + public var frameRate(default, null):Float; + + public var frameCount(default, null):Int; + + + public var loop(default, null):Bool; + +} \ No newline at end of file diff --git a/src/com/engine/direct/SpriteClip.hx b/src/com/engine/direct/SpriteClip.hx new file mode 100755 index 0000000..a8cc995 --- /dev/null +++ b/src/com/engine/direct/SpriteClip.hx @@ -0,0 +1,30 @@ +package com.engine.direct ; + +/** + * ... + * @author djoker + */ +class SpriteClip +{ + + public var height:Int; + public var offsetX:Int; + public var offsetY:Int; + public var width:Int; + public var x:Int; + public var y:Int; + + + public function new (x:Int, y:Int, width:Int, height:Int, offsetX:Int, offsetY:Int) { + + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.offsetX = offsetX; + this.offsetY = offsetY; + + } + + +} \ No newline at end of file diff --git a/src/com/engine/direct/TileBatch.hx b/src/com/engine/direct/TileBatch.hx new file mode 100755 index 0000000..7cf27af --- /dev/null +++ b/src/com/engine/direct/TileBatch.hx @@ -0,0 +1,410 @@ +package com.engine.direct ; +import flash.display.BitmapData; +import flash.display.Bitmap; +import flash.display.InteractiveObject; +import flash.display.Sprite; +import flash.geom.Matrix; +import flash.events.Event; +import openfl.display.Tilesheet; +import flash.Vector; +import flash.Lib; +import flash.geom.Point; +import flash.geom.Rectangle; +import haxe.xml.Fast; + +/** + * ... + * @author djoker + */ +class TileBatch extends Sprite +{ + private var tilesheet: Tilesheet; + private var tileData:Array; + private var sprites:Array; + private var clips:Vector; + private var sort:Bool; + private var length:Int; + private var maxSize:Int; + private var numTile:Int; + private var currentTime:Int; + private var previousTime:Int; + + public function new(image:BitmapData) + { + super(); + tilesheet = new Tilesheet(image); + tileData = new Array(); + sprites = new Array(); + clips = new Vector(); + length = 0; + addEventListener( Event.ENTER_FRAME, onEnterFrame ); + sort = false; + maxSize = 1000; + numTile = 0; + previousTime = Lib.getTimer (); + } + + public function parseXML (data:String):Void + { + var frameIndex:Map = new Map (); + + var xml:Xml = Xml.parse (data); + var spriteSheetNode:Xml = xml.firstElement (); + + for (behaviorNode in spriteSheetNode.elements ()) { + + var behaviorNodeFast:Fast = new Fast (behaviorNode); + var behaviorFrames:Array = new Array (); + + var allFramesText:String = behaviorNodeFast.innerData; + var framesText:Array = allFramesText.split (";"); + + for (frameText in framesText) { + + if (!frameIndex.exists (frameText)) { + + + var components:Array < String > = frameText.split (","); + + addTileRect(new Rectangle( + Std.parseInt (components[0]), + Std.parseInt (components[1]), + Std.parseInt (components[2]), + Std.parseInt (components[3])), + new Point( + -Std.parseInt (components[4]), + -Std.parseInt (components[5]))); + + + var frame:SpriteClip = new SpriteClip (Std.parseInt (components[0]), Std.parseInt (components[1]), Std.parseInt (components[2]), Std.parseInt (components[3]), -Std.parseInt (components[4]), -Std.parseInt (components[5])); + clips.push(frame); + } + + + + } + + + + } + + } + public function getClip(index:Int):SpriteClip + { + return clips[index]; + } + public function addTileRect(rectangle:Rectangle, centerPoint:Point = null):Int + { + numTile++; + return tilesheet.addTileRect(rectangle, centerPoint); + } + + + + private function sortObjects(a:TileImage, b:TileImage):Int + { + if (a.Layer == b.Layer) + return 0; + if (a.Layer > b.Layer) + return 1; + else + return -1; + } + public function clear():Void + { + length = 0; + sprites.splice(0, sprites.length); + } + public function kill():Void + { + var i:Int = 0; + var basic:TileImage = null; + + while (i < length) + { + basic = sprites[i++]; + + if ((basic != null) ) + { + basic.kill(); + } + } + + + } + + public function add(Object:TileImage):TileImage + { + if (Object == null) + { + return null; + } + + + if (Util.indexOf(sprites, Object) >= 0) + { + sort = true; + return Object; + } + + // First, look for a null entry where we can add the object. + var i:Int = 0; + var l:Int = sprites.length; + + while (i < l) + { + if (sprites[i] == null) + { + sprites[i] = Object; + + if (i >= length) + { + length = i + 1; + } + sort = true; + return Object; + } + i++; + } + + // Failing that, expand the array (if we can) and add the object. + if (maxSize > 0) + { + if (sprites.length >= maxSize) + { + sort = true; + return Object; + } + else if (sprites.length * 2 <= maxSize) + { + Util.setLength(sprites, sprites.length * 2); + } + else + { + Util.setLength(sprites, maxSize); + } + } + else + { + Util.setLength(sprites, sprites.length * 2); + } + + sprites[i] = Object; + sort = true; + length = i + 1; + + return Object; + } + public function numObjects():Int + { + return length; + } + public function destroy():Void + { + if (sprites != null) + { + var i:Int = 0; + var basic:TileImage = null; + + while (i < length) + { + basic = sprites[i++]; + + if (basic != null) + { + basic.destroy(); + } + } + + + sprites = null; + } + + + + + } + public function remove(obj:TileImage, Splice:Bool = false):TileImage + + { + if (sprites == null) + { + return null; + } + + var index:Int = Util.indexOf(sprites, obj); + + if ((index < 0) || (index >= sprites.length)) + { + return null; + } + if (Splice) + { + sprites.splice(index, 1); + } + else + { + sprites[index] = null; + } + + return obj; + } + public function dispose():Void + { + removeEventListener( Event.ENTER_FRAME, onEnterFrame ); + } + + public function render() + { + var currentTime = Lib.getTimer (); + var deltaTime:Int = currentTime - previousTime; + + graphics.clear(); + var flags = Tilesheet.TILE_TRANS_2x2 | Tilesheet.TILE_ALPHA | Tilesheet.TILE_BLEND_NORMAL | Tilesheet.TILE_RGB; + var i:Int = 0; + var basic:TileImage = null; + while (i < sprites.length) + { + basic = sprites[i++]; + + if ((basic != null) && basic.Visible) + { + basic.updateAnim(deltaTime / 100); + basic.update(); + renderObject(tileData, basic); + } + } + + tilesheet.drawTiles(graphics,tileData, false, flags); + tileData = []; + if (sort) + { + sprites.sort(sortObjects); + sort = false; + + } + previousTime = currentTime; + } + + private function onEnterFrame(e:Event):Void + { + var currentTime = Lib.getTimer (); + var deltaTime:Int = currentTime - previousTime; + + graphics.clear(); + var flags = Tilesheet.TILE_TRANS_2x2 | Tilesheet.TILE_ALPHA | Tilesheet.TILE_BLEND_NORMAL | Tilesheet.TILE_RGB; + var i:Int = 0; + var basic:TileImage = null; + while (i < sprites.length) + { + basic = sprites[i++]; + + if ((basic != null) && basic.Visible) + { + basic.updateAnim(deltaTime / 100); + basic.update(); + renderObject(tileData, basic); + } + } + + tilesheet.drawTiles(graphics,tileData, false, flags); + tileData = []; + if (sort) + { + sprites.sort(sortObjects); + sort = false; + + } + previousTime = currentTime; + } +public function renderObject(data:Array,obj:TileImage) + { + var mTransformationMatrix:Matrix = obj.getMatrix(); + data.push(mTransformationMatrix.tx); + data.push(mTransformationMatrix.ty); + data.push (obj.Graph); + data.push(mTransformationMatrix.a); + data.push(mTransformationMatrix.b); + data.push(mTransformationMatrix.c); + data.push(mTransformationMatrix.d); + data.push(obj.Red); + data.push(obj.Green); + data.push(obj.Blue); + data.push(obj.Alpha); + } + public function renderTile(data:Array, tile:Int, mX:Float, mY:Float, + mPivotX:Float,mPivotY:Float, + mScaleX:Float, mScaleY:Float, + mSkewX:Float,mSkewY:Float, + mRotation:Float, + red:Float, green:Float, blue:Float, alpha:Float) + { + + var mTransformationMatrix:Matrix = new Matrix(); + mTransformationMatrix.identity(); + + if (mSkewX == 0.0 && mSkewY == 0.0) + { + + if (mRotation == 0.0) + { + + Util.matrixsetTo(mTransformationMatrix,mScaleX, 0.0, 0.0, mScaleY, mX - mPivotX * mScaleX, mY - mPivotY * mScaleY); + } + else + { + var cos = Math.cos(mRotation * Math.PI / -180); + var sin = Math.sin(mRotation * Math.PI / -180); + + var a:Float = mScaleX * cos; + var b:Float = mScaleX * sin; + var c:Float = mScaleY * -sin; + var d:Float = mScaleY * cos; + var tx:Float = mX - mPivotX * a - mPivotY * c; + var ty:Float = mY - mPivotX * b - mPivotY * d; + + Util.matrixsetTo(mTransformationMatrix,a, b, c, d, tx, ty); + } + } + else + { + mTransformationMatrix.identity(); + mTransformationMatrix.scale(mScaleX, mScaleY); + Util.skew(mTransformationMatrix, mSkewX, mSkewY); + mTransformationMatrix.rotate(mRotation); + mTransformationMatrix.translate(mX, mY); + + if (mPivotX != 0.0 || mPivotY != 0.0) + { + + mTransformationMatrix.tx = mX - mTransformationMatrix.a * mPivotX + - mTransformationMatrix.c * mPivotY; + mTransformationMatrix.ty = mY - mTransformationMatrix.b * mPivotX + - mTransformationMatrix.d * mPivotY; + } + } + + + data.push(mTransformationMatrix.tx); + data.push(mTransformationMatrix.ty); + data.push (tile); + data.push(mTransformationMatrix.a); // m00 + data.push(mTransformationMatrix.b); // m10 + data.push(mTransformationMatrix.c); // m01 + data.push(mTransformationMatrix.d); // m11 + + + + data.push( red); + data.push(green); + data.push(blue); + data.push(alpha); + } + + public var numTiles(get, set) : Int; + private inline function get_numTiles():Int { return numTile;} + private function set_numTiles( v : Int ):Int {numTile = v;return numTile;} + + + +} \ No newline at end of file diff --git a/src/com/engine/direct/TileImage.hx b/src/com/engine/direct/TileImage.hx new file mode 100755 index 0000000..0dd528f --- /dev/null +++ b/src/com/engine/direct/TileImage.hx @@ -0,0 +1,272 @@ +package com.engine.direct; + +import flash.display.BitmapData; +import flash.display.Bitmap; +import flash.display.Sprite; +import flash.geom.Matrix; +import flash.events.Event; + +/** + * ... + * @author djoker + */ + +typedef CallbackFunction = Void -> Void; + +class TileImage +{ + + public var width:Int; + public var height:Int; + public var originX:Int; + public var originY:Int; + + public var complete:Bool; + public var callbackFunc:CallbackFunction; + public var rate:Float; + private var _frameCount:Int; + private var _anims:Map; + private var _anim:Animation; + private var _index:Int; + private var _frame:Int; + private var _timer:Float; + + public var x:Float; + public var y:Float; + public var PivotX:Float; + public var PivotY:Float; + public var ScaleX:Float; + public var ScaleY:Float; + public var SkewX:Float; + public var SkewY:Float; + public var Rotation:Float; + public var Alpha:Float; + public var Red:Float; + public var Green:Float; + public var Blue:Float; + public var Visible:Bool; + private var mName:String; + private var mParent:TileImage; + private var mTransformationMatrix:Matrix; + public var Layer:Int; + public var Graph:Int; + + public var name(get, set) : String; + public function get_name():String { return mName; } + public function set_name(value:String):String { mName = value; return mName; } + + + + public function new(x:Float,y:Float,graph:Int) + { + this.x = this.y = PivotX = PivotY = Rotation = SkewX = SkewY = 0.0; + ScaleX = ScaleY = Alpha=Red=Green=Blue = 1.0; + Visible = true; + Layer = 0; + this.x = x; + this.y = y; + this.Graph = graph; + mTransformationMatrix = new Matrix(); + complete = true; + rate = 1; + callbackFunc = null; + _anims = new Map(); + originX = originY = 0; + width = height = 0; + + } + + public function destroy():Void + { + + } + public function update():Void + { + //updateAnim(); + } + public function kill():Void + { + + } + + public function getMatrix():Matrix + { + + + mTransformationMatrix.identity(); + + mTransformationMatrix.scale(ScaleX, ScaleY); + + if (SkewX != 0.0 && SkewY != 0.0) + { + Util.skew(mTransformationMatrix, SkewX, SkewY); + } + mTransformationMatrix.rotate(Rotation); + mTransformationMatrix.translate(x, y); + + if (PivotX != 0.0 || PivotY != 0.0) + { + + mTransformationMatrix.tx = x - mTransformationMatrix.a * PivotX + - mTransformationMatrix.c * PivotY; + mTransformationMatrix.ty = y - mTransformationMatrix.b * PivotX + - mTransformationMatrix.d * PivotY; + } + + + + return mTransformationMatrix; + } + + public function add(name:String, frames:Array, frameRate:Float = 0, loop:Bool = true):Animation + { + if (_anims.get(name) != null) return null; + for (i in 0...frames.length) + { + // frames[i] %= _frameCount; + // if (frames[i] < 0) frames[i] += _frameCount; + } + var anim = new Animation(name, frames, frameRate, loop); + _anims.set(name, anim); + _frameCount = anim.frameCount; + return anim; + } + public function addFrames(name:String, minf:Int,maxf:Int, frameRate:Float = 0, loop:Bool = true):Animation + { + if (_anims.get(name) != null) return null; + var frames:Array= new Array(); + for (i in minf...maxf) + { + frames.push(i); + } + var anim = new Animation(name, frames, frameRate, loop); + _anims.set(name, anim); + _frameCount = anim.frameCount; + return anim; + } + public function play(name:String = "", reset:Bool = false):Animation + { + if (!reset && _anim != null && _anim.name == name) return _anim; + if (_anims.exists(name)) + { + _anim = _anims.get(name); + _timer = _index = 0; + _frame = _anim.frames[0]; + complete = false; + } + else + { + _anim = null; + _frame = _index = 0; + complete = true; + } + + return _anim; + } + public function updateAnim(elapsed:Float) + { + if (_anim != null && !complete) + { + _timer += (_anim.frameRate * elapsed) * rate; + if (_timer >= 1) + { + while (_timer >= 1) + { + _timer --; + _index ++; + if (_index == _anim.frameCount) + { + if (_anim.loop) + { + _index = 0; + if (callbackFunc != null) callbackFunc(); + } + else + { + _index = _anim.frameCount - 1; + complete = true; + if (callbackFunc != null) callbackFunc(); + break; + } + } + } + if (_anim != null) _frame = Std.int(_anim.frames[_index]); + Graph = _frame; + } + } + } + public var frame(get_frame, set_frame):Int; + private function get_frame():Int { return _frame; } + private function set_frame(value:Int):Int + { + _anim = null; + value %= _frameCount; + if (value < 0) value = _frameCount + value; + if (_frame == value) return _frame; + _frame = value; + return _frame; + } + public var frameCount(get_frameCount, null):Int; + private function get_frameCount():Int { return _frameCount; } + public var currentAnim(get_currentAnim, null):String; + private function get_currentAnim():String { return (_anim != null) ? _anim.name : ""; } + /* + public var visible(get, set) : Bool; + private inline function get_visible():Bool { return mVisible;} + private function set_visible( v : Bool ):Bool {mVisible = v;return mVisible;} + + + public var alpha(get, set) : Float; + private inline function get_alpha():Float { return mAlpha;} + private function set_alpha( v : Float ):Float {mAlpha = v;return mAlpha;} + + public var red(get, set) : Float; + private inline function get_red():Float { return mRed;} + private function set_red( v : Float ):Float {mRed = v;return mRed;} + + public var green(get, set) : Float; + private inline function get_green():Float { return mGreen;} + private function set_green( v : Float ):Float {mGreen = v;return mGreen;} + + public var blue(get, set) : Float; + private inline function get_blue():Float { return mBlue;} + private function set_blue( v : Float ):Float {mBlue = v;return mBlue;} + + + public var x(get, set) : Float; + private inline function get_x():Float { return mX;} + private function set_x( v : Float ):Float {mX = v;return mX;} + + public var y(get, set) : Float; + private inline function get_y():Float { return mY;} + private function set_y( v : Float ):Float {mY = v;return mY;} + + public var layer(get, set) : Int; + private inline function get_layer():Int { return mLayer;} + private function set_layer( v : Int ):Int {mLayer = v;return mLayer;} + + public var graph(get, set) : Int; + private inline function get_graph():Int { return mGraph;} + private function set_graph( v : Int ):Int { mGraph = v; return mGraph; } + + public var PivotX(get, set) : Float; + private inline function get_PivotX():Float { return mPivotX;} + private function set_PivotX( v : Float ):Float {mPivotX = v;return mPivotX;} + + public var PivotY(get, set) : Float; + private inline function get_PivotY():Float { return mPivotY;} + private function set_PivotY( v : Float ):Float {mPivotY = v;return mPivotY;} + + public var SkewX(get, set) : Float; + private inline function get_SkewX():Float { return mSkewX;} + private function set_SkewX( v : Float ):Float {mSkewX = v;return mSkewX;} + + public var SkewY(get, set) : Float; + private inline function get_SkewY():Float { return mSkewY;} + private function set_SkewY( v : Float ):Float {mSkewY = v;return mSkewY;} + + public var Rotation(get, set) : Float; + private inline function get_Rotation():Float { return mRotation;} + private function set_Rotation( v : Float ):Float {mRotation = v;return mRotation;} +*/ +} \ No newline at end of file diff --git a/src/com/engine/direct/Util.hx b/src/com/engine/direct/Util.hx new file mode 100755 index 0000000..5f700ac --- /dev/null +++ b/src/com/engine/direct/Util.hx @@ -0,0 +1,159 @@ +package com.engine.direct ; + +import flash.geom.Matrix; +import flash.geom.Rectangle; +/** + * ... + * @author djoker + */ +class Util +{ + public static var EPSILON:Float = 0.00000001; + public static var WHITE:Int = 0xffffff; + public static var SILVER:Int = 0xc0c0c0; + public static var GRAY:Int = 0x808080; + public static var BLACK:Int = 0x000000; + public static var RED:Int = 0xff0000; + public static var MAROON:Int = 0x800000; + public static var YELLOW:Int = 0xffff00; + public static var OLIVE:Int = 0x808000; + public static var LIME:Int = 0x00ff00; + public static var GREEN:Int = 0x008000; + public static var AQUA:Int = 0x00ffff; + public static var TEAL:Int = 0x008080; + public static var BLUE:Int = 0x0000ff; + public static var NAVY:Int = 0x000080; + public static var FUCHSIA:Int = 0xff00ff; + public static var PURPLE:Int = 0x800080; + + + public static function matrixsetTo(matrix:Matrix,aa : Float, ba : Float, ca : Float, da : Float, txa : Float, tya : Float) : Void + { + matrix.a = aa; + matrix.b = ba; + matrix.c = ca; + matrix.d = da; + matrix.tx = txa; + matrix.ty = tya; + + + } +public static function skew(matrix:Matrix, skewX:Float, skewY:Float):Void + { + var sinX:Float = Math.sin(skewX); + var cosX:Float = Math.cos(skewX); + var sinY:Float = Math.sin(skewY); + var cosY:Float = Math.cos(skewY); + + matrixsetTo(matrix,matrix.a * cosY - matrix.b * sinX, + matrix.a * sinY + matrix.b * cosX, + matrix.c * cosY - matrix.d * sinX, + matrix.c * sinY + matrix.d * cosX, + matrix.tx * cosY - matrix.ty * sinX, + matrix.tx * sinY + matrix.ty * cosX); + } + +public static function isEquivalent(a:Float, b:Float, epsilon:Float=0.0001):Bool + { + return (a - epsilon < b) && (a + epsilon > b); + } + +public static function normalizeAngle(angle:Float):Float + { + // move into range [-180 deg, +180 deg] + while (angle < -Math.PI) angle += Math.PI * 2.0; + while (angle > Math.PI) angle -= Math.PI * 2.0; + return angle; + } + + public static function getAlpha(color:Int):Int { return (color >> 24) & 0xff; } + public static function getRed(color:Int):Int { return (color >> 16) & 0xff; } + public static function getGreen(color:Int):Int { return (color >> 8) & 0xff; } + public static function getBlue(color:Int):Int { return color & 0xff; } + public static function rgb(red:Int, green:Int, blue:Int):Int + { + return (red << 16) | (green << 8) | blue; + } + public static function argb(alpha:Int, red:Int, green:Int, blue:Int):Int + { + return (alpha << 24) | (red << 16) | (green << 8) | blue; + } + + public static function intersect(rect1:Rectangle, rect2:Rectangle, resultRect:Rectangle):Rectangle + { + if (resultRect == null) resultRect = new Rectangle(); + + var left:Float = rect1.x > rect2.x ? rect1.x : rect2.x; + var right:Float = rect1.right < rect2.right ? rect1.right : rect2.right; + var top:Float = rect1.y > rect2.y ? rect1.y : rect2.y; + var bottom:Float = rect1.bottom < rect2.bottom ? rect1.bottom : rect2.bottom; + + if (left > right || top > bottom) + resultRect.setEmpty(); + // else + // resultRect.setTo(left, top, right-left, bottom-top); + + return resultRect; + } + + + public static function fit(rectangle:Rectangle, into:Rectangle, resultRect:Rectangle):Rectangle + { + + if (resultRect == null) resultRect = new Rectangle(); + + var width:Float = rectangle.width; + var height:Float = rectangle.height; + var factorX:Float = into.width / width; + var factorY:Float = into.height / height; + var factor:Float = 1.0; + + + width *= factor; + height *= factor; + + // resultRect.setTo( + // into.x + (into.width - width) / 2, + // into.y + (into.height - height) / 2, + // width, height); + + return resultRect; + } + + static public function setLength(array:Array, newLength:Int):Void + { + if (newLength < 0) return; + var oldLength:Int = array.length; + var diff:Int = newLength - oldLength; + if (diff < 0) + { + #if flash + untyped array.length = newLength; + #else + diff = -diff; + for (i in 0...diff) + { + array.pop(); + } + #end + } + } + static public function indexOf(array:Array, whatToFind:T, fromIndex:Int = 0):Int + { + #if flash + return untyped array.indexOf(whatToFind, fromIndex); + #else + var index:Int = -1; + var len:Int = array.length; + for (i in fromIndex...len) + { + if (array[i] == whatToFind) + { + index = i; + break; + } + } + return index; + #end + } +} \ No newline at end of file diff --git a/src/com/engine/game/Game.hx b/src/com/engine/game/Game.hx new file mode 100755 index 0000000..1739baa --- /dev/null +++ b/src/com/engine/game/Game.hx @@ -0,0 +1,320 @@ +package com.engine.game; + +import flash.display.Sprite; +import flash.geom.Rectangle; +import flash.geom.Matrix3D; +import flash.text.TextField; +import flash.text.TextFormat; +import flash.events.MouseEvent; +import flash.events.KeyboardEvent; +import flash.ui.Keyboard; +import flash.ui.Mouse; + +import flash.events.TouchEvent; +import flash.display.BitmapData; +import flash.display.DisplayObject; +import flash.display.Sprite; +import flash.display.StageAlign; +import flash.display.StageDisplayState; +import flash.display.StageQuality; +import flash.display.StageScaleMode; +import flash.events.Event; +import flash.geom.Rectangle; +import flash.Lib; + +import flash.ui.Multitouch; +import flash.ui.MultitouchInputMode; + +import com.engine.misc.Util; +import com.engine.math.Vector3; +import com.engine.math.Matrix; + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; +/** + * ... + * @author djoker + * http://code-haxe.co.nf/ + */ +class Game extends OpenGLView +{ + public var viewPort:Rectangle; + private var ready:Bool; + public var deltaTime:Float; + private var prevFrame:Int; + private var nextFrame:Int; + private var mMultiTouch:Bool; + private var screen:Screen = null; + private var container:Sprite; + static public var scrollX:Float = 0; + static public var scrollY:Float = 0; + static public var viewWidth:Float = 0; + static public var viewHeight:Float = 0; + public var screenWidth:Int = 0; + public var screenHeight:Int = 0; + public var gameWidth:Int=0; + public var gameHeight:Int = 0; + private var rescale:Bool = false; + + + + static public var projMatrix:Matrix; + static public var viewMatrix:Matrix; + + + + + public function fixRatio(w:Int, h:Int) + { + rescale = true; + gameWidth = w; + gameHeight = h; + } + + public function new() + { + super(); + ready = false; + this.render = renderView; + viewPort = new Rectangle(0, 0, Lib.current.stage.stageWidth,Lib.current.stage.stageHeight); + + screenWidth = Lib.current.stage.stageWidth; + screenHeight = Lib.current.stage.stageHeight; + Game.viewWidth = screenHeight; + Game.viewHeight = screenHeight; + gameWidth = screenWidth; + gameHeight = screenHeight; + + + + Game.projMatrix=Matrix.OrthoOffCenterLH(0, gameWidth,gameHeight,0, -1, 1); + Game.viewMatrix = Matrix.Identity(); + + + stage.addEventListener(Event.RESIZE, onResize); + stage.addEventListener(Event.ADDED, focusGained); + stage.addEventListener(Event.DEACTIVATE, focusLost); + + + container = new Sprite(); + container.addEventListener(Event.ADDED_TO_STAGE, addedToStage); + stage.addChild(container); + addChild(new FPS(10, 10, 0xff0ff)); + prevFrame = Lib.getTimer(); + + + + + + GL.disable(GL.CULL_FACE); + GL.enable(GL.DEPTH_TEST); + GL.depthFunc(GL.LEQUAL); + + + } + + + + public function removeChild(child : DisplayObject) + { + container.removeChild(child); + } + + public function addChild(child : DisplayObject) + { + container.addChild(child); + } + + private function addedToStage(e:Event) + { + + mMultiTouch = Multitouch.supportsTouchEvents; + if (mMultiTouch) Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT; + // trace("Using multi-touch : " + mMultiTouch); + + + + Lib.current.stage.addEventListener (MouseEvent.MOUSE_DOWN, doMouseDown); + Lib.current.stage.addEventListener (MouseEvent.MOUSE_MOVE, doMouseMove); + Lib.current.stage.addEventListener (MouseEvent.MOUSE_UP, doMouseUp); + Lib.current.stage.addEventListener (KeyboardEvent.KEY_DOWN, stage_onKeyDown); + Lib.current.stage.addEventListener (KeyboardEvent.KEY_UP, stage_onKeyUp); + + + if (mMultiTouch) + { + Lib.current.stage.addEventListener(TouchEvent.TOUCH_BEGIN, doTouchDown); + Lib.current.stage.addEventListener(TouchEvent.TOUCH_MOVE, doTouchMove); + Lib.current.stage.addEventListener(TouchEvent.TOUCH_END, doTouchUp); + } + + GL.disable(GL.DEPTH_TEST); + GL.disable(GL.CULL_FACE); + GL.enable(GL.BLEND); + GL.pixelStorei(GL.PACK_ALIGNMENT, 2); + GL.depthMask(true); + + + // GL.enable(GL.DEPTH_TEST); + // GL.enable(GL.STENCIL_TEST); + + + begin(); + ready = true; + + } + public function focusGained(e:Event) + { + + + + + } + + private function stage_onKeyDown (event:KeyboardEvent):Void + { + + keyDown(event.keyCode); + if (screen != null) screen.keyDown(event.keyCode); + } + + + private function stage_onKeyUp (event:KeyboardEvent):Void + { + + keyUp(event.keyCode); + if (screen != null) screen.keyUp(event.keyCode); + } + + private function doMouseDown (event:MouseEvent):Void + { + mouseDown(event.localX, event.localY); + if (screen != null) screen.mouseDown(event.localX, event.localY); + } + private function doMouseUp (event:MouseEvent):Void + { + mouseUp(event.localX, event.localY); + if (screen != null) screen.mouseUp(event.localX, event.localY); + } + private function doMouseMove (event:MouseEvent):Void + { + mouseMove(event.localX, event.localY); + if (screen != null) screen.mouseMove(event.localX, event.localY); + + } + + private function doTouchDown (event:TouchEvent):Void + { + + } + private function doTouchUp (event:TouchEvent):Void + { + + } + private function doTouchMove (event:TouchEvent):Void + { + + + } + + private function focusLost(e:Event) {trace("end game"); ready = false; end(); } + private function onResize(e:Event) + { + screenWidth = Lib.current.stage.stageWidth; + screenHeight = Lib.current.stage.stageHeight; + + resize(screenWidth,screenHeight); + } + + public function begin() { } + public function end() { } + public function resize(width:Int, height:Int) + { + // trace("resize :" + width + "X" + height); + if (screen != null) screen.resize(width, height); + } + public function update(dt:Float) + { + if (screen != null) screen.render(dt); + } + public function keyDown(key:Int) { }; + public function keyUp(key:Int) { }; + + public function mouseMove(mousex:Float, mousey:Float) { }; + public function mouseUp(mousex:Float, mousey:Float) { }; + public function mouseDown(mousex:Float, mousey:Float) { }; + + public function setScreen ( screen:Screen) + { + if (this.screen != null) this.screen.dispose(); + this.screen = screen; + this.screen.game = this; + if (this.screen != null) + { + this.screen.show(); + this.screen.resize(Std.int(Game.viewWidth),Std.int(Game.viewHeight)); + } + } + + +private function renderView(rect:Rectangle):Void +{ + viewWidth = rect.width; + viewHeight = rect.height; + + if (rescale==true) + { + var ar_origin:Float = (gameWidth / gameHeight); + var ar_new :Float = (screenWidth /screenHeight); + + var scale_w:Float = (screenWidth / gameWidth); + var scale_h:Float = (screenHeight / gameHeight); + if (ar_new > ar_origin) + { + scale_w = scale_h; + } else { + scale_h = scale_w; + } + + var margin_x:Float = (screenWidth - gameWidth * scale_w) / 2; + var margin_y:Float = (screenHeight - gameHeight * scale_h) / 2; + + GL.viewport (Std.int (margin_x), Std.int (margin_y), Std.int (gameWidth*scale_w), Std.int (gameHeight*scale_h)); + Game.projMatrix=Matrix.OrthoOffCenterLH(0, gameWidth/ar_origin, gameHeight/ar_origin,0, -1000, 1000); + } else + { + GL.viewport (Std.int (rect.x), Std.int (rect.y), Std.int (rect.width), Std.int (rect.height)); + //Game.projMatrix=Matrix.OrthoOffCenterLH(0, rect.width, rect.height,0, -1, 1); + Game.projMatrix=Matrix.OrthoOffCenterLH(0, gameWidth,gameHeight,0, -1, 1); + } + + Game.viewMatrix=Matrix.create2D( 0, 0, 1, 0); + + + + + nextFrame = Lib.getTimer(); + deltaTime = (nextFrame - prevFrame) * 0.001; + GL.clearColor(0, 0, 0.4, 1); + GL.clearDepth(1); + + GL.clear(GL.COLOR_BUFFER_BIT | GL.DEPTH_BUFFER_BIT); + + + + if (ready) + { + update(deltaTime); + } + GL.bindBuffer (GL.ARRAY_BUFFER, null); + GL.useProgram (null); + GL.blendFunc(GL.SRC_ALPHA,GL.DST_ALPHA ); + prevFrame = nextFrame; +} + +} \ No newline at end of file diff --git a/src/com/engine/game/GameObject.hx b/src/com/engine/game/GameObject.hx new file mode 100755 index 0000000..1c3a979 --- /dev/null +++ b/src/com/engine/game/GameObject.hx @@ -0,0 +1,15 @@ +package com.engine.game; + + +import flash.geom.Matrix; + +/** + * ... + * @author djoker + */ +class GameObject extends Transform +{ + + + +} \ No newline at end of file diff --git a/src/com/engine/game/Screen.hx b/src/com/engine/game/Screen.hx new file mode 100755 index 0000000..e4b948c --- /dev/null +++ b/src/com/engine/game/Screen.hx @@ -0,0 +1,23 @@ +package com.engine.game; + +/** + * ... + * @author djoker + */ +class Screen extends Transform +{ + + public var game:Game = null; + + public function show() { } + public function dispose() { } + public function render(dt:Float) { } + public function resize(width:Int, height:Int) {} + + public function mouseMove(mousex:Float, mousey:Float) { }; + public function mouseUp(mousex:Float, mousey:Float) { }; + public function mouseDown(mousex:Float, mousey:Float) { }; + public function keyDown(key:Int) { }; + public function keyUp(key:Int) { }; + +} \ No newline at end of file diff --git a/src/com/engine/game/Transform.hx b/src/com/engine/game/Transform.hx new file mode 100755 index 0000000..4584408 --- /dev/null +++ b/src/com/engine/game/Transform.hx @@ -0,0 +1,88 @@ +package com.engine.game; + +import flash.geom.Matrix; +import com.engine.misc.MatrixHelp; +/** + * ... + * @author djoker + */ +class Transform +{ + public var mTransformationMatrix:Matrix; + public var parent:Transform; + public var children:List; + private var isDirty:Bool = false; + + public var rotation:Float = 0; + public var scaleX:Float = 1; + public var scaleY:Float = 1; + public var skewX:Float = 0; + public var skewY:Float = 0; + public var pivotX:Float = 0; + public var pivotY:Float = 0; + public var x:Float = 0; + public var y:Float = 0; + public var scrollFactorX:Float = 1; + public var scrollFactorY:Float = 1; + + + + + public function new() + { + parent = null; + mTransformationMatrix = new Matrix(); + children = new List(); + + } + + public function add(child:Transform) + { + this.children.add(child); + } + public function remove(child:Transform) + { + this.children.remove(child); + } + + + public function getTransformationMatrix():Matrix + { + mTransformationMatrix.identity(); + + var cx:Float = Game.scrollX; + var cy:Float = Game.scrollY; + var sx:Float = x - cx * scrollFactorX; + var sy:Float = y - cy * scrollFactorY; + + + if (scaleX != 1.0 || scaleY != 1.0) mTransformationMatrix.scale(scaleX, scaleY); + if (skewX != 0.0 || skewY != 0.0) MatrixHelp.skew(mTransformationMatrix, skewX, skewY); + if (rotation != 0.0) mTransformationMatrix.rotate(rotation); + if (sx != 0.0 || sy != 0.0) mTransformationMatrix.translate(sx, sy); + + if (pivotX != 0.0 || pivotY != 0.0) + { + mTransformationMatrix.tx = sx - mTransformationMatrix.a * pivotX + - mTransformationMatrix.c * pivotY; + mTransformationMatrix.ty = sy - mTransformationMatrix.b * pivotX + - mTransformationMatrix.d * pivotY; + } + return mTransformationMatrix; + + } + public function getLocalToWorldMatrix():Matrix + { + if (parent == null) + { + return getTransformationMatrix(); + } + else + { + return parent.getTransformationMatrix().mult(getTransformationMatrix()); + } + + + } + +} \ No newline at end of file diff --git a/src/com/engine/math/Frustum.hx b/src/com/engine/math/Frustum.hx new file mode 100755 index 0000000..69f5dcd --- /dev/null +++ b/src/com/engine/math/Frustum.hx @@ -0,0 +1,65 @@ +package com.engine.math; + + + +class Frustum { + + public static function GetPlanes(transform:Matrix):Array { + var frustumPlanes = []; + + for (index in 0...6) { + frustumPlanes.push(new Plane(0, 0, 0, 0)); + } + + Frustum.GetPlanesToRef(transform, frustumPlanes); + + return frustumPlanes; + } + + inline public static function GetPlanesToRef(transform:Matrix, frustumPlanes:Array):Array { + // Near + frustumPlanes[0].normal.x = transform.m[3] + transform.m[2]; + frustumPlanes[0].normal.y = transform.m[7] + transform.m[6]; + frustumPlanes[0].normal.z = transform.m[10] + transform.m[10]; + frustumPlanes[0].d = transform.m[15] + transform.m[14]; + frustumPlanes[0].normalize(); + + // Far + frustumPlanes[1].normal.x = transform.m[3] - transform.m[2]; + frustumPlanes[1].normal.y = transform.m[7] - transform.m[6]; + frustumPlanes[1].normal.z = transform.m[11] - transform.m[10]; + frustumPlanes[1].d = transform.m[15] - transform.m[14]; + frustumPlanes[1].normalize(); + + // Left + frustumPlanes[2].normal.x = transform.m[3] + transform.m[0]; + frustumPlanes[2].normal.y = transform.m[7] + transform.m[4]; + frustumPlanes[2].normal.z = transform.m[11] + transform.m[8]; + frustumPlanes[2].d = transform.m[15] + transform.m[12]; + frustumPlanes[2].normalize(); + + // Right + frustumPlanes[3].normal.x = transform.m[3] - transform.m[0]; + frustumPlanes[3].normal.y = transform.m[7] - transform.m[4]; + frustumPlanes[3].normal.z = transform.m[11] - transform.m[8]; + frustumPlanes[3].d = transform.m[15] - transform.m[12]; + frustumPlanes[3].normalize(); + + // Top + frustumPlanes[4].normal.x = transform.m[3] - transform.m[1]; + frustumPlanes[4].normal.y = transform.m[7] - transform.m[5]; + frustumPlanes[4].normal.z = transform.m[11] - transform.m[9]; + frustumPlanes[4].d = transform.m[15] - transform.m[13]; + frustumPlanes[4].normalize(); + + // Bottom + frustumPlanes[5].normal.x = transform.m[3] + transform.m[1]; + frustumPlanes[5].normal.y = transform.m[7] + transform.m[5]; + frustumPlanes[5].normal.z = transform.m[11] + transform.m[9]; + frustumPlanes[5].d = transform.m[15] + transform.m[13]; + frustumPlanes[5].normalize(); + + return frustumPlanes; + } + +} diff --git a/src/com/engine/math/Matrix.hx b/src/com/engine/math/Matrix.hx new file mode 100755 index 0000000..0885f13 --- /dev/null +++ b/src/com/engine/math/Matrix.hx @@ -0,0 +1,725 @@ +package com.engine.math; + +import openfl.utils.Float32Array; + + + +class Matrix { + + public var m:Array; + + public function new() { + m = []; + } + + inline public function isIdentity():Bool { + var ret:Bool = true; + if (this.m[0] != 1.0 || this.m[5] != 1.0 || this.m[10] != 1.0 || this.m[15] != 1.0) + ret = false; + + if (this.m[1] != 0.0 || this.m[2] != 0.0 || this.m[3] != 0.0 || + this.m[4] != 0.0 || this.m[6] != 0.0 || this.m[7] != 0.0 || + this.m[8] != 0.0 || this.m[9] != 0.0 || this.m[11] != 0.0 || + this.m[12] != 0.0 || this.m[13] != 0.0 || this.m[14] != 0.0) + ret = false; + + return ret; + } + + inline public function determinant():Float { + var temp1 = (this.m[10] * this.m[15]) - (this.m[11] * this.m[14]); + var temp2 = (this.m[9] * this.m[15]) - (this.m[11] * this.m[13]); + var temp3 = (this.m[9] * this.m[14]) - (this.m[10] * this.m[13]); + var temp4 = (this.m[8] * this.m[15]) - (this.m[11] * this.m[12]); + var temp5 = (this.m[8] * this.m[14]) - (this.m[10] * this.m[12]); + var temp6 = (this.m[8] * this.m[13]) - (this.m[9] * this.m[12]); + + return ((((this.m[0] * (((this.m[5] * temp1) - (this.m[6] * temp2)) + (this.m[7] * temp3))) - (this.m[1] * (((this.m[4] * temp1) - + (this.m[6] * temp4)) + (this.m[7] * temp5)))) + (this.m[2] * (((this.m[4] * temp2) - (this.m[5] * temp4)) + (this.m[7] * temp6)))) - + (this.m[3] * (((this.m[4] * temp3) - (this.m[5] * temp5)) + (this.m[6] * temp6)))); + } + + inline public function toArray():Array + { + return this.m; + } + + inline public function invert() { + this.invertToRef(this); + } + + inline public function invertToRef(other:Matrix) { + var l1 = this.m[0]; + var l2 = this.m[1]; + var l3 = this.m[2]; + var l4 = this.m[3]; + var l5 = this.m[4]; + var l6 = this.m[5]; + var l7 = this.m[6]; + var l8 = this.m[7]; + var l9 = this.m[8]; + var l10 = this.m[9]; + var l11 = this.m[10]; + var l12 = this.m[11]; + var l13 = this.m[12]; + var l14 = this.m[13]; + var l15 = this.m[14]; + var l16 = this.m[15]; + var l17 = (l11 * l16) - (l12 * l15); + var l18 = (l10 * l16) - (l12 * l14); + var l19 = (l10 * l15) - (l11 * l14); + var l20 = (l9 * l16) - (l12 * l13); + var l21 = (l9 * l15) - (l11 * l13); + var l22 = (l9 * l14) - (l10 * l13); + var l23 = ((l6 * l17) - (l7 * l18)) + (l8 * l19); + var l24 = -(((l5 * l17) - (l7 * l20)) + (l8 * l21)); + var l25 = ((l5 * l18) - (l6 * l20)) + (l8 * l22); + var l26 = -(((l5 * l19) - (l6 * l21)) + (l7 * l22)); + var l27 = 1.0 / ((((l1 * l23) + (l2 * l24)) + (l3 * l25)) + (l4 * l26)); + var l28 = (l7 * l16) - (l8 * l15); + var l29 = (l6 * l16) - (l8 * l14); + var l30 = (l6 * l15) - (l7 * l14); + var l31 = (l5 * l16) - (l8 * l13); + var l32 = (l5 * l15) - (l7 * l13); + var l33 = (l5 * l14) - (l6 * l13); + var l34 = (l7 * l12) - (l8 * l11); + var l35 = (l6 * l12) - (l8 * l10); + var l36 = (l6 * l11) - (l7 * l10); + var l37 = (l5 * l12) - (l8 * l9); + var l38 = (l5 * l11) - (l7 * l9); + var l39 = (l5 * l10) - (l6 * l9); + + other.m[0] = l23 * l27; + other.m[4] = l24 * l27; + other.m[8] = l25 * l27; + other.m[12] = l26 * l27; + other.m[1] = -(((l2 * l17) - (l3 * l18)) + (l4 * l19)) * l27; + other.m[5] = (((l1 * l17) - (l3 * l20)) + (l4 * l21)) * l27; + other.m[9] = -(((l1 * l18) - (l2 * l20)) + (l4 * l22)) * l27; + other.m[13] = (((l1 * l19) - (l2 * l21)) + (l3 * l22)) * l27; + other.m[2] = (((l2 * l28) - (l3 * l29)) + (l4 * l30)) * l27; + other.m[6] = -(((l1 * l28) - (l3 * l31)) + (l4 * l32)) * l27; + other.m[10] = (((l1 * l29) - (l2 * l31)) + (l4 * l33)) * l27; + other.m[14] = -(((l1 * l30) - (l2 * l32)) + (l3 * l33)) * l27; + other.m[3] = -(((l2 * l34) - (l3 * l35)) + (l4 * l36)) * l27; + other.m[7] = (((l1 * l34) - (l3 * l37)) + (l4 * l38)) * l27; + other.m[11] = -(((l1 * l35) - (l2 * l37)) + (l4 * l39)) * l27; + other.m[15] = (((l1 * l36) - (l2 * l38)) + (l3 * l39)) * l27; + } + + inline public function setTranslation(vector3:Vector3) { + this.m[12] = vector3.x; + this.m[13] = vector3.y; + this.m[14] = vector3.z; + } + + inline public function multiply(other:Matrix):Matrix { + var result = new Matrix(); + this.multiplyToRef(other, result); + return result; + } + + inline public function copyFrom(other:Matrix) { + for (index in 0...16) { + this.m[index] = other.m[index]; + } + } + + inline public function multiplyToRef(other:Matrix, result:Matrix) { + this.multiplyToArray(other, result.m, 0); + } + inline public static function MatrixMultiply4x4(A:Matrix,B :Matrix) + { + var result = new Matrix(); + + + result.m[0] = A.m[0]*B.m[0] + A.m[4]*B.m[1] + A.m[8]*B.m[2] + A.m[12]*B.m[3]; + result.m[1] = A.m[1]*B.m[0] + A.m[5]*B.m[1] + A.m[9]*B.m[2] + A.m[13]*B.m[3]; + result.m[2] = A.m[2]*B.m[0] + A.m[6]*B.m[1] + A.m[10]*B.m[2] + A.m[14]*B.m[3]; + result.m[3] = A.m[3]*B.m[0] + A.m[7]*B.m[1] + A.m[11]*B.m[2] + A.m[15]*B.m[3]; + + result.m[4] = A.m[0]*B.m[4] + A.m[4]*B.m[5] + A.m[8]*B.m[6] + A.m[12]*B.m[7]; + result.m[5] = A.m[1]*B.m[4] + A.m[5]*B.m[5] + A.m[9]*B.m[6] + A.m[13]*B.m[7]; + result.m[6] = A.m[2]*B.m[4] + A.m[6]*B.m[5] + A.m[10]*B.m[6] + A.m[14]*B.m[7]; + result.m[7] = A.m[3]*B.m[4] + A.m[7]*B.m[5] + A.m[11]*B.m[6] + A.m[15]*B.m[7]; + + result.m[8] = A.m[0]*B.m[8] + A.m[4]*B.m[9] + A.m[8]*B.m[10] + A.m[12]*B.m[11]; + result.m[9] = A.m[1]*B.m[8] + A.m[5]*B.m[9] + A.m[9]*B.m[10] + A.m[13]*B.m[11]; + result.m[10] = A.m[2]*B.m[8] + A.m[6]*B.m[9] + A.m[10]*B.m[10] + A.m[14]*B.m[11]; + result.m[11] = A.m[3]*B.m[8] + A.m[7]*B.m[9] + A.m[11]*B.m[10] + A.m[15]*B.m[11]; + + result.m[12] = A.m[0]*B.m[12] + A.m[4]*B.m[13] + A.m[8]*B.m[14] + A.m[12]*B.m[15]; + result.m[13] = A.m[1]*B.m[12] + A.m[5]*B.m[13] + A.m[9]*B.m[14] + A.m[13]*B.m[15]; + result.m[14] = A.m[2]*B.m[12] + A.m[6]*B.m[13] + A.m[10]*B.m[14] + A.m[14]*B.m[15]; + result.m[15] = A.m[3] * B.m[12] + A.m[7] * B.m[13] + A.m[11] * B.m[14] + A.m[15] * B.m[15]; + + return result; + } + + + inline public function multiplyToArray(other:Matrix, result:Array, offset:Int):Array { + + var tm0 = this.m[0]; + var tm1 = this.m[1]; + var tm2 = this.m[2]; + var tm3 = this.m[3]; + var tm4 = this.m[4]; + var tm5 = this.m[5]; + var tm6 = this.m[6]; + var tm7 = this.m[7]; + var tm8 = this.m[8]; + var tm9 = this.m[9]; + var tm10 = this.m[10]; + var tm11 = this.m[11]; + var tm12 = this.m[12]; + var tm13 = this.m[13]; + var tm14 = this.m[14]; + var tm15 = this.m[15]; + + var om0 = other.m[0]; + var om1 = other.m[1]; + var om2 = other.m[2]; + var om3 = other.m[3]; + var om4 = other.m[4]; + var om5 = other.m[5]; + var om6 = other.m[6]; + var om7 = other.m[7]; + var om8 = other.m[8]; + var om9 = other.m[9]; + var om10 = other.m[10]; + var om11 = other.m[11]; + var om12 = other.m[12]; + var om13 = other.m[13]; + var om14 = other.m[14]; + var om15 = other.m[15]; + + result[offset] = tm0 * om0 + tm1 * om4 + tm2 * om8 + tm3 * om12; + result[offset + 1] = tm0 * om1 + tm1 * om5 + tm2 * om9 + tm3 * om13; + result[offset + 2] = tm0 * om2 + tm1 * om6 + tm2 * om10 + tm3 * om14; + result[offset + 3] = tm0 * om3 + tm1 * om7 + tm2 * om11 + tm3 * om15; + + result[offset + 4] = tm4 * om0 + tm5 * om4 + tm6 * om8 + tm7 * om12; + result[offset + 5] = tm4 * om1 + tm5 * om5 + tm6 * om9 + tm7 * om13; + result[offset + 6] = tm4 * om2 + tm5 * om6 + tm6 * om10 + tm7 * om14; + result[offset + 7] = tm4 * om3 + tm5 * om7 + tm6 * om11 + tm7 * om15; + + result[offset + 8] = tm8 * om0 + tm9 * om4 + tm10 * om8 + tm11 * om12; + result[offset + 9] = tm8 * om1 + tm9 * om5 + tm10 * om9 + tm11 * om13; + result[offset + 10] = tm8 * om2 + tm9 * om6 + tm10 * om10 + tm11 * om14; + result[offset + 11] = tm8 * om3 + tm9 * om7 + tm10 * om11 + tm11 * om15; + + result[offset + 12] = tm12 * om0 + tm13 * om4 + tm14 * om8 + tm15 * om12; + result[offset + 13] = tm12 * om1 + tm13 * om5 + tm14 * om9 + tm15 * om13; + result[offset + 14] = tm12 * om2 + tm13 * om6 + tm14 * om10 + tm15 * om14; + result[offset + 15] = tm12 * om3 + tm13 * om7 + tm14 * om11 + tm15 * om15; + + return result; + } + + inline public function equals(value:Matrix):Bool { + return (this.m[0] == value.m[0] && this.m[1] == value.m[1] && this.m[2] == value.m[2] && this.m[3] == value.m[3] && + this.m[4] == value.m[4] && this.m[5] == value.m[5] && this.m[6] == value.m[6] && this.m[7] == value.m[7] && + this.m[8] == value.m[8] && this.m[9] == value.m[9] && this.m[10] == value.m[10] && this.m[11] == value.m[11] && + this.m[12] == value.m[12] && this.m[13] == value.m[13] && this.m[14] == value.m[14] && this.m[15] == value.m[15]); + } + + inline public function clone():Matrix { + return Matrix.FromValues(this.m[0], this.m[1], this.m[2], this.m[3], + this.m[4], this.m[5], this.m[6], this.m[7], + this.m[8], this.m[9], this.m[10], this.m[11], + this.m[12], this.m[13], this.m[14], this.m[15]); + } + + + inline public static function FromArray(array:Array, offset:Int = 0):Matrix { + var result = new Matrix(); + Matrix.FromArrayToRef(array, offset, result); + return result; + } + + inline public static function FromArrayToRef(array:Array, offset:Int = 0, result:Matrix):Matrix { + for (index in 0...16) { + result.m[index] = array[index + offset]; + } + return result; + } + + inline public static function FromValues(m11:Float, m12:Float, m13:Float, m14:Float, + m21:Float, m22:Float, m23:Float, m24:Float, + m31:Float, m32:Float, m33:Float, m34:Float, + m41:Float, m42:Float, m43:Float, m44:Float):Matrix { + + var result = new Matrix(); + + result.m[0] = m11; + result.m[1] = m12; + result.m[2] = m13; + result.m[3] = m14; + result.m[4] = m21; + result.m[5] = m22; + result.m[6] = m23; + result.m[7] = m24; + result.m[8] = m31; + result.m[9] = m32; + result.m[10] = m33; + result.m[11] = m34; + result.m[12] = m41; + result.m[13] = m42; + result.m[14] = m43; + result.m[15] = m44; + + return result; + } + + inline public static function FromValuesToRef(m11:Float, m12:Float, m13:Float, m14:Float, + m21:Float, m22:Float, m23:Float, m24:Float, + m31:Float, m32:Float, m33:Float, m34:Float, + m41:Float, m42:Float, m43:Float, m44:Float, result:Matrix):Matrix { + + result.m[0] = m11; + result.m[1] = m12; + result.m[2] = m13; + result.m[3] = m14; + result.m[4] = m21; + result.m[5] = m22; + result.m[6] = m23; + result.m[7] = m24; + result.m[8] = m31; + result.m[9] = m32; + result.m[10] = m33; + result.m[11] = m34; + result.m[12] = m41; + result.m[13] = m42; + result.m[14] = m43; + result.m[15] = m44; + + return result; + } + + inline public static function Identity():Matrix { + return Matrix.FromValues( + 1.0, 0, 0, 0, + 0, 1.0, 0, 0, + 0, 0, 1.0, 0, + 0, 0, 0, 1.0 + ); + } + + inline public static function IdentityToRef(result:Matrix):Matrix { + Matrix.FromValuesToRef( + 1.0, 0, 0, 0, + 0, 1.0, 0, 0, + 0, 0, 1.0, 0, + 0, 0, 0, 1.0, result + ); + + return result; + } + + inline public static function Zero():Matrix { + return Matrix.FromValues( + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + ); + } + + inline public static function RotationX(angle:Float):Matrix { + var result = new Matrix(); + Matrix.RotationXToRef(angle, result); + + return result; + } + + inline public static function RotationXToRef(angle:Float, result:Matrix):Matrix { + var s = Math.sin(angle); + var c = Math.cos(angle); + + result.m[0] = 1.0; + result.m[15] = 1.0; + + result.m[5] = c; + result.m[10] = c; + result.m[9] = -s; + result.m[6] = s; + + result.m[1] = 0; + result.m[2] = 0; + result.m[3] = 0; + result.m[4] = 0; + result.m[7] = 0; + result.m[8] = 0; + result.m[11] = 0; + result.m[12] = 0; + result.m[13] = 0; + result.m[14] = 0; + + return result; + } + + inline public static function RotationY(angle:Float):Matrix { + var result = new Matrix(); + Matrix.RotationYToRef(angle, result); + + return result; + } + + inline public static function RotationYToRef(angle:Float, result:Matrix):Matrix { + var s = Math.sin(angle); + var c = Math.cos(angle); + + result.m[5] = 1.0; + result.m[15] = 1.0; + + result.m[0] = c; + result.m[2] = -s; + result.m[8] = s; + result.m[10] = c; + + result.m[1] = 0; + result.m[3] = 0; + result.m[4] = 0; + result.m[6] = 0; + result.m[7] = 0; + result.m[9] = 0; + result.m[11] = 0; + result.m[12] = 0; + result.m[13] = 0; + result.m[14] = 0; + + return result; + } + + inline public static function RotationZ(angle:Float):Matrix { + var result = new Matrix(); + Matrix.RotationZToRef(angle, result); + + return result; + } + + inline public static function RotationZToRef(angle:Float, result:Matrix):Matrix { + var s = Math.sin(angle); + var c = Math.cos(angle); + + result.m[10] = 1.0; + result.m[15] = 1.0; + + result.m[0] = c; + result.m[1] = s; + result.m[4] = -s; + result.m[5] = c; + + result.m[2] = 0; + result.m[3] = 0; + result.m[6] = 0; + result.m[7] = 0; + result.m[8] = 0; + result.m[9] = 0; + result.m[11] = 0; + result.m[12] = 0; + result.m[13] = 0; + result.m[14] = 0; + + return result; + } + + inline public static function RotationAxis(axis:Vector3, angle:Float):Matrix { + var s = Math.sin(-angle); + var c = Math.cos(-angle); + var c1 = 1 - c; + + axis.normalize(); + var result = Matrix.Zero(); + + result.m[0] = (axis.x * axis.x) * c1 + c; + result.m[1] = (axis.x * axis.y) * c1 - (axis.z * s); + result.m[2] = (axis.x * axis.z) * c1 + (axis.y * s); + result.m[3] = 0.0; + + result.m[4] = (axis.y * axis.x) * c1 + (axis.z * s); + result.m[5] = (axis.y * axis.y) * c1 + c; + result.m[6] = (axis.y * axis.z) * c1 - (axis.x * s); + result.m[7] = 0.0; + + result.m[8] = (axis.z * axis.x) * c1 - (axis.y * s); + result.m[9] = (axis.z * axis.y) * c1 + (axis.x * s); + result.m[10] = (axis.z * axis.z) * c1 + c; + result.m[11] = 0.0; + + result.m[15] = 1.0; + + return result; + } + + inline public static function RotationYawPitchRoll(yaw:Float, pitch:Float, roll:Float):Matrix { + var result = new Matrix(); + Matrix.RotationYawPitchRollToRef(yaw, pitch, roll, result); + + return result; + } + + inline public static function RotationYawPitchRollToRef(yaw:Float, pitch:Float, roll:Float, result:Matrix):Matrix { + var tempQuaternion = new Quaternion(); // For RotationYawPitchRoll + tempQuaternion = Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, tempQuaternion); + + return tempQuaternion.toRotationMatrix(result); + } + + inline public static function Scaling(x:Float, y:Float, z:Float):Matrix { + var result = Matrix.Zero(); + Matrix.ScalingToRef(x, y, z, result); + + return result; + } + + inline public static function ScalingToRef(x:Float, y:Float, z:Float, result:Matrix):Matrix { + result.m[0] = x; + result.m[1] = 0; + result.m[2] = 0; + result.m[3] = 0; + result.m[4] = 0; + result.m[5] = y; + result.m[6] = 0; + result.m[7] = 0; + result.m[8] = 0; + result.m[9] = 0; + result.m[10] = z; + result.m[11] = 0; + result.m[12] = 0; + result.m[13] = 0; + result.m[14] = 0; + result.m[15] = 1.0; + + return result; + } + + inline public static function Translation(x:Float, y:Float, z:Float):Matrix { + var result = Matrix.Identity(); + Matrix.TranslationToRef(x, y, z, result); + + return result; + } + + inline public static function TranslationToRef(x:Float, y:Float, z:Float, result:Matrix) { + Matrix.FromValuesToRef( + 1.0, 0, 0, 0, + 0, 1.0, 0, 0, + 0, 0, 1.0, 0, + x, y, z, 1.0, result + ); + } + + inline public static function LookAtLH(eye:Vector3, target:Vector3, up:Vector3):Matrix { + var result = Matrix.Zero(); + Matrix.LookAtLHToRef(eye, target, up, result); + + return result; + } + + inline public static function LookAtLHToRef(eye:Vector3, target:Vector3, up:Vector3, result:Matrix):Matrix { + var xAxis = Vector3.Zero(); + var yAxis = Vector3.Zero(); + var zAxis = Vector3.Zero(); + + // Z axis + target.subtractToRef(eye, zAxis); + zAxis.normalize(); + + // X axis + Vector3.CrossToRef(up, zAxis, xAxis); + xAxis.normalize(); + + // Y axis + Vector3.CrossToRef(zAxis, xAxis, yAxis); + yAxis.normalize(); + + // Eye angles + var ex = -Vector3.Dot(xAxis, eye); + var ey = -Vector3.Dot(yAxis, eye); + var ez = -Vector3.Dot(zAxis, eye); + + return Matrix.FromValuesToRef(xAxis.x, yAxis.x, zAxis.x, 0, + xAxis.y, yAxis.y, zAxis.y, 0, + xAxis.z, yAxis.z, zAxis.z, 0, + ex, ey, ez, 1, result); + } + + inline public static function OrthoLH(width:Float, height:Float, znear:Float, zfar:Float):Matrix { + var hw = 2.0 / width; + var hh = 2.0 / height; + var id = 1.0 / (zfar - znear); + var nid = znear / (znear - zfar); + + return Matrix.FromValues( + hw, 0, 0, 0, + 0, hh, 0, 0, + 0, 0, id, 0, + 0, 0, nid, 1 + ); + } + + inline public static function OrthoOffCenterLH(left:Float, right:Float, bottom:Float, top:Float, znear:Float, zfar:Float):Matrix { + var matrix = Matrix.Zero(); + Matrix.OrthoOffCenterLHToRef(left, right, bottom, top, znear, zfar, matrix); + + return matrix; + } + + inline public static function OrthoOffCenterLHToRef(left:Float, right:Float, bottom:Float, top:Float, znear:Float, zfar:Float, result:Matrix):Matrix { + result.m[0] = 2.0 / (right - left); + result.m[1] = result.m[2] = result.m[3] = result.m[4] = 0; + result.m[5] = 2.0 / (top - bottom); + result.m[6] = result.m[7] = 0; + result.m[8] = result.m[9] = 0; + result.m[10] = -1 / (znear - zfar); + result.m[11] = 0; + result.m[12] = (left + right) / (left - right); + result.m[13] = (top + bottom) / (bottom - top); + result.m[14] = znear / (znear - zfar); + result.m[15] = 1.0; + + + return result; + } + + inline public static function PerspectiveLH(width:Float, height:Float, znear:Float, zfar:Float):Matrix { + var matrix = Matrix.Zero(); + + matrix.m[0] = (2.0 * znear) / width; + matrix.m[1] = matrix.m[2] = matrix.m[3] = 0.0; + matrix.m[5] = (2.0 * znear) / height; + matrix.m[4] = matrix.m[6] = matrix.m[7] = 0.0; + matrix.m[10] = -zfar / (znear - zfar); + matrix.m[8] = matrix.m[9] = 0.0; + matrix.m[11] = 1.0; + matrix.m[12] = matrix.m[13] = matrix.m[15] = 0.0; + matrix.m[14] = (znear * zfar) / (znear - zfar); + + return matrix; + } + + inline public static function PerspectiveFovLH(fov:Float, aspect:Float, znear:Float, zfar:Float):Matrix { + var matrix = Matrix.Zero(); + Matrix.PerspectiveFovLHToRef(fov, aspect, znear, zfar, matrix); + + return matrix; + } + + inline public static function PerspectiveFovLHToRef(fov:Float, aspect:Float, znear:Float, zfar:Float, result:Matrix):Matrix { + var tan = 1.0 / (Math.tan(fov * 0.5)); + + result.m[0] = tan / aspect; + result.m[1] = result.m[2] = result.m[3] = 0.0; + result.m[5] = tan; + result.m[4] = result.m[6] = result.m[7] = 0.0; + result.m[8] = result.m[9] = 0.0; + result.m[10] = -zfar / (znear - zfar); + result.m[11] = 1.0; + result.m[12] = result.m[13] = result.m[15] = 0.0; + result.m[14] = (znear * zfar) / (znear - zfar); + + return result; + } + +/* + + inline public static function GetFinalMatrix(viewport:Viewport, world:Matrix, view:Matrix, projection:Matrix, zmin:Float, zmax:Float):Matrix { + var cw = viewport.width; + var ch = viewport.height; + var cx = viewport.x; + var cy = viewport.y; + + var viewportMatrix = Matrix.FromValues( + cw / 2.0, 0, 0, 0, + 0, -ch / 2.0, 0, 0, + 0, 0, zmax - zmin, 0, + cx + cw / 2.0, ch / 2.0 + cy, zmin, 1 + ); + + return world.multiply(view).multiply(projection).multiply(viewportMatrix); + } + */ + inline public static function Transpose(matrix:Matrix):Matrix { + var result = new Matrix(); + + result.m[0] = matrix.m[0]; + result.m[1] = matrix.m[4]; + result.m[2] = matrix.m[8]; + result.m[3] = matrix.m[12]; + + result.m[4] = matrix.m[1]; + result.m[5] = matrix.m[5]; + result.m[6] = matrix.m[9]; + result.m[7] = matrix.m[13]; + + result.m[8] = matrix.m[2]; + result.m[9] = matrix.m[6]; + result.m[10] = matrix.m[10]; + result.m[11] = matrix.m[14]; + + result.m[12] = matrix.m[3]; + result.m[13] = matrix.m[7]; + result.m[14] = matrix.m[11]; + result.m[15] = matrix.m[15]; + + return result; + } + + inline public static function Reflection(plane:Plane):Matrix { + var matrix = new Matrix(); + Matrix.ReflectionToRef(plane, matrix); + + return matrix; + } + + inline public static function create2D(x:Float, y:Float, scale:Float = 1, rotation:Float = 0) + { + var theta = rotation * Math.PI / 180.0; + var c = Math.cos(theta); + var s = Math.sin(theta); + + return Matrix.FromArray([ + c*scale, -s*scale, 0, 0, + s*scale, c*scale, 0, 0, + 0, 0, 1, 0, + x, y, 0, 1 + ]); + + //return new Matrix([ + // c*scale, -s*scale, 0, 0, + // s*scale, c*scale, 0, 0, + // 0, 0, 1, 0, + // x, y, 0, 1 + //]); + } + + inline public static function ReflectionToRef(plane:Plane, result:Matrix):Matrix { + plane.normalize(); + var x = plane.normal.x; + var y = plane.normal.y; + var z = plane.normal.z; + var temp = -2 * x; + var temp2 = -2 * y; + var temp3 = -2 * z; + result.m[0] = (temp * x) + 1; + result.m[1] = temp2 * x; + result.m[2] = temp3 * x; + result.m[3] = 0.0; + result.m[4] = temp * y; + result.m[5] = (temp2 * y) + 1; + result.m[6] = temp3 * y; + result.m[7] = 0.0; + result.m[8] = temp * z; + result.m[9] = temp2 * z; + result.m[10] = (temp3 * z) + 1; + result.m[11] = 0.0; + result.m[12] = temp * plane.d; + result.m[13] = temp2 * plane.d; + result.m[14] = temp3 * plane.d; + result.m[15] = 1.0; + + return result; + } + +} diff --git a/src/com/engine/math/Plane.hx b/src/com/engine/math/Plane.hx new file mode 100755 index 0000000..31912de --- /dev/null +++ b/src/com/engine/math/Plane.hx @@ -0,0 +1,118 @@ +package com.engine.math; + + + + +class Plane { + + public var normal:Vector3; + public var d:Float; + + public function new(a:Float, b:Float, c:Float, d:Float) { + this.normal = new Vector3(a, b, c); + this.d = d; + } + + public function clone():Plane { + return new Plane(this.normal.x, this.normal.y, this.normal.z, this.d); + } + + inline public function normalize() { + var norm = (Math.sqrt((this.normal.x * this.normal.x) + (this.normal.y * this.normal.y) + (this.normal.z * this.normal.z))); + var magnitude:Float = 0; + + if (norm != 0) { + magnitude = 1.0 / norm; + } + + this.normal.x *= magnitude; + this.normal.y *= magnitude; + this.normal.z *= magnitude; + + this.d *= magnitude; + } + + inline public function transform(transformation:Matrix):Plane { + var transposedMatrix = Matrix.Transpose(transformation); + var x = this.normal.x; + var y = this.normal.y; + var z = this.normal.z; + var d = this.d; + + var normalX = (((x * transposedMatrix.m[0]) + (y * transposedMatrix.m[1])) + (z * transposedMatrix.m[2])) + (d * transposedMatrix.m[3]); + var normalY = (((x * transposedMatrix.m[4]) + (y * transposedMatrix.m[5])) + (z * transposedMatrix.m[6])) + (d * transposedMatrix.m[7]); + var normalZ = (((x * transposedMatrix.m[8]) + (y * transposedMatrix.m[9])) + (z * transposedMatrix.m[10])) + (d * transposedMatrix.m[11]); + var finalD = (((x * transposedMatrix.m[12]) + (y * transposedMatrix.m[13])) + (z * transposedMatrix.m[14])) + (d * transposedMatrix.m[15]); + + return new Plane(normalX, normalY, normalZ, finalD); + } + + inline public function dotCoordinate(point:Vector3):Float { + return ((((this.normal.x * point.x) + (this.normal.y * point.y)) + (this.normal.z * point.z)) + this.d); + } + + inline public function copyFromPoints(point1:Vector3, point2:Vector3, point3:Vector3) { + var x1 = point2.x - point1.x; + var y1 = point2.y - point1.y; + var z1 = point2.z - point1.z; + var x2 = point3.x - point1.x; + var y2 = point3.y - point1.y; + var z2 = point3.z - point1.z; + var yz = (y1 * z2) - (z1 * y2); + var xz = (z1 * x2) - (x1 * z2); + var xy = (x1 * y2) - (y1 * x2); + var pyth = (Math.sqrt((yz * yz) + (xz * xz) + (xy * xy))); + var invPyth; + + if (pyth != 0) { + invPyth = 1.0 / pyth; + } + else { + invPyth = 0; + } + + this.normal.x = yz * invPyth; + this.normal.y = xz * invPyth; + this.normal.z = xy * invPyth; + this.d = -((this.normal.x * point1.x) + (this.normal.y * point1.y) + (this.normal.z * point1.z)); + } + + inline public function isFrontFacingTo(direction:Vector3, epsilon:Float):Bool { + var dot = Vector3.Dot(this.normal, direction); + + return (dot <= epsilon); + } + + inline public function signedDistanceTo(point:Vector3):Float { + return Vector3.Dot(point, this.normal) + this.d; + } + + + inline public static function FromArray(array:Array):Plane { + return new Plane(array[0], array[1], array[2], array[3]); + } + + inline public static function FromPoints(point1:Vector3, point2:Vector3, point3:Vector3):Plane { + var result = new Plane(0, 0, 0, 0); + result.copyFromPoints(point1, point2, point3); + + return result; + } + + inline public static function FromPositionAndNormal(origin:Vector3, normal:Vector3):Plane { + var result = new Plane(0, 0, 0, 0); + normal.normalize(); + + result.normal = normal; + result.d = -(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z); + + return result; + } + + inline public static function SignedDistanceToPlaneFromPositionAndNormal(origin:Vector3, normal:Vector3, point:Vector3):Float { + var d = -(normal.x * origin.x + normal.y * origin.y + normal.z * origin.z); + + return Vector3.Dot(point, normal) + d; + } + +} diff --git a/src/com/engine/math/Quaternion.hx b/src/com/engine/math/Quaternion.hx new file mode 100755 index 0000000..04395c0 --- /dev/null +++ b/src/com/engine/math/Quaternion.hx @@ -0,0 +1,190 @@ +package com.engine.math; + + + + +class Quaternion { + + public var x:Float; + public var y:Float; + public var z:Float; + public var w:Float; + + public function toString():String { + return "{X: " + this.x + " Y:" + this.y + " Z:" + this.z + " W:" + this.w + "}"; + } + + public function new(initialX:Float = 0, initialY:Float = 0, initialZ:Float = 0, initialW:Float = 0) { + this.x = initialX; + this.y = initialY; + this.z = initialZ; + this.w = initialW; + } + + inline public function equals(otherQuaternion:Quaternion):Bool { + return this.x == otherQuaternion.x && this.y == otherQuaternion.y && this.z == otherQuaternion.z && this.w == otherQuaternion.w; + } + + inline public function clone():Quaternion { + return new Quaternion(this.x, this.y, this.z, this.w); + } + + inline public function copyFrom(other:Quaternion) { + this.x = other.x; + this.y = other.y; + this.z = other.z; + this.w = other.w; + } + + inline public function add(other:Quaternion):Quaternion { + return new Quaternion(this.x + other.x, this.y + other.y, this.z + other.z, this.w + other.w); + } + + inline public function scale(value:Float):Quaternion { + return new Quaternion(this.x * value, this.y * value, this.z * value, this.w * value); + } + + inline public function multiply(q1:Quaternion):Quaternion { + var result = new Quaternion(0, 0, 0, 1.0); + this.multiplyToRef(q1, result); + + return result; + } + + inline public function multiplyToRef(q1:Quaternion, result:Quaternion):Quaternion { + result.x = this.x * q1.w + this.y * q1.z - this.z * q1.y + this.w * q1.x; + result.y = -this.x * q1.z + this.y * q1.w + this.z * q1.x + this.w * q1.y; + result.z = this.x * q1.y - this.y * q1.x + this.z * q1.w + this.w * q1.z; + result.w = -this.x * q1.x - this.y * q1.y - this.z * q1.z + this.w * q1.w; + + return result; + } + + inline public function length():Float { + return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z) + (this.w * this.w)); + } + + inline public function normalize() { + var length = 1.0 / this.length(); + this.x *= length; + this.y *= length; + this.z *= length; + this.w *= length; + } + + inline public function toEulerAngles():Vector3 { + var qx = this.x; + var qy = this.y; + var qz = this.z; + var qw = this.w; + + var sqx = qx * qx; + var sqy = qy * qy; + var sqz = qz * qz; + + var yaw = Math.atan2(2.0 * (qy * qw - qx * qz), 1.0 - 2.0 * (sqy + sqz)); + var pitch = Math.asin(2.0 * (qx * qy + qz * qw)); + var roll = Math.atan2(2.0 * (qx * qw - qy * qz), 1.0 - 2.0 * (sqx + sqz)); + + var gimbaLockTest = qx * qy + qz * qw; + if (gimbaLockTest > 0.499) { + yaw = 2.0 * Math.atan2(qx, qw); + roll = 0; + } else if (gimbaLockTest < -0.499) { + yaw = -2.0 * Math.atan2(qx, qw); + roll = 0; + } + + return new Vector3(pitch, yaw, roll); + } + + inline public function toRotationMatrix(result:Matrix):Matrix { + var xx = this.x * this.x; + var yy = this.y * this.y; + var zz = this.z * this.z; + var xy = this.x * this.y; + var zw = this.z * this.w; + var zx = this.z * this.x; + var yw = this.y * this.w; + var yz = this.y * this.z; + var xw = this.x * this.w; + + result.m[0] = 1.0 - (2.0 * (yy + zz)); + result.m[1] = 2.0 * (xy + zw); + result.m[2] = 2.0 * (zx - yw); + result.m[3] = 0; + result.m[4] = 2.0 * (xy - zw); + result.m[5] = 1.0 - (2.0 * (zz + xx)); + result.m[6] = 2.0 * (yz + xw); + result.m[7] = 0; + result.m[8] = 2.0 * (zx + yw); + result.m[9] = 2.0 * (yz - xw); + result.m[10] = 1.0 - (2.0 * (yy + xx)); + result.m[11] = 0; + result.m[12] = 0; + result.m[13] = 0; + result.m[14] = 0; + result.m[15] = 1.0; + + return result; + } + + + inline public static function FromArray(array:Array, offset:Int = 0):Quaternion { + return new Quaternion(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]); + } + + inline public static function RotationYawPitchRoll(yaw:Float, pitch:Float, roll:Float):Quaternion { + var result = new Quaternion(); + Quaternion.RotationYawPitchRollToRef(yaw, pitch, roll, result); + + return result; + } + + inline public static function RotationYawPitchRollToRef(yaw:Float, pitch:Float, roll:Float, result:Quaternion):Quaternion { + var halfRoll = roll * 0.5; + var halfPitch = pitch * 0.5; + var halfYaw = yaw * 0.5; + + var sinRoll = Math.sin(halfRoll); + var cosRoll = Math.cos(halfRoll); + var sinPitch = Math.sin(halfPitch); + var cosPitch = Math.cos(halfPitch); + var sinYaw = Math.sin(halfYaw); + var cosYaw = Math.cos(halfYaw); + + result.x = (cosYaw * sinPitch * cosRoll) + (sinYaw * cosPitch * sinRoll); + result.y = (sinYaw * cosPitch * cosRoll) - (cosYaw * sinPitch * sinRoll); + result.z = (cosYaw * cosPitch * sinRoll) - (sinYaw * sinPitch * cosRoll); + result.w = (cosYaw * cosPitch * cosRoll) + (sinYaw * sinPitch * sinRoll); + + return result; + } + + inline public static function Slerp(left:Quaternion, right:Quaternion, amount:Float):Quaternion { + var num2:Float; + var num3:Float; + var num = amount; + var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w); + var flag = false; + + if (num4 < 0) { + flag = true; + num4 = -num4; + } + + if (num4 > 0.999999) { + num3 = 1 - num; + num2 = flag ? -num : num; + } + else { + var num5 = Math.acos(num4); + var num6 = (1.0 / Math.sin(num5)); + num3 = (Math.sin((1.0 - num) * num5)) * num6; + num2 = flag ? ((-Math.sin(num * num5)) * num6) : ((Math.sin(num * num5)) * num6); + } + + return new Quaternion((num3 * left.x) + (num2 * right.x), (num3 * left.y) + (num2 * right.y), (num3 * left.z) + (num2 * right.z), (num3 * left.w) + (num2 * right.w)); + } + +} diff --git a/src/com/engine/math/Vector2.hx b/src/com/engine/math/Vector2.hx new file mode 100755 index 0000000..3da4814 --- /dev/null +++ b/src/com/engine/math/Vector2.hx @@ -0,0 +1,185 @@ +package com.engine.math; + + + +class Vector2 { + + public var x:Float; + public var y:Float; + + + static public function Sub(a:Vector2, b:Vector2):Vector2 + { + return new Vector2(a.x - b.x, a.y - b.y); + } + static public function Add(a:Vector2, b:Vector2):Vector2 + { + return new Vector2(a.x + b.x, a.y + b.y); + } + + public function new(x:Float, y:Float) { + this.x = x; + this.y = y; + } + + public function toString():String { + return "{X: " + this.x + " Y:" + this.y + "}"; + } + + // Operators + inline public function add(otherVector:Vector2):Vector2 { + return new Vector2(this.x + otherVector.x, this.y + otherVector.y); + } + + inline public function asArray():Array { + var result = []; + this.toArray(result, 0); + return result; + } + + inline public function toArray(array:Array, index:Int = 0) { + array[index] = this.x; + array[index + 1] = this.y; + } + + inline public function subtract(otherVector:Vector2):Vector2 { + return new Vector2(this.x - otherVector.x, this.y - otherVector.y); + } + + inline public function negate():Vector2{ + return new Vector2( -this.x, -this.y); + } + + inline public function scaleInPlace(scale:Float) { + this.x *= scale; + this.y *= scale; + } + + inline public function scale(scale:Float):Vector2 { + return new Vector2(this.x * scale, this.y * scale); + } + + inline public function equals(otherVector:Vector2):Bool { + return this.x == otherVector.x && this.y == otherVector.y; + } + + inline public function length():Float { + return Math.sqrt(this.x * this.x + this.y * this.y); + } + + inline public function lengthSquared():Float { + return (this.x * this.x + this.y * this.y); + } + + inline public function normalize() { + var len = length(); + + if (len != 0) { + var num = 1.0 / len; + + this.x *= num; + this.y *= num; + } + } + + inline public function clone():Vector2 { + return new Vector2(this.x, this.y); + } + + + // Statics + inline public static function Zero():Vector2 { + return new Vector2(0, 0); + } + + inline public static function CatmullRom(value1:Vector2, value2:Vector2, value3:Vector2, value4:Vector2, amount:Float):Vector2 { + var squared = amount * amount; + var cubed = amount * squared; + + var x = 0.5 * ((((2.0 * value2.x) + ((-value1.x + value3.x) * amount)) + + (((((2.0 * value1.x) - (5.0 * value2.x)) + (4.0 * value3.x)) - value4.x) * squared)) + + ((((-value1.x + (3.0 * value2.x)) - (3.0 * value3.x)) + value4.x) * cubed)); + + var y = 0.5 * ((((2.0 * value2.y) + ((-value1.y + value3.y) * amount)) + + (((((2.0 * value1.y) - (5.0 * value2.y)) + (4.0 * value3.y)) - value4.y) * squared)) + + ((((-value1.y + (3.0 * value2.y)) - (3.0 * value3.y)) + value4.y) * cubed)); + + return new Vector2(x, y); + } + + inline public static function Clamp(value:Vector2, min:Vector2, max:Vector2):Vector2 { + var x = value.x; + x = (x > max.x) ? max.x : x; + x = (x < min.x) ? min.x : x; + + var y = value.y; + y = (y > max.y) ? max.y : y; + y = (y < min.y) ? min.y : y; + + return new Vector2(x, y); + } + + inline public static function Hermite(value1:Vector2, tangent1:Vector2, value2:Vector2, tangent2:Vector2, amount:Float):Vector2 { + var squared = amount * amount; + var cubed = amount * squared; + var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0; + var part2 = (-2.0 * cubed) + (3.0 * squared); + var part3 = (cubed - (2.0 * squared)) + amount; + var part4 = cubed - squared; + + var _x = (((value1.x * part1) + (value2.x * part2)) + (tangent1.x * part3)) + (tangent2.x * part4); + var _y = (((value1.y * part1) + (value2.y * part2)) + (tangent1.y * part3)) + (tangent2.y * part4); + + return new Vector2(_x, _y); + } + + inline public static function Lerp(start:Vector2, end:Vector2, amount:Float):Vector2 { + var _x = start.x + ((end.x - start.x) * amount); + var _y = start.y + ((end.y - start.y) * amount); + + return new Vector2(_x, _y); + } + + inline public static function Dot(left:Vector2, right:Vector2):Float { + return left.x * right.x + left.y * right.y; + } + + inline public static function Normalize(vector:Vector2):Vector2 { + var newVector = vector.clone(); + newVector.normalize(); + return newVector; + } + + inline public static function Minimize(left:Vector2, right:Vector2):Vector2 { + var _x = (left.x < right.x) ? left.x : right.x; + var _y = (left.y < right.y) ? left.y : right.y; + + return new Vector2(_x, _y); + } + + inline public static function Maximize(left:Vector2, right:Vector2):Vector2 { + var _x = (left.x > right.x) ? left.x : right.x; + var _y = (left.y > right.y) ? left.y : right.y; + + return new Vector2(_x, _y); + } + + inline public static function Transform(vector:Vector2, transformation:Matrix):Vector2 { + var _x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]); + var _y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]); + + return new Vector2(_x, _y); + } + + inline public static function Distance(value1:Vector2, value2:Vector2):Float { + return Math.sqrt(Vector2.DistanceSquared(value1, value2)); + } + + inline public static function DistanceSquared(value1:Vector2, value2:Vector2):Float { + var _x = value1.x - value2.x; + var _y = value1.y - value2.y; + + return (_x * _x) + (_y * _y); + } + +} diff --git a/src/com/engine/math/Vector3.hx b/src/com/engine/math/Vector3.hx new file mode 100755 index 0000000..dd53ab0 --- /dev/null +++ b/src/com/engine/math/Vector3.hx @@ -0,0 +1,411 @@ +package com.engine.math; +import com.engine.render.Clip; +import openfl.utils.Float32Array; +import com.engine.misc.Util; + + +class Vector3 { + + public var x:Float; + public var y:Float; + public var z:Float; + + public function set(initialX:Float, initialY:Float, ?initialZ:Float = 0) + { + this.x = initialX; + this.y = initialY; + this.z = initialZ; + } + + static public function Sub(a:Vector3, b:Vector3):Vector3 + { + return new Vector3(a.x - b.x, a.y - b.y,a.z-b.z); + } + static public function Add(a:Vector3, b:Vector3):Vector3 + { + return new Vector3(a.x + b.x, a.y + b.y,a.z+b.z); + } + + public function new(initialX:Float, initialY:Float, ?initialZ:Float=0) { + this.x = initialX; + this.y = initialY; + this.z = initialZ; + } + + public function toString():String { + return "{X:" + this.x + " Y:" + this.y + " Z:" + this.z + "}"; + } + + inline public function asArray():Array { + var result = []; + this.toArray(result, 0); + return result; + } + + inline public function toArray(array:Array, index:Int = 0):Array { + array[index] = this.x; + array[index + 1] = this.y; + array[index + 2] = this.z; + return array; + } + + inline public function addInPlace(otherVector:Vector3) { + this.x += otherVector.x; + this.y += otherVector.y; + this.z += otherVector.z; + } + + inline public function add(otherVector:Vector3):Vector3 { + return new Vector3(this.x + otherVector.x, this.y + otherVector.y, this.z + otherVector.z); + } + + inline public function addToRef(otherVector:Vector3, result:Vector3):Vector3 { + result.x = this.x + otherVector.x; + result.y = this.y + otherVector.y; + result.z = this.z + otherVector.z; + return result; + } + + inline public function subtractInPlace(otherVector:Vector3) { + this.x -= otherVector.x; + this.y -= otherVector.y; + this.z -= otherVector.z; + } + + inline public function subtract(otherVector:Vector3):Vector3 { + return new Vector3(this.x - otherVector.x, this.y - otherVector.y, this.z - otherVector.z); + } + + inline public function subtractToRef(otherVector:Vector3, result:Vector3) { + result.x = this.x - otherVector.x; + result.y = this.y - otherVector.y; + result.z = this.z - otherVector.z; + } + + inline public function subtractFromFloats(x:Float, y:Float, z:Float):Vector3 { + return new Vector3(this.x - x, this.y - y, this.z - z); + } + + inline public function subtractFromFloatsToRef(x:Float, y:Float, z:Float, result:Vector3) { + result.x = this.x - x; + result.y = this.y - y; + result.z = this.z - z; + } + + inline public function negate():Vector3 { + return new Vector3( -this.x, -this.y, -this.z); + } + + inline public function scaleInPlace(scale:Float) { + this.x *= scale; + this.y *= scale; + this.z *= scale; + } + + inline public function scale(scale:Float):Vector3 { + return new Vector3(this.x * scale, this.y * scale, this.z * scale); + } + + inline public function scaleToRef(scale:Float, result:Vector3) { + result.x = this.x * scale; + result.y = this.y * scale; + result.z = this.z * scale; + } + + inline public function equals(otherVector:Vector3):Bool { + return this.x == otherVector.x && this.y == otherVector.y && this.z == otherVector.z; + } + + inline public function equalsToFloats(x:Float, y:Float, z:Float):Bool { + return this.x == x && this.y == y && this.z == z; + } + + inline public function multiplyInPlace(otherVector:Vector3) { + this.x *= otherVector.x; + this.y *= otherVector.y; + this.z *= otherVector.z; + } + + inline public function multiply(otherVector:Vector3):Vector3 { + return new Vector3(this.x * otherVector.x, this.y * otherVector.y, this.z * otherVector.z); + } + + inline public function multiplyToRef(otherVector:Vector3, result:Vector3) { + result.x = this.x * otherVector.x; + result.y = this.y * otherVector.y; + result.z = this.z * otherVector.z; + } + + inline public function multiplyByFloats(x:Float, y:Float, z:Float):Vector3 { + return new Vector3(this.x * x, this.y * y, this.z * z); + } + + inline public function divide(otherVector:Vector3):Vector3 { + return new Vector3(this.x / otherVector.x, this.y / otherVector.y, this.z / otherVector.z); + } + + inline public function divideToRef(otherVector:Vector3, result:Vector3) { + result.x = this.x / otherVector.x; + result.y = this.y / otherVector.y; + result.z = this.z / otherVector.z; + } + + inline public function length():Float { + return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + } + + inline public function lengthSquared():Float { + return (this.x * this.x + this.y * this.y + this.z * this.z); + } + + inline public function normalize() { + var len = this.length(); + + if (len != 0) { + var num = 1.0 / len; + + this.x *= num; + this.y *= num; + this.z *= num; + } + } + + inline public function clone():Vector3 { + return new Vector3(this.x, this.y, this.z); + } + + inline public function copyFrom(source:Vector3) { + this.x = source.x; + this.y = source.y; + this.z = source.z; + } + + inline public function copyFromFloats(x:Float, y:Float, z:Float) { + this.x = x; + this.y = y; + this.z = z; + } + + + inline public static function FromArray(array:Array, offset:Int = 0) { + return new Vector3(array[offset], array[offset + 1], array[offset + 2]); + } + + inline public static function FromArrayToRef(array:Array, offset:Int = 0, result:Vector3) { + result.x = array[offset]; + result.y = array[offset + 1]; + result.z = array[offset + 2]; + } + + inline public static function FromFloatsToRef(x:Float, y:Float, z:Float, result:Vector3) { + result.x = x; + result.y = y; + result.z = z; + } + + public static function Zero():Vector3 { + return new Vector3(0.0, 0.0, 0.0); + } + + public static function Up():Vector3 { + return new Vector3(0, 1.0, 0); + } + + inline public static function TransformCoordinates(vector:Vector3, transformation:Matrix):Vector3 { + var result = Vector3.Zero(); + + Vector3.TransformCoordinatesToRef(vector, transformation, result); + + return result; + } + + inline public static function TransformCoordinatesToRef(vector:Vector3, transformation:Matrix, result:Vector3) { + var x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]) + transformation.m[12]; + var y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + (vector.z * transformation.m[9]) + transformation.m[13]; + var z = (vector.x * transformation.m[2]) + (vector.y * transformation.m[6]) + (vector.z * transformation.m[10]) + transformation.m[14]; + var w = (vector.x * transformation.m[3]) + (vector.y * transformation.m[7]) + (vector.z * transformation.m[11]) + transformation.m[15]; + + result.x = x / w; + result.y = y / w; + result.z = z / w; + } + + inline public static function TransformCoordinatesFromFloatsToRef(x:Float, y:Float, z:Float, transformation:Matrix, result:Vector3):Vector3 { + var rx = (x * transformation.m[0]) + (y * transformation.m[4]) + (z * transformation.m[8]) + transformation.m[12]; + var ry = (x * transformation.m[1]) + (y * transformation.m[5]) + (z * transformation.m[9]) + transformation.m[13]; + var rz = (x * transformation.m[2]) + (y * transformation.m[6]) + (z * transformation.m[10]) + transformation.m[14]; + var rw = (x * transformation.m[3]) + (y * transformation.m[7]) + (z * transformation.m[11]) + transformation.m[15]; + + result.x = rx / rw; + result.y = ry / rw; + result.z = rz / rw; + + return result; + } + + inline public static function TransformNormal(vector:Vector3, transformation:Matrix):Vector3 { + var result = Vector3.Zero(); + + Vector3.TransformNormalToRef(vector, transformation, result); + + return result; + } + + inline public static function TransformNormalToRef(vector:Vector3, transformation:Matrix, result:Vector3) { + result.x = (vector.x * transformation.m[0]) + (vector.y * transformation.m[4]) + (vector.z * transformation.m[8]); + result.y = (vector.x * transformation.m[1]) + (vector.y * transformation.m[5]) + (vector.z * transformation.m[9]); + result.z = (vector.x * transformation.m[2]) + (vector.y * transformation.m[6]) + (vector.z * transformation.m[10]); + } + + inline public static function TransformNormalFromFloatsToRef(x:Float, y:Float, z:Float, transformation:Matrix, result:Vector3) { + result.x = (x * transformation.m[0]) + (y * transformation.m[4]) + (z * transformation.m[8]); + result.y = (x * transformation.m[1]) + (y * transformation.m[5]) + (z * transformation.m[9]); + result.z = (x * transformation.m[2]) + (y * transformation.m[6]) + (z * transformation.m[10]); + } + + + inline public static function CatmullRom(value1:Vector3, value2:Vector3, value3:Vector3, value4:Vector3, amount:Float):Vector3 { + var squared = amount * amount; + var cubed = amount * squared; + + var x = 0.5 * ((((2.0 * value2.x) + ((-value1.x + value3.x) * amount)) + + (((((2.0 * value1.x) - (5.0 * value2.x)) + (4.0 * value3.x)) - value4.x) * squared)) + + ((((-value1.x + (3.0 * value2.x)) - (3.0 * value3.x)) + value4.x) * cubed)); + + var y = 0.5 * ((((2.0 * value2.y) + ((-value1.y + value3.y) * amount)) + + (((((2.0 * value1.y) - (5.0 * value2.y)) + (4.0 * value3.y)) - value4.y) * squared)) + + ((((-value1.y + (3.0 * value2.y)) - (3.0 * value3.y)) + value4.y) * cubed)); + + var z = 0.5 * ((((2.0 * value2.z) + ((-value1.z + value3.z) * amount)) + + (((((2.0 * value1.z) - (5.0 * value2.z)) + (4.0 * value3.z)) - value4.z) * squared)) + + ((((-value1.z + (3.0 * value2.z)) - (3.0 * value3.z)) + value4.z) * cubed)); + + return new Vector3(x, y, z); + } + + inline public static function Clamp(value:Vector3, min:Vector3, max:Vector3):Vector3 { + var x = value.x; + x = (x > max.x) ? max.x : x; + x = (x < min.x) ? min.x : x; + + var y = value.y; + y = (y > max.y) ? max.y : y; + y = (y < min.y) ? min.y : y; + + var z = value.z; + z = (z > max.z) ? max.z : z; + z = (z < min.z) ? min.z : z; + + return new Vector3(x, y, z); + } + + inline public static function Hermite(value1:Vector3, tangent1:Vector3, value2:Vector3, tangent2:Vector3, amount:Float):Vector3 { + var squared = amount * amount; + var cubed = amount * squared; + var part1 = ((2.0 * cubed) - (3.0 * squared)) + 1.0; + var part2 = (-2.0 * cubed) + (3.0 * squared); + var part3 = (cubed - (2.0 * squared)) + amount; + var part4 = cubed - squared; + + var x = (((value1.x * part1) + (value2.x * part2)) + (tangent1.x * part3)) + (tangent2.x * part4); + var y = (((value1.y * part1) + (value2.y * part2)) + (tangent1.y * part3)) + (tangent2.y * part4); + var z = (((value1.z * part1) + (value2.z * part2)) + (tangent1.z * part3)) + (tangent2.z * part4); + + return new Vector3(x, y, z); + } + + inline public static function Lerp(start:Vector3, end:Vector3, amount:Float):Vector3 { + var x = start.x + ((end.x - start.x) * amount); + var y = start.y + ((end.y - start.y) * amount); + var z = start.z + ((end.z - start.z) * amount); + + return new Vector3(x, y, z); + } + + inline public static function Dot(left:Vector3, right:Vector3):Float { + return (left.x * right.x + left.y * right.y + left.z * right.z); + } + + inline public static function Cross(left:Vector3, right:Vector3):Vector3 { + var result = Vector3.Zero(); + Vector3.CrossToRef(left, right, result); + return result; + } + + inline public static function CrossToRef(left:Vector3, right:Vector3, result:Vector3) { + result.x = left.y * right.z - left.z * right.y; + result.y = left.z * right.x - left.x * right.z; + result.z = left.x * right.y - left.y * right.x; + } + + inline public static function Normalize(vector:Vector3):Vector3 { + var result = Vector3.Zero(); + Vector3.NormalizeToRef(vector, result); + return result; + } + + inline public static function NormalizeToRef(vector:Vector3, result:Vector3) { + result.copyFrom(vector); + result.normalize(); + } + + + inline public static function Project(vector:Vector3, world:Matrix, transform:Matrix, viewport:Clip):Vector3 { + var cw = viewport.width; + var ch = viewport.height; + var cx = viewport.x; + var cy = viewport.y; + + var viewportMatrix = Matrix.FromValues( + cw / 2.0, 0, 0, 0, + 0, -ch / 2.0, 0, 0, + 0, 0, 1, 0, + cx + cw / 2.0, ch / 2.0 + cy, 0, 1); + + var finalMatrix = world.multiply(transform).multiply(viewportMatrix); + + return Vector3.TransformCoordinates(vector, finalMatrix); + } + + inline public static function Unproject(source:Vector3, viewportWidth:Float, viewportHeight:Float, world:Matrix, view:Matrix, projection:Matrix):Vector3 { + var matrix = world.multiply(view).multiply(projection); + matrix.invert(); + source.x = source.x / viewportWidth * 2 - 1; + source.y = -(source.y / viewportHeight * 2 - 1); + var vector = Vector3.TransformCoordinates(source, matrix); + var num = source.x * matrix.m[3] + source.y * matrix.m[7] + source.z * matrix.m[11] + matrix.m[15]; + + if (Util.WithinEpsilon(num, 1.0)) { + vector = vector.scale(1.0 / num); + } + + return vector; + } + + inline public static function Minimize(left:Vector3, right:Vector3):Vector3 { + var x = (left.x < right.x) ? left.x : right.x; + var y = (left.y < right.y) ? left.y : right.y; + var z = (left.z < right.z) ? left.z : right.z; + return new Vector3(x, y, z); + } + + inline public static function Maximize(left:Vector3, right:Vector3):Vector3 { + var x = (left.x > right.x) ? left.x : right.x; + var y = (left.y > right.y) ? left.y : right.y; + var z = (left.z > right.z) ? left.z : right.z; + return new Vector3(x, y, z); + } + + inline public static function Distance(value1:Vector3, value2:Vector3):Float { + return Math.sqrt(Vector3.DistanceSquared(value1, value2)); + } + + inline public static function DistanceSquared(value1:Vector3, value2:Vector3):Float { + var x = value1.x - value2.x; + var y = value1.y - value2.y; + var z = value1.z - value2.z; + + return (x * x) + (y * y) + (z * z); + } + +} diff --git a/src/com/engine/misc/Color3.hx b/src/com/engine/misc/Color3.hx new file mode 100755 index 0000000..ed8c907 --- /dev/null +++ b/src/com/engine/misc/Color3.hx @@ -0,0 +1,78 @@ +package com.engine.misc; + + + +class Color3 { + + public var r:Float; + public var g:Float; + public var b:Float; + + public function new(initialR:Float = 0, initialG:Float = 0, initialB:Float = 0) { + this.r = initialR; + this.g = initialG; + this.b = initialB; + } + + inline public function equals(otherColor:Color3):Bool { + return this.r == otherColor.r && this.g == otherColor.g && this.b == otherColor.b; + } + + public function toString():String { + return "{R: " + this.r + " G:" + this.g + " B:" + this.b + "}"; + } + + inline public function clone():Color3 { + return new Color3(this.r, this.g, this.b); + } + + inline public function asArray():Array { + var result = []; + this.toArray(result, 0); + return result; + } + + inline public function toArray(array:Array, index:Int = 0) { + array[index] = this.r; + array[index + 1] = this.g; + array[index + 2] = this.b; + } + + inline public function multiply(otherColor:Color3):Color3 { + return new Color3(this.r * otherColor.r, this.g * otherColor.g, this.b * otherColor.b); + } + + inline public function multiplyToRef(otherColor:Color3, result:Color3) { + result.r = this.r * otherColor.r; + result.g = this.g * otherColor.g; + result.b = this.b * otherColor.b; + } + + inline public function scale(scale:Float):Color3 { + return new Color3(this.r * scale, this.g * scale, this.b * scale); + } + + inline public function scaleToRef(scale:Float, result:Color3) { + result.r = this.r * scale; + result.g = this.g * scale; + result.b = this.b * scale; + } + + inline public function copyFrom(source:Color3) { + this.r = source.r; + this.g = source.g; + this.b = source.b; + } + + inline public function copyFromFloats(r:Float, g:Float, b:Float) { + this.r = r; + this.g = g; + this.b = b; + } + + + inline public static function FromArray(array:Array):Color3 { + return new Color3(array[0], array[1], array[2]); + } + +} diff --git a/src/com/engine/misc/Color4.hx b/src/com/engine/misc/Color4.hx new file mode 100755 index 0000000..baf0b10 --- /dev/null +++ b/src/com/engine/misc/Color4.hx @@ -0,0 +1,97 @@ +package com.engine.misc; + + + + +class Color4 { + + public var r:Float; + public var g:Float; + public var b:Float; + public var a:Float; + + public function new(initialR:Float, initialG:Float, initialB:Float, initialA:Float = 1.0) { + this.r = initialR; + this.g = initialG; + this.b = initialB; + this.a = initialA; + } + + inline public function addInPlace(right:Color4) { + this.r += right.r; + this.g += right.g; + this.b += right.b; + this.a += right.a; + } + + public inline function asArray():Array { + var result = []; + this.toArray(result, 0); + return result; + } + + public inline function toArray(array:Array, index:Int = 0) { + array[index] = this.r; + array[index + 1] = this.g; + array[index + 2] = this.b; + array[index + 3] = this.a; + } + + inline public function add(right:Color4):Color4 { + return new Color4(this.r + right.r, this.g + right.g, this.b + right.b, this.a + right.a); + } + + inline public function subtract(right:Color4):Color4 { + return new Color4(this.r - right.r, this.g - right.g, this.b - right.b, this.a - right.a); + } + + inline public function subtractToRef(right:Color4, result:Color4):Color4 { + result.r = this.r - right.r; + result.g = this.g - right.g; + result.b = this.b - right.b; + result.a = this.a - right.a; + + return result; + } + + inline public function scale(scale:Float):Color4 { + return new Color4(this.r * scale, this.g * scale, this.b * scale, this.a * scale); + } + + inline public function scaleToRef(scale:Float, result:Color4):Color4 { + result.r = this.r * scale; + result.g = this.g * scale; + result.b = this.b * scale; + result.a = this.a * scale; + + return result; + } + + public function toString() { + return "{R: " + this.r + " G:" + this.g + " B:" + this.b + " A:" + this.a + "}"; + } + + public function clone():Color4 { + return new Color4(this.r, this.g, this.b, this.a); + } + + + inline public static function Lerp(left:Color4, right:Color4, amount:Float):Color4 { + var result = new Color4(0, 0, 0, 0); + return Color4.LerpToRef(left, right, amount, result); + } + + inline public static function LerpToRef(left:Color4, right:Color4, amount:Float, result:Color4):Color4 { + result.r = left.r + (right.r - left.r) * amount; + result.g = left.g + (right.g - left.g) * amount; + result.b = left.b + (right.b - left.b) * amount; + result.a = left.a + (right.a - left.a) * amount; + + return result; + } + + inline public static function FromArray(array:Array, offset:Int = 0):Color4 { + return new Color4(array[offset], array[offset + 1], array[offset + 2], array[offset + 3]); + } + +} diff --git a/src/com/engine/misc/MatrixHelp.hx b/src/com/engine/misc/MatrixHelp.hx new file mode 100755 index 0000000..f6d7138 --- /dev/null +++ b/src/com/engine/misc/MatrixHelp.hx @@ -0,0 +1,66 @@ +package com.engine.misc; + +import flash.geom.Matrix; + +import flash.display.Bitmap; +import flash.display.BitmapData; + +/** + * ... + * @author djoker + */ +class MatrixHelp +{ + + + inline static public function getScaled(source:BitmapData, newWidth:Int, newHeight:Int):BitmapData + { + var m:flash.geom.Matrix = new flash.geom.Matrix(); + m.scale(newWidth / source.width, newHeight / source.height); + + var bmp:BitmapData = new BitmapData(newWidth, newHeight, true,0xff); + + bmp.draw(source, m); + return bmp; + } + + inline static public function flipBitmapData(original:BitmapData, axis:String = "y"):BitmapData +{ + var flipped:BitmapData = new BitmapData(original.width, original.height, true, 0); + var matrix:Matrix; + if(axis == "x"){ + matrix = new Matrix( -1, 0, 0, 1, original.width, 0); + } else { + matrix = new Matrix( 1, 0, 0, -1, 0, original.height); + } + flipped.draw(original, matrix, null, null, null, true); + return flipped; +} + +public static function skew(matrix:Matrix, skewX:Float, skewY:Float) + { + var sinX:Float = Math.sin(skewX); + var cosX:Float = Math.cos(skewX); + var sinY:Float = Math.sin(skewY); + var cosY:Float = Math.cos(skewY); + + setTo(matrix,matrix.a * cosY - matrix.b * sinX, + matrix.a * sinY + matrix.b * cosX, + matrix.c * cosY - matrix.d * sinX, + matrix.c * sinY + matrix.d * cosX, + matrix.tx * cosY - matrix.ty * sinX, + matrix.tx * sinY + matrix.ty * cosX); + } + public static function setTo (matrix:Matrix, a:Float, b:Float, c:Float, d:Float, tx:Float, ty:Float):Void + { + + matrix.a = a; + matrix.b = b; + matrix.c = c; + matrix.d = d; + matrix.tx = tx; + matrix.ty = ty; + + } + +} \ No newline at end of file diff --git a/src/com/engine/misc/SmartArray.hx b/src/com/engine/misc/SmartArray.hx new file mode 100755 index 0000000..c67e222 --- /dev/null +++ b/src/com/engine/misc/SmartArray.hx @@ -0,0 +1,78 @@ +package com.engine.misc; + + + +class SmartArray { + + public var data:Array; + public var length:Int; + + public function new() { + this.data = []; + this.length = 0; + } + + public function push(value:Dynamic) { + this.data[this.length++] = value; + + /*if (this.length > this.data.length) { + this.data.length *= 2; + }*/ + } + + public function pushNoDuplicate(value:Dynamic) { + if (Lambda.indexOf(this.data, value) == -1) { + this.push(value); + } + } + + public function sort(compareFn:Dynamic->Dynamic->Int) { + this.data.sort(compareFn); + } + + public function reset() { + this.length = 0; + //this.data = []; + } + + public function concat(array:Dynamic) { + // TODO - inspect and fix this + if (Std.is(array, Array) && array.length != 0) { + /*if (this.length + array.length > this.data.length) { + this.data.length = (this.length + array.length) * 2; + }*/ + for (index in 0...array.length) { + this.data[this.length++] = Std.is(array, Array) ? array[index] : array.data[index];// (array.data || array)[index]; + } + } + } + + public function concatWithNoDuplicate(array:Dynamic) { + if (Std.is(array, Array) && array.length == 0) { + return; + } + /*if (this.length + array.length > this.data.length) { + this.data.length = (this.length + array.length) * 2; + }*/ + + for (index in 0...array.length) { + var item = Std.is(array, Array) ? array[index] : array.data[index]; + var pos = Lambda.indexOf(this.data, item); + + if (pos == -1 || pos >= this.length) { + this.data[this.length++] = item; + } + } + } + + public function indexOf(value:Dynamic):Int { + var position = Lambda.indexOf(this.data, value); + + if (position >= this.length) { + return -1; + } + + return position; + } + +} diff --git a/src/com/engine/misc/Util.hx b/src/com/engine/misc/Util.hx new file mode 100755 index 0000000..7628a48 --- /dev/null +++ b/src/com/engine/misc/Util.hx @@ -0,0 +1,100 @@ +package com.engine.misc; + + +import flash.display.Bitmap; +import flash.display.BitmapData; + +import com.engine.math.Matrix; +import com.engine.math.Vector3; + +/** + * ... + * @author djoker + */ + class Util +{ + static public var DEG:Float = -180 / Math.PI; + static public var RAD:Float = Math.PI / -180; + static public var EPSILON:Float = 0.00000001; + + + static public function randf(max:Float, min:Float ):Float +{ + return Math.random() * (max - min) + min; +} +static public function randi(max:Int, min:Int ):Int +{ + return Std.int(Math.random() * (max - min) + min); + +} + + public static inline function WithinEpsilon(a:Float, b:Float):Bool { + var num:Float = a - b; + return -1.401298E-45 <= num && num <= 1.401298E-45; + } + public static function getColorValue(color:Int):Float + { + var h:Int = (color >> 16) & 0xFF; + var s:Int = (color >> 8) & 0xFF; + var v:Int = color & 0xFF; + + return Std.int(Math.max(h, Math.max(s, v))) / 255; + } + + + public static function deg2rad(deg:Float):Float + { + return deg / 180.0 * Math.PI; + } + public function rad2deg(rad:Float):Float + { + return rad / Math.PI * 180.0; + } + + + + inline static public function print(s:Dynamic) + { + // flash.Lib.trace(s); + } + + static public function deepCopy( arr : Array ) : Array + { + var r = new Array(); + for( i in 0...arr.length ) + r.push(copy(arr[i])); + return r; + } + + static private function copy( value : Dynamic) : T { + if( Std.is( value, Array ) ) + return cast deepCopy( value ); + else + return value; + } + function getExponantOfTwo(value:Int, max:Int):Int { + var count:Int = 1; + + do { + count *= 2; + } while (count < value); + + if (count > max) + count = max; + + return count; + } + + inline static public function getNextPowerOfTwo(number:Int):Int + { + if (number > 0 && (number & (number - 1)) == 0) // see: http://goo.gl/D9kPj + return number; + else + { + var result:Int = 1; + while (result < number) result <<= 1; + return result; + } + } + +} \ No newline at end of file diff --git a/src/com/engine/render/Batch.hx b/src/com/engine/render/Batch.hx new file mode 100755 index 0000000..5813595 --- /dev/null +++ b/src/com/engine/render/Batch.hx @@ -0,0 +1,334 @@ +package com.engine.render; + +import flash.geom.Matrix3D; + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; + + +import com.engine.render.BlendMode; + +/** + * ... + * @author djoker + */ +class Batch +{ + public var colorBuffer:GLBuffer; + public var colorIndex:Int; + public var colors:Float32Array; + + public var indexBuffer:GLBuffer; + public var indices:Int16Array; + public var uvBuffer:GLBuffer; + public var uvs:Float32Array; + public var vertexBuffer:GLBuffer; + public var vertices:Float32Array; + + private var capacity:Int; + private var numVerts:Int; + private var numIndices:Int; + + private var currentBatchSize:Int; + private var currentBlendMode:Int; + private var currentBaseTexture:Texture; + + + private var uvCount:Int; + private var colorCount:Int; + private var vertexCount:Int; + + + +public var shader:SpriteShader; + +private var invTexWidth:Float = 0; +private var invTexHeight:Float = 0; + + + public var vertexDeclaration:Array; + public var vertexStrideSize:Int; + + + public var camera:OrthoCamera; + + + public function new(texture:Texture,Camera:OrthoCamera,capacity:Int) + { + + + this.vertexBuffer = GL.createBuffer(); + this.indexBuffer = GL.createBuffer(); + this.uvBuffer = GL.createBuffer(); + this.colorBuffer = GL.createBuffer(); + + + this.capacity = capacity; + camera = Camera; + + + vertexDeclaration = [3, 2,4]; + vertexStrideSize = 9 * 4; // 9 floats (x, y, z,u,v, r, g, b, a) + + numVerts = capacity * vertexStrideSize * 4; + numIndices = capacity * 6; + + uvCount = 0; + colorCount=0; + vertexCount = 0; + + + + vertices = new Float32Array(capacity * 3 *4); + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.bufferData(GL.ARRAY_BUFFER,this.vertices , GL.DYNAMIC_DRAW); + + + uvs = new Float32Array(capacity * 2*4); + GL.bindBuffer(GL.ARRAY_BUFFER, this.uvBuffer); + GL.bufferData(GL.ARRAY_BUFFER, this.uvs , GL.DYNAMIC_DRAW); + + + colors = new Float32Array(capacity * 4 * 4); + GL.bindBuffer(GL.ARRAY_BUFFER, this.colorBuffer); + GL.bufferData(GL.ARRAY_BUFFER, this.colors , GL.DYNAMIC_DRAW); + + + + + + + + + this.indices = new Int16Array(numIndices); + var length = Std.int(this.indices.length/6); + + for (i in 0...length) + { + var index2 = i * 6; + var index3 = i * 4; + this.indices[index2 + 0] = index3 + 0; + this.indices[index2 + 1] = index3 + 1; + this.indices[index2 + 2] = index3 + 2; + this.indices[index2 + 3] = index3 + 0; + this.indices[index2 + 4] = index3 + 2; + this.indices[index2 + 5] = index3 + 3; + }; + + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, this.indices, GL.STATIC_DRAW); + + + + currentBatchSize = 0; + currentBlendMode = BlendMode.SCREEN; + this.currentBaseTexture = texture; + invTexWidth = 1.0 / texture.texWidth; + invTexHeight = 1.0 / texture.texHeight; + + shader = new SpriteShader(); + + } + public function dispose ():Void { + + this.vertices = new Float32Array ([]); + this.uvs = new Float32Array ([]); + this.indices = new Int16Array ([]); + this.colors = new Float32Array ([]); + GL.deleteBuffer(indexBuffer); + GL.deleteBuffer(vertexBuffer); + GL.deleteBuffer(colorBuffer); + GL.deleteBuffer(uvBuffer); + } + + + public function Begin() + { + uvCount = 0; + colorCount=0; + vertexCount = 0; + currentBatchSize = 0; + shader.Enable(); + + + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.bufferSubData(GL.ARRAY_BUFFER, 0, this.vertices); + GL.vertexAttribPointer(shader.vertexAttribute, 3, GL.FLOAT, false, 0, 0); + + GL.bindBuffer(GL.ARRAY_BUFFER, this.uvBuffer); + GL.bufferSubData(GL.ARRAY_BUFFER, 0, this.uvs); + GL.vertexAttribPointer(shader.texCoordAttribute , 2, GL.FLOAT, false, 0, 0); + + GL.activeTexture(GL.TEXTURE0); + currentBaseTexture.Bind(); + + GL.bindBuffer(GL.ARRAY_BUFFER, this.colorBuffer); + GL.bufferSubData(GL.ARRAY_BUFFER, 0, this.colors); + GL.vertexAttribPointer(shader.colorAttribute, 4, GL.FLOAT, false, 0,0); + + BlendMode.setBlend(currentBlendMode); + } + public function End() + { + if (currentBatchSize==0) return; + + + GL.uniformMatrix4fv(shader.projectionMatrixUniform, false,new Float32Array(camera.projMatrix.toArray())); + GL.uniformMatrix4fv(shader.modelViewMatrixUniform, false, new Float32Array(camera.modelViewMatrix.toArray())); + + GL.uniform1i (shader.imageUniform, 0); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + GL.drawElements(GL.TRIANGLES, currentBatchSize * 6, GL.UNSIGNED_SHORT, 0); + currentBatchSize = 0; + shader.Disable(); + } + + + + public function drawImage(img:Image) + { + + + + +var r, g, b, a:Float; +r = img.red; +g = img.green; +b = img.blue; +a = img.alpha; + + + + + + var worldOriginX:Float = img.x + img.originX; + var worldOriginY:Float = img.y + img.originY; + var fx:Float = -img.originX; + var fy:Float = -img.originY; + var fx2:Float = img.width - img.originX; + var fy2:Float = img.height - img.originY; + + if (img.scaleX != 1 || img.scaleY != 1) + { + fx *= img.scaleX; + fy *= img.scaleY; + fx2 *= img.scaleX; + fy2 *= img.scaleY; + } + + var p1x:Float = fx; + var p1y:Float = fy; + var p2x:Float = fx; + var p2y:Float = fy2; + var p3x:Float = fx2; + var p3y:Float = fy2; + var p4x:Float = fx2; + var p4y:Float = fy; + + var x1:Float; + var y1:Float; + var x2:Float; + var y2:Float; + var x3:Float; + var y3:Float; + var x4:Float; + var y4:Float; + + + + if (img.angle != 0) + { + + var angle:Float = img.angle * Math.PI / 180; + var cos:Float = Math.cos(angle); + var sin:Float = Math.sin(angle); + + x1 = cos * p1x - sin * p1y; + y1 = sin * p1x + cos * p1y; + + x2 = cos * p2x - sin * p2y; + y2 = sin * p2x + cos * p2y; + + x3 = cos * p3x - sin * p3y; + y3 = sin * p3x + cos * p3y; + + x4 = x1 + (x3 - x2); + y4 = y3 - (y2 - y1); + } else { + x1 = p1x; + y1 = p1y; + + x2 = p2x; + y2 = p2y; + + x3 = p3x; + y3 = p3y; + + x4 = p4x; + y4 = p4y; + } + + x1 += worldOriginX; + y1 += worldOriginY; + x2 += worldOriginX; + y2 += worldOriginY; + x3 += worldOriginX; + y3 += worldOriginY; + x4 += worldOriginX; + y4 += worldOriginY; + + + var u:Float = img.clip.x * invTexWidth; + var u2:Float = (img.clip.x + img.clip.width) * invTexWidth; + + var v:Float = (img.clip.y + img.clip.height) * invTexHeight; + var v2:Float = img.clip.y * invTexHeight; + + + if (img.flipX) { + var tmp:Float = u; + u = u2; + u2 = tmp; + } + + if (img.flipY) { + var tmp:Float = v; + v = v2; + v2 = tmp; + } + +vertices[vertexCount++] = x1; +vertices[vertexCount++] = y1; +vertices[vertexCount++] = 0; +uvs[uvCount++] = u;uvs[uvCount++] = v; +colors[colorCount++] = r;colors[colorCount++] = g;colors[colorCount++] = b;colors[colorCount++] = a; + +vertices[vertexCount++] = x2; +vertices[vertexCount++] = y2; +vertices[vertexCount++] = 0; +uvs[uvCount++] = u;uvs[uvCount++] = v2; +colors[colorCount++] = r;colors[colorCount++] = g;colors[colorCount++] = b;colors[colorCount++] = a; + +vertices[vertexCount++] = x3; +vertices[vertexCount++] = y3; +vertices[vertexCount++] = 0; +uvs[uvCount++] = u2;uvs[uvCount++] = v2; +colors[colorCount++] = r;colors[colorCount++] = g;colors[colorCount++] = b;colors[colorCount++] = a; + +vertices[vertexCount++] = x4; +vertices[vertexCount++] = y4; +vertices[vertexCount++] = 0; +uvs[uvCount++] = u2;uvs[uvCount++] = v; +colors[colorCount++] = r;colors[colorCount++] = g;colors[colorCount++] = b;colors[colorCount++] = a; + + + currentBatchSize++; + + } + +} \ No newline at end of file diff --git a/src/com/engine/render/BatchPrimitives.hx b/src/com/engine/render/BatchPrimitives.hx new file mode 100755 index 0000000..a91998b --- /dev/null +++ b/src/com/engine/render/BatchPrimitives.hx @@ -0,0 +1,298 @@ +package com.engine.render; + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; + +import com.engine.misc.Util; +import com.engine.game.Game; + + +/** + * ... + * @author djoker + */ +class BatchPrimitives extends Buffer +{ + public var colorBuffer:GLBuffer; + public var colorIndex:Int; + public var colors:Float32Array; + + + + public var vertexBuffer:GLBuffer; + public var vertices:Float32Array; + + private var capacity:Int; + + + + private var fillMode:Bool; + private var currentBlendMode:Int; + + + private var idxCols:Int; + private var idxPos:Int; + private var numVertices:Int; + + + + public var shader:PrimitiveShader; + + + + public var vertexDeclaration:Array; + public var vertexStrideSize:Int; + + + + + + public function new(capacity:Int) + { + super(); + this.vertexBuffer = GL.createBuffer(); + this.colorBuffer = GL.createBuffer(); + this.capacity = capacity; + + idxPos=0; + idxCols = 0; + numVertices = 0; + +// Util.create2D(matrix, x, y, zoom, -rotation *Math.PI / 180); + vertices = new Float32Array(capacity * 3 *4); + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.bufferData(GL.ARRAY_BUFFER,this.vertices , GL.DYNAMIC_DRAW); + colors = new Float32Array(capacity * 4 * 4); + GL.bindBuffer(GL.ARRAY_BUFFER, this.colorBuffer); + GL.bufferData(GL.ARRAY_BUFFER, this.colors , GL.DYNAMIC_DRAW); + fillMode = false; + currentBlendMode = BlendMode.NORMAL; + shader = new PrimitiveShader(); + } + + + + + +public function vertex(x:Float, y:Float, ?z:Float = 0.0) +{ + vertices[idxPos++] = x; + vertices[idxPos++] = y; + vertices[idxPos++] = z; + numVertices++; +} +public function color(r:Float, g:Float,b:Float, ?a:Float =0.0) + { + colors[idxCols++] = r; + colors[idxCols++] = g; + colors[idxCols++] = b; + colors[idxCols++] = a; + } + + + + public function renderMode(fill:Bool=false) + { + idxPos=0; + idxCols = 0; + numVertices = 0; + fillMode = fill; + } + + public function render() + { + + + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.bufferSubData(GL.ARRAY_BUFFER, 0, this.vertices); + GL.vertexAttribPointer(shader.vertexAttribute, 3, GL.FLOAT, false, 0, 0); + GL.bindBuffer(GL.ARRAY_BUFFER, this.colorBuffer); + GL.bufferSubData(GL.ARRAY_BUFFER, 0, this.colors); + GL.vertexAttribPointer(shader.colorAttribute, 4, GL.FLOAT, false, 0, 0); + + if (fillMode == true) + { + GL.drawArrays( GL.TRIANGLES, 0, Std.int(idxPos / 3)); + } else + { + GL.drawArrays(GL.LINES, 0, Std.int(idxPos / 3)); + } + + idxPos = 0; + idxCols = 0; + + } + public function begin() + { + shader.Enable(); + GL.uniformMatrix4fv(shader.projectionMatrixUniform, false,new Float32Array(Game.projMatrix.toArray())); + GL.uniformMatrix4fv(shader.modelViewMatrixUniform, false, new Float32Array(viewMatrix.toArray())); + BlendMode.setBlend(currentBlendMode); + } + public function end() + { + + shader.Disable(); + } + + + + //********** + public function circle (x:Float, y:Float, radius:Float , segments:Int,r:Float,g:Float,b:Float,?a:Float=1 ) + { + + var angle:Float = 2 * 3.1415926 / segments; + var cos:Float = Math.cos(angle); + var sin:Float = Math.sin(angle); + var cx:Float = radius; + var cy:Float = 0; + for ( i in 0...segments) + { + + vertex(x + cx, y + cy, 0);color(r, g, b, a); + var temp = cx; + cx = cos * cx - sin * cy; + cy = sin * temp + cos * cy; + + vertex(x + cx, y + cy, 0);color(r, g, b, a); + } + + vertex(x + cx, y + cy, 0);color(r, g, b, a); + + vertex(x, y, 0);color(r, g, b, a); + + vertex(x + cx, y + cy, 0);color(r, g, b, a); + + + var temp:Float = cx; + cx = radius; + cy = 0; + + vertex(x + cx, y + cy, 0);color(r, g, b, a); + } +public function fillcircle (x:Float, y:Float, radius:Float , segments:Int,r:Float,g:Float,b:Float,?a:Float=1 ) + { + + var angle:Float = 2 * 3.1415926 / segments; + var cos:Float = Math.cos(angle); + var sin:Float = Math.sin(angle); + var cx:Float = radius; + var cy:Float = 0; + segments--; + for ( i in 0...segments) + { + vertex(x, y, 0);color(r, g, b, a); + vertex(x + cx, y + cy, 0);color(r, g, b, a); + var temp:Float = cx; + cx = cos * cx - sin * cy; + cy = sin * temp + cos * cy; + + vertex(x + cx, y + cy, 0);color(r, g, b, a); + + } + + + + vertex(x, y, 0);color(r, g, b, a); + vertex(x + cx, y + cy, 0);color(r, g, b, a); + + + var temp:Float = cx; + cx = radius; + cy = 0; + + vertex(x + cx, y + cy, 0);color(r, g, b, a); + } + + public function ellipse ( x:Float, y:Float, width:Float, height:Float, segments:Int,r:Float,g:Float,b:Float,?a:Float=1 ) + { + + var angle:Float = 2 * 3.1415926/ segments; + + var cx:Float = x + width / 2; + var cy:Float = y + height / 2; + + + for (i in 0... segments) + { + + vertex(cx + (width * 0.5 * Math.cos(i * angle)), cy + (height * 0.5 * Math.sin(i * angle)), 0); + color(r, g, b, a); + + + vertex(cx + (width * 0.5 * Math.cos((i + 1) * angle)),cy + (height * 0.5 * Math.sin((i + 1) * angle)), 0); + color(r, g, b, a); + } + + } + public function fillellipse ( x:Float, y:Float, width:Float, height:Float, segments:Int,r:Float,g:Float,b:Float,?a:Float=1 ) + { + + var angle:Float = 2 * 3.1415926/ segments; + + var cx:Float = x + width / 2; + var cy:Float = y + height / 2; + + + for (i in 0... segments) + { + + vertex(cx + (width * 0.5 * Math.cos(i * angle)), cy + (height * 0.5 * Math.sin(i * angle)), 0); + color(r, g, b, a); + + vertex(cx ,cy, 0); + color(r, g, b, a); + + vertex(cx + (width * 0.5 * Math.cos((i + 1) * angle)),cy + (height * 0.5 * Math.sin((i + 1) * angle)), 0); + color(r, g, b, a); + } + + } +public function line(x1:Float,y1:Float,x2:Float,y2:Float,r:Float,g:Float,b:Float,?a:Float=1) +{ + +vertex(x1, y1); +color(r, g, b, a); +vertex(x2, y2); +color(r, g, b, a); +} + +public function rect(x:Float,y:Float,width:Float,height:Float,r:Float,g:Float,b:Float,?a:Float=1) +{ + vertex(x, y, 0);color(r, g, b, a); + vertex(x + width, y, 0);color(r, g, b, a); + vertex(x + width, y, 0);color(r, g, b, a); + vertex(x + width, y + height, 0);color(r, g, b, a); + vertex(x + width, y + height, 0);color(r, g, b, a); + vertex(x, y + height, 0);color(r, g, b, a); + vertex(x, y + height, 0);color(r, g, b, a); + vertex(x, y, 0);color(r, g, b, a); +} + +public function fillrect(x:Float,y:Float,width:Float,height:Float,r:Float,g:Float,b:Float,?a:Float=1) +{ + + vertex(x, y, 0);color(r, g, b, a); + vertex(x + width, y, 0);color(r, g, b, a); + vertex(x + width, y + height, 0);color(r, g, b, a); + vertex(x + width, y + height, 0);color(r, g, b, a); + vertex(x, y + height, 0);color(r, g, b, a); + vertex(x, y, 0);color(r, g, b, a); +} +override public function dispose():Void +{ + this.vertices = new Float32Array ([]); + this.colors = new Float32Array ([]); + GL.deleteBuffer(vertexBuffer); + GL.deleteBuffer(colorBuffer); + + super.dispose(); +} + + +} \ No newline at end of file diff --git a/src/com/engine/render/BlendMode.hx b/src/com/engine/render/BlendMode.hx new file mode 100755 index 0000000..076bd20 --- /dev/null +++ b/src/com/engine/render/BlendMode.hx @@ -0,0 +1,40 @@ +package com.engine.render; + +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; + +/** + * ... + * @author djoker + */ +class BlendMode +{ + +public static var NORMAL:Int = 0; +public static var ADD:Int = 1; +public static var MULTIPLY:Int = 2; +public static var SCREEN:Int = 3; + +static public function setBlend(mode:Int ) + { + switch( mode ) { + case 0: + GL.blendFunc(GL.ONE,GL.ONE_MINUS_SRC_ALPHA ); + case 1: + GL.blendFunc(GL.SRC_ALPHA,GL.DST_ALPHA ); + case 2: + GL.blendFunc(GL.DST_COLOR,GL.ONE_MINUS_SRC_ALPHA ); + case 3: + GL.blendFunc(GL.SRC_ALPHA,GL.ONE ); + default: + GL.blendFunc(GL.ONE,GL.ONE_MINUS_SRC_ALPHA ); + } +} + + + + + + +} \ No newline at end of file diff --git a/src/com/engine/render/Buffer.hx b/src/com/engine/render/Buffer.hx new file mode 100755 index 0000000..451c891 --- /dev/null +++ b/src/com/engine/render/Buffer.hx @@ -0,0 +1,44 @@ +package com.engine.render; + +import com.engine.misc.Util; +import com.engine.misc.MatrixHelp; +import com.engine.math.Matrix; +import com.engine.math.Vector2; +/** + * ... + * @author djoker + */ +class Buffer +{ + + public var viewMatrix:Matrix; + public var position:Vector2; + public var scale:Float; + public var rotation:Float; + + public function new() + { + position =new Vector2(0, 0); + rotation = 0; + scale=1; + viewMatrix = Matrix.create2D(position.x, position.y, scale, rotation); + } + public function getMatrix():Matrix + { + return this.viewMatrix; + } + public function combineMatrix(m:Matrix) + { + viewMatrix = Matrix.MatrixMultiply4x4(this.viewMatrix, m); + } + public function update() + { + viewMatrix = Matrix.create2D( position.x, position.y, scale, rotation); + } + + public function dispose() + { + + } + +} \ No newline at end of file diff --git a/src/com/engine/render/Camera.hx b/src/com/engine/render/Camera.hx new file mode 100755 index 0000000..9f5e26b --- /dev/null +++ b/src/com/engine/render/Camera.hx @@ -0,0 +1,44 @@ +package com.engine.render; + +import flash.display.Sprite; +import flash.geom.Rectangle; + + + + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; + +import com.engine.misc.Util; +import com.engine.math.Vector3; +import com.engine.math.Matrix; +import com.engine.game.Game; + + +/** + * ... + * @author djoker + */ +class Camera buffer +{ + + public function new() + { + super(); + } + + + public function unproject(source:Vector3):Vector3 + { + var world=Matrix.Identity(); + return Vector3.Unproject(source, Game.viewWidth, Game.viewHeight, world, this.viewMatrix, Game.projMatrix); + } + + + +} \ No newline at end of file diff --git a/src/com/engine/render/Clip.hx b/src/com/engine/render/Clip.hx new file mode 100755 index 0000000..ab3ca09 --- /dev/null +++ b/src/com/engine/render/Clip.hx @@ -0,0 +1,32 @@ +package com.engine.render; + +/** + * ... + * @author djoker + */ +class Clip +{ + + public var x:Int; + public var y:Int; + public var width:Int; + public var height:Int; + + + + public function new(?x:Int=0,?y:Int=0,?width:Int=0,?height:Int=0) + { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + public function set(x:Int,y:Int,width:Int,height:Int) + { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + +} \ No newline at end of file diff --git a/src/com/engine/render/Image.hx b/src/com/engine/render/Image.hx new file mode 100755 index 0000000..65c4b6a --- /dev/null +++ b/src/com/engine/render/Image.hx @@ -0,0 +1,55 @@ +package com.engine.render; + +import flash.geom.Rectangle; +/** + * ... + * @author djoker + */ +class Image +{ + +public var width:Float; +public var height:Float; + +public var x:Float; +public var y:Float; +public var red:Float; +public var green:Float; +public var blue:Float; +public var alpha:Float; + +public var angle:Float; +public var scaleX:Float; +public var scaleY:Float; +public var originX:Float; +public var originY:Float; +public var texture:Texture; +public var blendMode:Int; +public var clip:Clip; +public var flipX:Bool; +public var flipY:Bool; + + public function new(Tex:Texture) + { + clip = new Clip(0, 0, Tex.width, Tex.height); + angle = 0; + scaleX = 1; + scaleY = 1; + originX = 0; + originY = 0; + red = 1; + green = 1; + blue = 1; + alpha = 1; + x = 0; + y = 0; + width = Tex.width; + height = Tex.height; + flipX = false; + flipY = false; + blendMode = BlendMode.SCREEN; + + texture = Tex; + } + +} \ No newline at end of file diff --git a/src/com/engine/render/PrimitiveShader.hx b/src/com/engine/render/PrimitiveShader.hx new file mode 100755 index 0000000..6d4b14a --- /dev/null +++ b/src/com/engine/render/PrimitiveShader.hx @@ -0,0 +1,111 @@ +package com.engine.render; + +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; + +import flash.geom.Matrix3D; + + +/** + * ... + * @author djoker + */ +class PrimitiveShader +{ +private var shaderProgram:GLProgram; + + public var vertexAttribute :Int; + public var colorAttribute :Int; + public var projectionMatrixUniform:Dynamic; + public var modelViewMatrixUniform:Dynamic; + + + + public function new() + { + + +var vertexShaderSource = +" +attribute vec3 aVertexPosition; +attribute vec4 aColor; + +varying vec4 vColor; + +uniform mat4 uModelViewMatrix; +uniform mat4 uProjectionMatrix; +void main(void) +{ +vColor = aColor; +gl_Position = uProjectionMatrix * uModelViewMatrix * vec4 (aVertexPosition, 1.0); +}"; + +var vertexShader = GL.createShader (GL.VERTEX_SHADER); +GL.shaderSource (vertexShader, vertexShaderSource); +GL.compileShader (vertexShader); + +if (GL.getShaderParameter (vertexShader, GL.COMPILE_STATUS) == 0) +{ + +throw (GL.getShaderInfoLog(vertexShader)); + +} + +var fragmentShaderSource = + +#if !desktop +"precision mediump float;" + +#end +" + +varying vec4 vColor; +void main(void) +{ + gl_FragColor = vColor; +}"; + +var fragmentShader = GL.createShader (GL.FRAGMENT_SHADER); +GL.shaderSource (fragmentShader, fragmentShaderSource); +GL.compileShader (fragmentShader); + +if (GL.getShaderParameter (fragmentShader, GL.COMPILE_STATUS) == 0) { + + throw(GL.getShaderInfoLog(fragmentShader)); + +} + +shaderProgram = GL.createProgram (); +GL.attachShader (shaderProgram, vertexShader); +GL.attachShader (shaderProgram, fragmentShader); +GL.linkProgram (shaderProgram); + +if (GL.getProgramParameter (shaderProgram, GL.LINK_STATUS) == 0) { + + +throw "Unable to initialize the shader program."; +} + +vertexAttribute = GL.getAttribLocation (shaderProgram, "aVertexPosition"); +colorAttribute = GL.getAttribLocation (shaderProgram, "aColor"); +projectionMatrixUniform = GL.getUniformLocation (shaderProgram, "uProjectionMatrix"); +modelViewMatrixUniform = GL.getUniformLocation (shaderProgram, "uModelViewMatrix"); + + + } + + public function Enable() + { + GL.useProgram (shaderProgram); + GL.enableVertexAttribArray (vertexAttribute); + GL.enableVertexAttribArray (colorAttribute); + + + } + public function Disable() + { + GL.disableVertexAttribArray (vertexAttribute); + GL.disableVertexAttribArray (colorAttribute); + } +} \ No newline at end of file diff --git a/src/com/engine/render/SpriteAtlas.hx b/src/com/engine/render/SpriteAtlas.hx new file mode 100755 index 0000000..1061aca --- /dev/null +++ b/src/com/engine/render/SpriteAtlas.hx @@ -0,0 +1,343 @@ +package com.engine.render; + + +import flash.geom.Matrix3D; + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; + + +import com.engine.render.BlendMode; + +/** + * ... + * @author djoker + */ +class SpriteAtlas extends Buffer +{ + + private var capacity:Int; + private var numVerts:Int; + private var numIndices:Int; + private var vertices:Float32Array; + private var indices:Int16Array; + private var lastIndexCount:Int; + private var drawing:Bool; + private var currentBatchSize:Int; + private var currentBlendMode:Int; + private var currentBaseTexture:Texture; + + + +private var vertexBuffer:GLBuffer; +private var indexBuffer:GLBuffer; + +private var invTexWidth:Float = 0; +private var invTexHeight:Float = 0; + +public var camera:OrthoCamera; + + public var vertexDeclaration:Array; + public var vertexStrideSize:Int; + + + +public var shader:SpriteShader; + + public function new(texture:Texture,capacity:Int ) + { + + super(); + this.capacity = capacity; + + vertexDeclaration = [3, 2,4]; + vertexStrideSize = 9 * 4; // 9 floats (x, y, z,u,v, r, g, b, a) + + numVerts = capacity * vertexStrideSize * 4; + numIndices = capacity * 6; + + + + vertices = new Float32Array(numVerts); + + + + + + this.indices = new Int16Array(numIndices); + var length = Std.int(this.indices.length/6); + + for (i in 0...length) + { + var index2 = i * 6; + var index3 = i * 4; + this.indices[index2 + 0] = index3 + 0; + this.indices[index2 + 1] = index3 + 1; + this.indices[index2 + 2] = index3 + 2; + this.indices[index2 + 3] = index3 + 0; + this.indices[index2 + 4] = index3 + 2; + this.indices[index2 + 5] = index3 + 3; + }; + + + drawing = false; + currentBatchSize = 0; + currentBlendMode = BlendMode.SCREEN; + this.currentBaseTexture = texture; + invTexWidth = 1.0 / texture.texWidth; + invTexHeight = 1.0 / texture.texHeight; + + + // create a couple of buffers + vertexBuffer = GL.createBuffer(); + indexBuffer = GL.createBuffer(); + + + //upload the index data + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer); + GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, indices, GL.STATIC_DRAW); + + GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); + GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.DYNAMIC_DRAW); + + + + shader = new SpriteShader(); + + } + + public function dispose():Void + { + GL.deleteBuffer(indexBuffer); + GL.deleteBuffer(vertexBuffer); + } + + + + public function drawImage(img:Image) + { + + + + +var r, g, b, a:Float; +r = img.red; +g = img.green; +b = img.blue; +a = img.alpha; + + + + +var index:Int = currentBatchSize * vertexStrideSize; + + + var worldOriginX:Float = img.x + img.originX; + var worldOriginY:Float = img.y + img.originY; + var fx:Float = -img.originX; + var fy:Float = -img.originY; + var fx2:Float = img.width - img.originX; + var fy2:Float = img.height - img.originY; + + if (img.scaleX != 1 || img.scaleY != 1) + { + fx *= img.scaleX; + fy *= img.scaleY; + fx2 *= img.scaleX; + fy2 *= img.scaleY; + } + + var p1x:Float = fx; + var p1y:Float = fy; + var p2x:Float = fx; + var p2y:Float = fy2; + var p3x:Float = fx2; + var p3y:Float = fy2; + var p4x:Float = fx2; + var p4y:Float = fy; + + var x1:Float; + var y1:Float; + var x2:Float; + var y2:Float; + var x3:Float; + var y3:Float; + var x4:Float; + var y4:Float; + + + + if (img.angle != 0) + { + + var angle:Float = img.angle * Math.PI / 180; + var cos:Float = Math.cos(angle); + var sin:Float = Math.sin(angle); + + x1 = cos * p1x - sin * p1y; + y1 = sin * p1x + cos * p1y; + + x2 = cos * p2x - sin * p2y; + y2 = sin * p2x + cos * p2y; + + x3 = cos * p3x - sin * p3y; + y3 = sin * p3x + cos * p3y; + + x4 = x1 + (x3 - x2); + y4 = y3 - (y2 - y1); + } else { + x1 = p1x; + y1 = p1y; + + x2 = p2x; + y2 = p2y; + + x3 = p3x; + y3 = p3y; + + x4 = p4x; + y4 = p4y; + } + + x1 += worldOriginX; + y1 += worldOriginY; + x2 += worldOriginX; + y2 += worldOriginY; + x3 += worldOriginX; + y3 += worldOriginY; + x4 += worldOriginX; + y4 += worldOriginY; + + + var u:Float = img.clip.x * invTexWidth; + var u2:Float = (img.clip.x + img.clip.width) * invTexWidth; + + var v:Float = (img.clip.y + img.clip.height) * invTexHeight; + var v2:Float = img.clip.y * invTexHeight; + + + if (img.flipX) { + var tmp:Float = u; + u = u2; + u2 = tmp; + } + + if (img.flipY) { + var tmp:Float = v; + v = v2; + v2 = tmp; + } + +vertices[index++] = x1; +vertices[index++] = y1; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = r;vertices[index++] = g;vertices[index++] = b;vertices[index++] = a; + +vertices[index++] = x2; +vertices[index++] = y2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = r;vertices[index++] = g;vertices[index++] = b;vertices[index++] = a; + +vertices[index++] = x3; +vertices[index++] = y3; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = r;vertices[index++] = g;vertices[index++] = b;vertices[index++] = a; + +vertices[index++] = x4; +vertices[index++] = y4; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = r;vertices[index++] = g;vertices[index++] = b;vertices[index++] = a; + + + currentBatchSize++; + + } + +inline public function RenderNormal(x:Float, y:Float) +{ + + var u:Float = 0; + var v:Float = 1; + var u2:Float = 1; + var v2:Float = 0; + var fx2:Float = x + currentBaseTexture.width; + var fy2:Float = y + currentBaseTexture.height; + + + + + +var index:Int = currentBatchSize * vertexStrideSize; + +vertices[index++] = x; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = x; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + + + currentBatchSize++; + + } + + public function Begin() + { + currentBatchSize = 0; + shader.Enable(); + GL.activeTexture(GL.TEXTURE0); + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.vertexAttribPointer(shader.vertexAttribute, 3, GL.FLOAT, false, vertexStrideSize, 0); + GL.vertexAttribPointer(shader.texCoordAttribute , 2, GL.FLOAT, false, vertexStrideSize, 3 * 4); + GL.vertexAttribPointer(shader.colorAttribute, 4, GL.FLOAT, false, vertexStrideSize, (3+2) * 4); + + } + public function End() + { + if (currentBatchSize==0) return; + currentBaseTexture.Bind(); + BlendMode.setBlend(currentBlendMode); + + GL.uniformMatrix4fv(shader.projectionMatrixUniform, false,new Float32Array(camera.projMatrix.toArray())); + GL.uniformMatrix4fv(shader.modelViewMatrixUniform, false, new Float32Array(viewMatrix.toArray())); + GL.uniform1i (shader.imageUniform, 0); + GL.bufferSubData(GL.ARRAY_BUFFER, 0, vertices); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + GL.drawElements(GL.TRIANGLES, currentBatchSize * 6, GL.UNSIGNED_SHORT, 0); + currentBatchSize = 0; + shader.Disable(); + } +override public function dispose():Void +{ + super.dispose(); + +} + + +} \ No newline at end of file diff --git a/src/com/engine/render/SpriteBatch.hx b/src/com/engine/render/SpriteBatch.hx new file mode 100755 index 0000000..fc3696c --- /dev/null +++ b/src/com/engine/render/SpriteBatch.hx @@ -0,0 +1,691 @@ +package com.engine.render; + +import flash.geom.Matrix3D; + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; + + +import com.engine.render.BlendMode; +import com.engine.game.Game; + +/** + * ... + * @author djoker + */ +class SpriteBatch extends Buffer +{ + + private var capacity:Int; + private var numVerts:Int; + private var numIndices:Int; + private var vertices:Float32Array; + private var lastIndexCount:Int; + private var drawing:Bool; + private var currentBatchSize:Int; + private var currentBlendMode:Int; + private var currentBaseTexture:Texture; + + + public var numTex:Int=0; + public var numBlend:Int=0; + +private var vertexBuffer:GLBuffer; +private var indexBuffer:GLBuffer; + +private var invTexWidth:Float = 0; +private var invTexHeight:Float = 0; + + + public var vertexDeclaration:Array; + public var vertexStrideSize:Int; + + + +public var shader:SpriteShader; + + public function new(capacity:Int ) + { + super(); + this.capacity = capacity; + vertexStrideSize = 9 * 4; // 9 floats (x, y, z,u,v, r, g, b, a) + numVerts = capacity * vertexStrideSize * 4; + numIndices = capacity * 6; + vertices = new Float32Array(numVerts); + + + + + + var indices:Array = []; + var index = 0; + for (count in 0...numIndices) { + indices.push(index); + indices.push(index + 1); + indices.push(index + 2); + indices.push(index); + indices.push(index + 2); + indices.push(index + 3); + index += 4; + } + + + drawing = false; + currentBatchSize = 0; + currentBlendMode = BlendMode.NORMAL; + + currentBaseTexture = null; + + + + vertexBuffer = GL.createBuffer(); + indexBuffer = GL.createBuffer(); + + + //upload the index data + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer); + GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, new Int16Array(indices), GL.STATIC_DRAW); + + + GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); + GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.DYNAMIC_DRAW); + + + + shader = new SpriteShader(); + start(); + } + + + public function Render(texture:Texture, x:Float, y:Float, srcX:Int, srcY:Int, srcWidth:Int, srcHeight:Int,blendMode:Int) + { + if(texture!= this.currentBaseTexture || this.currentBatchSize >= this.capacity) + { + switchTexture(texture); + } + + + // check blend mode + if(blendMode != this.currentBlendMode) + { + this.setBlendMode(blendMode); + } + + var u:Float = srcX * invTexWidth; + var v:Float = (srcY + srcHeight) * invTexHeight; + var u2:Float = (srcX + srcWidth) * invTexWidth; + var v2:Float = srcY * invTexHeight; + var fx2:Float = x + srcWidth; + var fy2:Float = y + srcHeight; + + +var r, g, b, a:Float; +r = 1; +g = 1; +b = 1; +a = 1; + + + + +var index:Int = currentBatchSize * vertexStrideSize; + +vertices[index++] = x; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = x; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + + + + +this.currentBatchSize++; + + + + } +public function RenderTile(texture:Texture,x:Float,y:Float,width:Float,height:Float,clip:Clip,flipx:Bool,flipy:Bool,blendMode:Int) +{ + if(texture!= this.currentBaseTexture || this.currentBatchSize >= this.capacity) + { + switchTexture(texture); + } + + + // check blend mode + if(blendMode != this.currentBlendMode) + { + this.setBlendMode(blendMode); + } + + + + + + + var fx2:Float = x+width; + var fy2:Float = y+height; + + + + + + + var u:Float = clip.x * invTexWidth; + var u2:Float = (clip.x + clip.width) * invTexWidth; + + var v:Float = (clip.y + clip.height) * invTexHeight; + var v2:Float = clip.y * invTexHeight; + + if (flipx) + { + var tmp:Float = u; + u = u2; + u2 = tmp; + } + + if (flipy) + { + var tmp:Float = v; + v = v2; + v2 = tmp; + } + + + var index:Int = currentBatchSize * vertexStrideSize; + +vertices[index++] = x; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = x; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + + + + +this.currentBatchSize++; + + + +} + public function Blt(texture:Texture, src:Clip,dst:Clip,flipX:Bool,flipY:Bool,blendMode:Int) + { + if(texture!= this.currentBaseTexture || this.currentBatchSize >= this.capacity) + { + switchTexture(texture); + } + + + if(blendMode != this.currentBlendMode) + { + this.setBlendMode(blendMode); + } + + + + + var fx2:Float = src.x+src.width; + var fy2:Float = src.y+src.height; + + + + + + + var u:Float = dst.x * invTexWidth; + var u2:Float = (dst.x + dst.width) * invTexWidth; + + var v:Float = (dst.y + dst.height) * invTexHeight; + var v2:Float = dst.y * invTexHeight; + + if (flipX) + { + var tmp:Float = u; + u = u2; + u2 = tmp; + } + + if (flipY) + { + var tmp:Float = v; + v = v2; + v2 = tmp; + } + + + +var index:Int = currentBatchSize * vertexStrideSize; + +vertices[index++] = src.x; +vertices[index++] = src.y; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = src.x; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = src.y; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + + + + + +this.currentBatchSize++; + + + + } + + public function RenderClip(texture:Texture, x:Float, y:Float,c:Clip,flipX:Bool,flipY:Bool,blendMode:Int) + { + if(texture!= this.currentBaseTexture || this.currentBatchSize >= this.capacity) + { + switchTexture(texture); + } + + + // check blend mode + if(blendMode != this.currentBlendMode) + { + this.setBlendMode(blendMode); + } + + var u:Float = c.x * invTexWidth; + var u2:Float = (c.x + c.width) * invTexWidth; + + var v:Float = (c.y + c.height) * invTexHeight; + var v2:Float = c.y * invTexHeight; + + + + + var fx2:Float = x + c.width; + var fy2:Float = y + c.height; + + + if (flipX) { + var tmp:Float = u; + u = u2; + u2 = tmp; + } + + if (flipY) { + var tmp:Float = v; + v = v2; + v2 = tmp; + } + + + + +var index:Int = currentBatchSize * vertexStrideSize; + + +vertices[index++] = x; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = x; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + + + +this.currentBatchSize++; + + + + } + + public function drawImage(img:Image) + { + if(img.texture!= this.currentBaseTexture || this.currentBatchSize >= this.capacity) + { + switchTexture(img.texture); + } + + + // check blend mode + if(img.blendMode != this.currentBlendMode) + { + this.setBlendMode(img.blendMode); + } + + + + +var r, g, b, a:Float; +r = img.red; +g = img.green; +b = img.blue; +a = img.alpha; + + + + +var index:Int = currentBatchSize * vertexStrideSize; + + + var worldOriginX:Float = img.x + img.originX; + var worldOriginY:Float = img.y + img.originY; + var fx:Float = -img.originX; + var fy:Float = -img.originY; + var fx2:Float = img.width - img.originX; + var fy2:Float = img.height - img.originY; + + if (img.scaleX != 1 || img.scaleY != 1) + { + fx *= img.scaleX; + fy *= img.scaleY; + fx2 *= img.scaleX; + fy2 *= img.scaleY; + } + + var p1x:Float = fx; + var p1y:Float = fy; + var p2x:Float = fx; + var p2y:Float = fy2; + var p3x:Float = fx2; + var p3y:Float = fy2; + var p4x:Float = fx2; + var p4y:Float = fy; + + var x1:Float; + var y1:Float; + var x2:Float; + var y2:Float; + var x3:Float; + var y3:Float; + var x4:Float; + var y4:Float; + + + + if (img.angle != 0) + { + + var angle:Float = img.angle * Math.PI / 180; + var cos:Float = Math.cos(angle); + var sin:Float = Math.sin(angle); + + x1 = cos * p1x - sin * p1y; + y1 = sin * p1x + cos * p1y; + + x2 = cos * p2x - sin * p2y; + y2 = sin * p2x + cos * p2y; + + x3 = cos * p3x - sin * p3y; + y3 = sin * p3x + cos * p3y; + + x4 = x1 + (x3 - x2); + y4 = y3 - (y2 - y1); + } else { + x1 = p1x; + y1 = p1y; + + x2 = p2x; + y2 = p2y; + + x3 = p3x; + y3 = p3y; + + x4 = p4x; + y4 = p4y; + } + + x1 += worldOriginX; + y1 += worldOriginY; + x2 += worldOriginX; + y2 += worldOriginY; + x3 += worldOriginX; + y3 += worldOriginY; + x4 += worldOriginX; + y4 += worldOriginY; + + + var u:Float = img.clip.x * invTexWidth; + var u2:Float = (img.clip.x + img.clip.width) * invTexWidth; + + var v:Float = (img.clip.y + img.clip.height) * invTexHeight; + var v2:Float = img.clip.y * invTexHeight; + + + if (img.flipX) { + var tmp:Float = u; + u = u2; + u2 = tmp; + } + + if (img.flipY) { + var tmp:Float = v; + v = v2; + v2 = tmp; + } + +vertices[index++] = x1; +vertices[index++] = y1; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = r;vertices[index++] = g;vertices[index++] = b;vertices[index++] = a; + +vertices[index++] = x2; +vertices[index++] = y2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = r;vertices[index++] = g;vertices[index++] = b;vertices[index++] = a; + +vertices[index++] = x3; +vertices[index++] = y3; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = r;vertices[index++] = g;vertices[index++] = b;vertices[index++] = a; + +vertices[index++] = x4; +vertices[index++] = y4; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = r;vertices[index++] = g;vertices[index++] = b;vertices[index++] = a; + + + currentBatchSize++; + + } + + inline public function RenderNormal(texture:Texture, x:Float, y:Float,blendMode:Int) + { + if(texture!= this.currentBaseTexture || this.currentBatchSize >= this.capacity) + { + switchTexture(texture); + } + + + // check blend mode + if(blendMode != this.currentBlendMode) + { + this.setBlendMode(blendMode); + } + + var u:Float = 0; + var v:Float = 1; + var u2:Float = 1; + var v2:Float = 0; + var fx2:Float = x + texture.width; + var fy2:Float = y + texture.height; + + + + + +var index:Int = currentBatchSize * vertexStrideSize; + +vertices[index++] = x; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = x; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + + + currentBatchSize++; + + } + + public function Begin() + { + numTex = 0; + numBlend = 0; + currentBatchSize = 0; + start(); + } + public function End() + { + flush(); + shader.Disable(); + } + + private function start() + { + shader.Enable(); + GL.activeTexture(GL.TEXTURE0); + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.vertexAttribPointer(shader.vertexAttribute, 3, GL.FLOAT, false, vertexStrideSize, 0); + GL.vertexAttribPointer(shader.texCoordAttribute , 2, GL.FLOAT, false, vertexStrideSize, 3 * 4); + GL.vertexAttribPointer(shader.colorAttribute, 4, GL.FLOAT, false, vertexStrideSize, (3+2) * 4); + if(currentBlendMode != BlendMode.NORMAL) + { + setBlendMode(currentBlendMode); + } +} + +private function flush() +{ + if (currentBatchSize == 0) return; + this.update(); + currentBaseTexture.Bind(); + numTex++; + GL.uniformMatrix4fv(shader.projectionMatrixUniform, false,new Float32Array(Game.projMatrix.toArray())); + GL.uniformMatrix4fv(shader.modelViewMatrixUniform, false, new Float32Array(viewMatrix.toArray())); + + GL.uniform1i (shader.imageUniform, 0); + GL.bufferSubData(GL.ARRAY_BUFFER, 0, vertices); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + GL.drawElements(GL.TRIANGLES, currentBatchSize * 6, GL.UNSIGNED_SHORT, 0); +// trace(currentBatchSize); + currentBatchSize = 0; +} +private function switchTexture (texture:Texture) +{ +this.flush(); +this.currentBaseTexture = texture; +invTexWidth = 1.0 / texture.width; +invTexHeight = 1.0 / texture.height; + +} + +public function setBlendMode(blendMode:Int) +{ + flush(); + currentBlendMode = blendMode; + BlendMode.setBlend(currentBlendMode); + numBlend++; + +} +override public function dispose():Void +{ + this.vertices = null; + GL.deleteBuffer(indexBuffer); + GL.deleteBuffer(vertexBuffer); + super.dispose(); + +} + + +} \ No newline at end of file diff --git a/src/com/engine/render/SpriteCloud.hx b/src/com/engine/render/SpriteCloud.hx new file mode 100755 index 0000000..f9bc281 --- /dev/null +++ b/src/com/engine/render/SpriteCloud.hx @@ -0,0 +1,398 @@ +package com.engine.render; + + + + + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; + +import com.engine.misc.Util; +import com.engine.math.Matrix; +import com.engine.math.Vector2; + +import com.engine.game.Game; + +/** + * ... + * @author djoker + */ +class SpriteCloud extends Buffer +{ + + private var capacity:Int; + private var numVerts:Int; + private var numIndices:Int; + private var tmpVertices:Float32Array; + private var vertices:Float32Array; + private var indices:Int16Array; + private var lastIndexCount:Int; + private var drawing:Bool; + public var currentBatchSize:Int; + private var currentBlendMode:Int; + private var currentBaseTexture:Texture; + private var vertexBuffer:GLBuffer; + private var indexBuffer:GLBuffer; + private var invTexWidth:Float = 0; + private var invTexHeight:Float = 0; + public var vertexDeclaration:Array; + public var vertexStrideSize:Int; + public var shader:SpriteShader; + private var index:Int; + private var rebuid:Bool; + + + + + public function new(texture:Texture,capacity:Int ) + { + super(); + this.capacity = capacity; + + + + + vertexDeclaration = [3, 2,4]; + vertexStrideSize = 9 * 4; + + + index = 0; + + tmpVertices = new Float32Array(capacity*vertexStrideSize); + + + drawing = false; + currentBatchSize = 0; + currentBlendMode = BlendMode.NORMAL; + this.currentBaseTexture = texture; + invTexWidth = 1.0 / texture.width; + invTexHeight = 1.0 / texture.height; + + + + + vertexBuffer = GL.createBuffer(); + indexBuffer = GL.createBuffer(); + + + shader = new SpriteShader(); + + rebuid = false; + } + + public function build() + { + + numVerts = tmpVertices.length * vertexStrideSize * 4; + numIndices = tmpVertices.length * 6; + + + vertices = new Float32Array(numVerts); + + for ( i in 0...tmpVertices.length ) + { + vertices[i]=tmpVertices[i]; + } + tmpVertices = null; + + + + this.indices = new Int16Array(numIndices); + var length = Std.int(this.indices.length/6); + + for (i in 0...length) + { + var index2 = i * 6; + var index3 = i * 4; + this.indices[index2 + 0] = index3 + 0; + this.indices[index2 + 1] = index3 + 1; + this.indices[index2 + 2] = index3 + 2; + this.indices[index2 + 3] = index3 + 0; + this.indices[index2 + 4] = index3 + 2; + this.indices[index2 + 5] = index3 + 3; + }; + + + + + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer); + GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, indices, GL.STATIC_DRAW); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, null); + + GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); + GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.STATIC_DRAW); + GL.bindBuffer(GL.ARRAY_BUFFER, null); + rebuid = true; + + } + +override public function dispose():Void +{ + this.indices = null; + this.vertices = null; + GL.deleteBuffer(indexBuffer); + GL.deleteBuffer(vertexBuffer); + super.dispose(); + +} + + + +public function addImage(img:Image) +{ +var r, g, b, a:Float; +r = img.red; +g = img.green; +b = img.blue; +a = img.alpha; + + + + + var worldOriginX:Float = img.x + img.originX; + var worldOriginY:Float = img.y + img.originY; + var fx:Float = -img.originX; + var fy:Float = -img.originY; + var fx2:Float = img.width - img.originX; + var fy2:Float = img.height - img.originY; + + if (img.scaleX != 1 || img.scaleY != 1) + { + fx *= img.scaleX; + fy *= img.scaleY; + fx2 *= img.scaleX; + fy2 *= img.scaleY; + } + + var p1x:Float = fx; + var p1y:Float = fy; + var p2x:Float = fx; + var p2y:Float = fy2; + var p3x:Float = fx2; + var p3y:Float = fy2; + var p4x:Float = fx2; + var p4y:Float = fy; + + var x1:Float; + var y1:Float; + var x2:Float; + var y2:Float; + var x3:Float; + var y3:Float; + var x4:Float; + var y4:Float; + + + + if (img.angle != 0) + { + + var angle:Float = img.angle * Math.PI / 180; + var cos:Float = Math.cos(angle); + var sin:Float = Math.sin(angle); + + x1 = cos * p1x - sin * p1y; + y1 = sin * p1x + cos * p1y; + + x2 = cos * p2x - sin * p2y; + y2 = sin * p2x + cos * p2y; + + x3 = cos * p3x - sin * p3y; + y3 = sin * p3x + cos * p3y; + + x4 = x1 + (x3 - x2); + y4 = y3 - (y2 - y1); + } else { + x1 = p1x; + y1 = p1y; + + x2 = p2x; + y2 = p2y; + + x3 = p3x; + y3 = p3y; + + x4 = p4x; + y4 = p4y; + } + + x1 += worldOriginX; + y1 += worldOriginY; + x2 += worldOriginX; + y2 += worldOriginY; + x3 += worldOriginX; + y3 += worldOriginY; + x4 += worldOriginX; + y4 += worldOriginY; + + + var u:Float = img.clip.x * invTexWidth; + var u2:Float = (img.clip.x + img.clip.width) * invTexWidth; + + var v:Float = (img.clip.y + img.clip.height) * invTexHeight; + var v2:Float = img.clip.y * invTexHeight; + + + if (img.flipX) { + var tmp:Float = u; + u = u2; + u2 = tmp; + } + + if (img.flipY) { + var tmp:Float = v; + v = v2; + v2 = tmp; + } + +tmpVertices[index++] = x1; +tmpVertices[index++] = y1; +tmpVertices[index++] = 0; +tmpVertices[index++] = u;tmpVertices[index++] = v; +tmpVertices[index++] = r;tmpVertices[index++] = g;tmpVertices[index++] = b;tmpVertices[index++] = a; + +tmpVertices[index++] = x2; +tmpVertices[index++] = y2; +tmpVertices[index++] = 0; +tmpVertices[index++] = u;tmpVertices[index++] = v2; +tmpVertices[index++] = r;tmpVertices[index++] = g;tmpVertices[index++] = b;tmpVertices[index++] = a; + +tmpVertices[index++] = x3; +tmpVertices[index++] = y3; +tmpVertices[index++] = 0; +tmpVertices[index++] = u2;tmpVertices[index++] = v2; +tmpVertices[index++] = r;tmpVertices[index++] = g;tmpVertices[index++] = b;tmpVertices[index++] = a; + +tmpVertices[index++] = x4; +tmpVertices[index++] = y4; +tmpVertices[index++] = 0; +tmpVertices[index++] = u2;tmpVertices[index++] = v; +tmpVertices[index++] = r;tmpVertices[index++] = g;tmpVertices[index++] = b;tmpVertices[index++] = a; + + + currentBatchSize++; + + } + + public function add() + { + currentBatchSize++; + } +public function addTile(x:Float,y:Float,width:Float,height:Float,clip:Clip,flipx:Bool,flipy:Bool) +{ +var r, g, b, a:Float; +r = 1; +g = 1; +b = 1; +a = 1; + + + + + var fx2:Float = x+width; + var fy2:Float = y+height; + + + + + + + var u:Float = clip.x * invTexWidth; + var u2:Float = (clip.x + clip.width) * invTexWidth; + + var v:Float = (clip.y + clip.height) * invTexHeight; + var v2:Float = clip.y * invTexHeight; + + if (flipx) + { + var tmp:Float = u; + u = u2; + u2 = tmp; + } + + if (flipy) + { + var tmp:Float = v; + v = v2; + v2 = tmp; + } + +tmpVertices[index++] = x; +tmpVertices[index++] = y; +tmpVertices[index++] = 0; +tmpVertices[index++] = u;tmpVertices[index++] = v; +tmpVertices[index++] = r;tmpVertices[index++] = g;tmpVertices[index++] = b;tmpVertices[index++] = a; + +tmpVertices[index++] = x; +tmpVertices[index++] = fy2; +tmpVertices[index++] = 0; +tmpVertices[index++] = u;tmpVertices[index++] = v2; +tmpVertices[index++] = r;tmpVertices[index++] = g;tmpVertices[index++] = b;tmpVertices[index++] = a; + +tmpVertices[index++] = fx2; +tmpVertices[index++] = fy2; +tmpVertices[index++] = 0; +tmpVertices[index++] = u2;tmpVertices[index++] = v2; +tmpVertices[index++] = r;tmpVertices[index++] = g;tmpVertices[index++] = b;tmpVertices[index++] = a; + +tmpVertices[index++] = fx2; +tmpVertices[index++] = y; +tmpVertices[index++] = 0; +tmpVertices[index++] = u2;tmpVertices[index++] = v; +tmpVertices[index++] = r;tmpVertices[index++] = g;tmpVertices[index++] = b;tmpVertices[index++] = a; + + + + + + + currentBatchSize++; + + } + + public function addVertex(x:Float, y:Float, u:Float, v:Float) + { + tmpVertices[index++] = x; + tmpVertices[index++] = y; + tmpVertices[index++] = 0; + tmpVertices[index++] = u;tmpVertices[index++] = v; + tmpVertices[index++] = 1;tmpVertices[index++] = 1;tmpVertices[index++] = 1;tmpVertices[index++] = 1; + } + + + + public function render() + { + this.update(); + if (!rebuid) + { + rebuid = true; + build(); + return; + } + + if (currentBatchSize==0) return; + shader.Enable(); + // GL.bufferSubData(GL.ARRAY_BUFFER, 0, vertices); + + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.vertexAttribPointer(shader.vertexAttribute, 3, GL.FLOAT, false, vertexStrideSize, 0); + GL.vertexAttribPointer(shader.texCoordAttribute , 2, GL.FLOAT, false, vertexStrideSize, 3 * 4); + GL.vertexAttribPointer(shader.colorAttribute, 4, GL.FLOAT, false, vertexStrideSize, (3+2) * 4); + BlendMode.setBlend(currentBlendMode); + GL.uniformMatrix4fv(shader.modelViewMatrixUniform, false, new Float32Array(viewMatrix.toArray())); + GL.uniformMatrix4fv(shader.projectionMatrixUniform, false,new Float32Array(Game.projMatrix.toArray())); + GL.activeTexture(GL.TEXTURE0); + currentBaseTexture.Bind(); + GL.uniform1i (shader.imageUniform, 0); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + GL.drawElements(GL.TRIANGLES, currentBatchSize * 6, GL.UNSIGNED_SHORT, 0); + shader.Disable(); + } + +} \ No newline at end of file diff --git a/src/com/engine/render/SpriteShader.hx b/src/com/engine/render/SpriteShader.hx new file mode 100755 index 0000000..684aa33 --- /dev/null +++ b/src/com/engine/render/SpriteShader.hx @@ -0,0 +1,124 @@ +package com.engine.render; + +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; + +import flash.geom.Matrix3D; + +/** + * ... + * @author djoker + */ +class SpriteShader +{ +private var shaderProgram:GLProgram; + + public var vertexAttribute :Int; + public var texCoordAttribute :Int; + public var colorAttribute :Int; + public var projectionMatrixUniform:Dynamic; + public var modelViewMatrixUniform:Dynamic; + public var imageUniform:Dynamic; + + + + public function new() + { + + +var vertexShaderSource = +" +attribute vec3 aVertexPosition; +attribute vec2 aTexCoord; +attribute vec4 aColor; + +varying vec2 vTexCoord; +varying vec4 vColor; + +uniform mat4 uModelViewMatrix; +uniform mat4 uProjectionMatrix; +void main(void) +{ +vTexCoord = aTexCoord; +vColor = aColor; +gl_Position = uProjectionMatrix * uModelViewMatrix * vec4 (aVertexPosition, 1.0); + +}"; + + //gl_Position = vec4(outpos.x, yflip*outpos.y, outpos.z*2.0 - outpos.w, outpos.w); + + +var vertexShader = GL.createShader (GL.VERTEX_SHADER); +GL.shaderSource (vertexShader, vertexShaderSource); +GL.compileShader (vertexShader); + +if (GL.getShaderParameter (vertexShader, GL.COMPILE_STATUS) == 0) +{ + +throw (GL.getShaderInfoLog(vertexShader)); + +} + +var fragmentShaderSource = + +#if !desktop +"precision mediump float;" + +#end +" +varying vec2 vTexCoord; +varying vec4 vColor; +uniform sampler2D uImage0; + +void main(void) +{ + gl_FragColor = texture2D (uImage0, vTexCoord) * vColor; + +}"; + +var fragmentShader = GL.createShader (GL.FRAGMENT_SHADER); +GL.shaderSource (fragmentShader, fragmentShaderSource); +GL.compileShader (fragmentShader); + +if (GL.getShaderParameter (fragmentShader, GL.COMPILE_STATUS) == 0) { + + throw(GL.getShaderInfoLog(fragmentShader)); + +} + +shaderProgram = GL.createProgram (); +GL.attachShader (shaderProgram, vertexShader); +GL.attachShader (shaderProgram, fragmentShader); +GL.linkProgram (shaderProgram); + +if (GL.getProgramParameter (shaderProgram, GL.LINK_STATUS) == 0) { + + +throw "Unable to initialize the shader program."; +} + +vertexAttribute = GL.getAttribLocation (shaderProgram, "aVertexPosition"); +texCoordAttribute = GL.getAttribLocation (shaderProgram, "aTexCoord"); +colorAttribute = GL.getAttribLocation (shaderProgram, "aColor"); +projectionMatrixUniform = GL.getUniformLocation (shaderProgram, "uProjectionMatrix"); +modelViewMatrixUniform = GL.getUniformLocation (shaderProgram, "uModelViewMatrix"); +imageUniform = GL.getUniformLocation (shaderProgram, "uImage0"); + + } + + public function Enable() + { + GL.useProgram (shaderProgram); + GL.enableVertexAttribArray (vertexAttribute); + GL.enableVertexAttribArray (texCoordAttribute); + GL.enableVertexAttribArray (colorAttribute); + } + public function Disable() + { + GL.disableVertexAttribArray (vertexAttribute); + GL.disableVertexAttribArray (texCoordAttribute); + GL.disableVertexAttribArray (colorAttribute); + //GL.useProgram (null); + } +} \ No newline at end of file diff --git a/src/com/engine/render/Texture.hx b/src/com/engine/render/Texture.hx new file mode 100755 index 0000000..070c320 --- /dev/null +++ b/src/com/engine/render/Texture.hx @@ -0,0 +1,114 @@ +package com.engine.render; + +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.gl.GLTexture; +import openfl.utils.UInt8Array; + +import flash.display.Bitmap; +import flash.geom.Matrix; +import flash.display.BitmapData; +import flash.Lib; + +import openfl.Assets; + +import com.engine.misc.Util; +import com.engine.misc.MatrixHelp; + +/** + * ... + * @author djoker + */ +class Texture +{ + public var data:GLTexture; + private var bitmapData:BitmapData ; + public var width:Int; + public var height:Int; + public var texHeight:Int; + public var texWidth:Int; + + public function Bind() + { + GL.bindTexture(GL.TEXTURE_2D, data); + } + + public function new(url:String) + { + + + + bitmapData = Assets.getBitmapData(url); + // bitmapData = flipBitmapData(bitmapData); + + + data = GL.createTexture (); + GL.bindTexture(GL.TEXTURE_2D, data); + + + + + this.width = bitmapData.width; + this.height = bitmapData.height; + + this.texWidth = Util.getNextPowerOfTwo(width); + this.texHeight = Util.getNextPowerOfTwo(height); + + // trace(this.texWidth +"<>"+ this.texHeight); + + var isPot = (bitmapData.width == texWidth && bitmapData.height == texHeight); + + + // trace(bitmapData.width + " x " + bitmapData.height); + // trace(texWidth + " x " + texHeight); + + GL.texParameteri (GL.TEXTURE_2D, GL.TEXTURE_WRAP_S, GL.CLAMP_TO_EDGE); + GL.texParameteri (GL.TEXTURE_2D, GL.TEXTURE_WRAP_T, GL.CLAMP_TO_EDGE); + GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST); + GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST); + + + if (!isPot) + { + var workingCanvas:BitmapData = MatrixHelp.getScaled(bitmapData, Std.int(texWidth / 2), Std.int(texHeight / 2)); + bitmapData = null; + + #if html5 + var pixelData = workingCanvas.getPixels(workingCanvas.rect).byteView; + #else + var pixelData = new UInt8Array(BitmapData.getRGBAPixels(workingCanvas)); + #end + GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, workingCanvas.width, workingCanvas.height, 0, GL.RGBA, GL.UNSIGNED_BYTE, pixelData); + + + + + } else + { + + #if html5 + var pixelData = bitmapData.getPixels(bitmapData.rect).byteView; + #else + var pixelData = new UInt8Array(BitmapData.getRGBAPixels(bitmapData)); + #end + GL.texImage2D(GL.TEXTURE_2D, 0, GL.RGBA, texWidth, texHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, pixelData); + } + + + + + + + + + + //GL.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST_MIPMAP_NEAREST); + //GL.generateMipmap(GL.TEXTURE_2D); + // GL.bindTexture(GL.TEXTURE_2D, null); + + + } + + +} \ No newline at end of file diff --git a/src/com/engine/render/TileMap.hx b/src/com/engine/render/TileMap.hx new file mode 100755 index 0000000..7820f5c --- /dev/null +++ b/src/com/engine/render/TileMap.hx @@ -0,0 +1,746 @@ +package com.engine.render; + +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.utils.Float32Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; +import com.engine.game.Game; +import flash.geom.Point; +import openfl.Assets; + +import com.engine.misc.Util; +import com.engine.math.Vector3; +import com.engine.math.Matrix; + +import flash.geom.Matrix3D; +import flash.geom.Vector3D; + + +/** + * ... + * @author djoker + */ + +typedef Array2D = Array> + +class TileMap extends Buffer +{ + + private var _map:Array2D; + private var _columns:Int; + private var _rows:Int; + public var widthInTiles:Int; + public var heightInTiles:Int; + public var tileWidth:Int; + public var tileHeight:Int; + public var margin:Int=0; + public var spacing:Int=0; + public var tilesIDs:Array; + public var clips:Array; + public var columns:Int; + public var image:Texture; + private var isBuild:Bool; + private var capacity:Int; + private var numVerts:Int; + private var numIndices:Int; + private var vertices:Float32Array; + private var indices:Int16Array; + private var lastIndexCount:Int; + private var drawing:Bool; + private var currentBatchSize:Int; + private var currentBlendMode:Int; + private var currentBaseTexture:Texture; + + private var trasform:Matrix3D; + + +private var vertexBuffer:GLBuffer; +private var indexBuffer:GLBuffer; + +private var invTexWidth:Float = 0; +private var invTexHeight:Float = 0; + +public var shader:SpriteShader; +public var vertexStrideSize:Int; + + + + +public function new (xml:String):Void + { + super(); + var xml = Xml.parse(xml).firstElement(); + + widthInTiles = Std.parseInt(xml.get("width")); + heightInTiles = Std.parseInt(xml.get("height")); + //this.orientation = xml.get("orientation"); + // tileWidth = Std.parseInt(xml.get("tilewidth")); + // tileHeight = Std.parseInt(xml.get("tileheight")); + var properties = new Map(); + + for (child in xml) + { + // trace("node:" +child.toString()); + if (isValidElement(child)) + { + // trace(child.nodeName); + if (child.nodeName == "tileset") + { + if (child.get("source") != null) + { + tilesfromGenericXml(getText(child.get("source"))); + } else + { + tilesfromGenericXml(child.toString()); + } + + //tileset.setFirstGID(Std.parseInt(child.get("firstgid"))); + + //this.tilesets.push(tileset); + } + + else if (child.nodeName == "properties") + { + for (property in child) + { + if (!isValidElement(property)) + continue; + // properties.set(property.get("name"), property.get("value")); + } + } + + else if (child.nodeName == "layer") + { + layerfromGenericXml(child); + } + + else if (child.nodeName == "objectgroup") + { + objectsfromGenericXml(child); + + + } + } + } + + addClips(); + + capacity = (this.widthInTiles * this.heightInTiles); + + + vertexStrideSize = 9 * 4; + + numVerts = capacity * vertexStrideSize * 4; + numIndices = capacity * 6; + + + + vertices = new Float32Array(numVerts); + + + + + + this.indices = new Int16Array(numIndices); + var length = Std.int(this.indices.length/6); + + for (i in 0...length) + { + var index2 = i * 6; + var index3 = i * 4; + this.indices[index2 + 0] = index3 + 0; + this.indices[index2 + 1] = index3 + 1; + this.indices[index2 + 2] = index3 + 2; + this.indices[index2 + 3] = index3 + 0; + this.indices[index2 + 4] = index3 + 2; + this.indices[index2 + 5] = index3 + 3; + }; + + + + currentBatchSize = 0; + currentBlendMode = BlendMode.NORMAL; + invTexWidth = 1.0 / image.texWidth; + invTexHeight = 1.0 / image.texHeight; + + + + vertexBuffer = GL.createBuffer(); + indexBuffer = GL.createBuffer(); + + + //upload the index data + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer); + GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, indices, GL.STATIC_DRAW); + // GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, null); + + GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); + GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.DYNAMIC_DRAW); + //GL.bufferData(GL.ARRAY_BUFFER, vertices, null); + + + shader = new SpriteShader(); + isBuild = false; + + + trasform = new Matrix3D(); + + + } + + + public function build() + { + for (y in 0...heightInTiles) + { + for (x in 0...widthInTiles) + { + + + var id = getCell(x, y); + if (id >= 1) + { + //id = 1; + var t:Clip = getClip(id - 1); + var DrawX:Int =Std.int((x * tileWidth)); + var DrawY:Int =Std.int((y * tileHeight)); + var dst:Clip = new Clip(DrawX, DrawY, tileWidth, tileHeight); + this.addQuad(t,dst); + } + } + } + isBuild = true; + } + + +public function addQuad(srcrect:Clip, dstrect:Clip) +{ + +var index:Int = currentBatchSize * vertexStrideSize; + +var widthTex:Int = image.width; +var heightTex:Int = image.height; + + + + +vertices[index++] = dstrect.x; +vertices[index++] = dstrect.y; +vertices[index++] = 0; +vertices[index++] = srcrect.x / widthTex; vertices[index++] = srcrect.y / heightTex; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = (dstrect.x + dstrect.width); +vertices[index++] = dstrect.y; +vertices[index++] = 0; +vertices[index++] = (srcrect.x + srcrect.width) / widthTex;vertices[index++] = srcrect.y / heightTex; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] =(dstrect.x + dstrect.width); +vertices[index++] =(dstrect.y + dstrect.height); +vertices[index++] = 0; +vertices[index++] = (srcrect.x + srcrect.width) / widthTex;vertices[index++] = (srcrect.y + srcrect.height) / heightTex; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = dstrect.x; +vertices[index++] = (dstrect.y + dstrect.height); +vertices[index++] = 0; +vertices[index++] = srcrect.x / widthTex; vertices[index++] = (srcrect.y + srcrect.height) / heightTex; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + + + + +this.currentBatchSize++; + +} +public function render() + { + this.update(); + + + + if (!isBuild) + { + build(); + return; + } + shader.Enable(); + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.vertexAttribPointer(shader.vertexAttribute, 3, GL.FLOAT, false, vertexStrideSize, 0); + GL.vertexAttribPointer(shader.texCoordAttribute , 2, GL.FLOAT, false, vertexStrideSize, 3 * 4); + GL.vertexAttribPointer(shader.colorAttribute, 4, GL.FLOAT, false, vertexStrideSize, (3+2) * 4); + + + + if (currentBatchSize == 0) return; + + + + GL.activeTexture(GL.TEXTURE0); + image.Bind(); + BlendMode.setBlend(this.currentBlendMode); + GL.uniformMatrix4fv(shader.projectionMatrixUniform, false,new Float32Array(Game.projMatrix.toArray())); + GL.uniformMatrix4fv(shader.modelViewMatrixUniform, false, new Float32Array(viewMatrix.toArray())); + + GL.uniform1i (shader.imageUniform, 0); + GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.DYNAMIC_DRAW); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + GL.drawElements(GL.TRIANGLES, currentBatchSize * 6, GL.UNSIGNED_SHORT, 0); + shader.Disable(); + } + +public function renderDinamic(posx:Float,posy:Float) + { + this.update(); + isBuild = false; + currentBatchSize = 0; + shader.Enable(); + GL.bindBuffer(GL.ARRAY_BUFFER, this.vertexBuffer); + GL.vertexAttribPointer(shader.vertexAttribute, 3, GL.FLOAT, false, vertexStrideSize, 0); + GL.vertexAttribPointer(shader.texCoordAttribute , 2, GL.FLOAT, false, vertexStrideSize, 3 * 4); + GL.vertexAttribPointer(shader.colorAttribute, 4, GL.FLOAT, false, vertexStrideSize, (3+2) * 4); + + for (y in 0...heightInTiles) + { + for (x in 0...widthInTiles) + { + + + var id = getCell(x, y); + if (id >= 1) + { + var t:Clip = getClip(id - 1); + var DrawX:Int =Std.int(posx+(x * tileWidth)); + var DrawY:Int =Std.int(posy+(y * tileHeight)); + var dst:Clip = new Clip(DrawX, DrawY, tileWidth, tileHeight); + if (((DrawX >= -tileWidth) && (DrawX <= Game.viewWidth+tileWidth)) && ((DrawY >= -tileHeight) && (DrawY < Game.viewHeight+tileHeight))) + { + this.addQuad(t, dst); + } + } + } + } + + + if (currentBatchSize == 0) return; + GL.activeTexture(GL.TEXTURE0); + image.Bind(); + BlendMode.setBlend(this.currentBlendMode); + GL.uniformMatrix4fv(shader.projectionMatrixUniform, false,new Float32Array(Game.projMatrix.toArray())); + GL.uniformMatrix4fv(shader.modelViewMatrixUniform, false, new Float32Array(viewMatrix.toArray())); + GL.uniform1i (shader.imageUniform, 0); + GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.DYNAMIC_DRAW); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + GL.drawElements(GL.TRIANGLES, currentBatchSize * 6, GL.UNSIGNED_SHORT, 0); + currentBatchSize = 0; + shader.Disable(); + } + + + + public function getCell(x:Int, y:Int):Int + { + return tilesIDs[y * this.widthInTiles + x]; + + } + public function getClip(num:Int):Clip + { + + + + // return new Clip(this.tileWidth * (num % columns), this.tileHeight * Std.int(num / columns), this.tileWidth, this.tileHeight); + return new Clip( + this.margin + (this.tileWidth + this.spacing) * num % columns, + this.margin + (this.tileHeight + this.spacing) * Std.int(num / columns), + this.tileWidth, this.tileHeight); + + + + + } + public function getClipNum(num:Int):Clip + { + if (num <= 0) + { + //trace("id <0:" + num); + return clips[0]; + } + if (num >= clips.length) + { + //trace("id: >" +clips.length +" : "+ num); + return clips[clips.length]; + } + + return clips[num]; + } + + public function addClips() + { + clips = []; + var columns:Int =Std.int( image.width / this.tileWidth ); + var rows:Int =Std.int( image.height / this.tileHeight ); + + + for ( y in 0...rows) + { + for (x in 0...columns) + { + var rect:Clip = new Clip(); + rect.y = y * (tileHeight + spacing); + rect.y += margin; + rect.height = tileHeight; + rect.x = x * (tileWidth + spacing); + rect.x += margin; + rect.width = tileWidth; + clips.push(rect); + + + } + } + } + + public function loadFromString(str:String, columnSep:String = ",", rowSep:String = "\n") + { + var row:Array = str.split(rowSep), + rows:Int = row.length, + col:Array, cols:Int, x:Int, y:Int; + for (y in 0...rows) + { + if (row[y] == '') continue; + col = row[y].split(columnSep); + cols = col.length; + for (x in 0...cols) + { + if (col[x] == '') continue; + _map[y][x] = Std.parseInt(col[x]); + } + } + } + + + public function objectfromGenericXml(xml:Xml) + { + var gid:Int = xml.get("gid") != null ? Std.parseInt(xml.get("gid")) : 0; + var name:String = xml.get("name"); + var type:String = xml.get("type"); + var x:Int = Std.parseInt(xml.get("x")); + var y:Int = Std.parseInt(xml.get("y")); + var width:Int = Std.parseInt(xml.get("width")); + var height:Int = Std.parseInt(xml.get("height")); + //var polygon:TiledPolygon = null; + //var polyline:TiledPolyline = null; + var properties:Map = new Map(); + + for (child in xml) + { + if (isValidElement(child)) + { + if (child.nodeName == "properties") + { + for (property in child) + { + if (isValidElement(property)) + { + properties.set(property.get("name"), property.get("value")); + } + } + } + + if (child.nodeName == "polygon" || child.nodeName == "polyline") + { + var origin:Point = new Point(x, y); + var points:Array = new Array(); + + var pointsAsString:String = child.get("points"); + + var pointsAsStringArray:Array = pointsAsString.split(" "); + + for (p in pointsAsStringArray) + { + //var coords:Array = p.split(","); + //points.push(new Point(Std.parseInt(coords[0]), Std.parseInt(coords[1]))); + } + + if (child.nodeName == "polygon") + { + //polygon = new TiledPolygon(origin, points); + } else if (child.nodeName == "polyline") + { + // polyline = new TiledPolyline(origin, points); + } + } + } + } + + + } + public function objectsfromGenericXml(xml:Xml) + { + var name = xml.get("name"); + var color = xml.get("color"); + var width = Std.parseInt(xml.get("width")); + var height = Std.parseInt(xml.get("height")); + var properties:Map = new Map(); + //var objects:Array = new Array(); + + for (child in xml) { + if (isValidElement(child)) + { + if (child.nodeName == "properties") { + for (property in child) { + if (isValidElement(property)) + { + properties.set(property.get("name"), property.get("value")); + } + } + } + + if (child.nodeName == "object") + { + objectfromGenericXml(child); + } + } + } + + + } + + + public function isValidElement(element:Xml):Bool + { + return Std.string(element.nodeType) == "element"; + } + public function getText(assetPath:String):String + { + return Assets.getText(assetPath); + } + + public function tilesfromGenericXml(content:String) + { + var xml = Xml.parse(content).firstElement(); + + var name:String = xml.get("name"); + tileWidth = Std.parseInt(xml.get("tilewidth")); + tileHeight = Std.parseInt(xml.get("tileheight")); + spacing = xml.exists("spacing") ? Std.parseInt(xml.get("spacing")) : 0; + margin = xml.exists("margin") ? Std.parseInt(xml.get("margin")) : 0; + + var properties:Map = new Map(); + //var propertyTiles:Map = new Map(); + //var terrainTypes:Array = new Array(); + //var image:TilesetImage = null; + + var tileOffsetX:Int = 0; + var tileOffsetY:Int = 0; + + for (child in xml.elements()) + { + if (isValidElement(child)) + { + if (child.nodeName == "properties") + { + for (property in child) { + if (isValidElement(property)) + { + trace("tileHeight set name:" + property.get("name") +" - Value : " + property.get("value")); + // properties.set(property.get("name"), property.get("value")); + } + } + } + + if (child.nodeName == "tileoffset") + { + tileOffsetX = Std.parseInt(child.get("x")); + tileOffsetY = Std.parseInt(child.get("y")); + } + + if (child.nodeName == "image") + { + var width = Std.parseInt(child.get("width")); + var height = Std.parseInt(child.get("height")); + // trace("Tile set: Image: " + child.get("source")); + this.image = new Texture("assets/" + child.get("source")); + if (image!=null) + { + this.columns = Std.int(image.width / this.tileWidth); + + + //trace("Columns:" + columns); + } + //image = new TilesetImage(child.get("source"), width, height); + } + + if (child.nodeName == "terraintypes") + { + for (element in child) + { + + if (isValidElement(element)) + { + if (element.nodeName == "terrain") + { + // terrainTypes.push(new TerrainType(element.get("name"), Std.parseInt(element.get("tile")))); + } + } + } + } + + + if (child.nodeName == "tile") + { + //trace("tile"); + var id:Int = Std.parseInt(child.get("id")); + var properties:Map = new Map(); + + for (element in child) + { + + if (isValidElement(element)) + { + if (element.nodeName == "properties") + { + for (property in element) { + if (!isValidElement(property)) { + continue; + } + + //properties.set(property.get("name"), property.get("value")); + } + } + } + } + + //propertyTiles.set(id, new PropertyTile(id, properties)); + } + } + } + + //return new Tileset(name, tileWidth, tileHeight, spacing, properties, terrainTypes, image, + //new Point(tileOffsetX, tileOffsetY)); + } + + + private function csvToArray(input:String):Array + { + var result:Array = new Array(); + var rows:Array = StringTools.trim(input).split("\n"); + var row:String; + + for (row in rows) { + + if (row == "") { + continue; + } + + var resultRow:Array = new Array(); + var entries:Array = row.split(","); + var entry:String; + + for (entry in entries) { + + if(entry != "") { + result.push(Std.parseInt(entry)); + } + } + } + return result; + } + + + public function layerfromGenericXml(xml:Xml) + { + var name:String = xml.get("name"); + var width:Int = Std.parseInt(xml.get("width")); + var height:Int = Std.parseInt(xml.get("height")); + var opacity:Float = Std.parseFloat(xml.get("opacity") != null ? xml.get("opacity") : "1.0"); + + tilesIDs= new Array(); + + for (child in xml) + { + if (isValidElement(child)) + { + if (child.nodeName == "data") + { + var encoding:String = ""; + if (child.exists("encoding")) + { + encoding = child.get("encoding"); + } + var chunk:String = ""; + switch(encoding){ + case "base64": + { + chunk = child.firstChild().nodeValue; + //trace("base64"); + } + case "csv": + { + chunk = child.firstChild().nodeValue; + //trace("csv"); + tilesIDs = csvToArray(chunk); + } + default: + { + //trace("string tiles"); + for (tile in child) + { + if (isValidElement(tile)) + { + var gid = Std.parseInt(tile.get("gid")); + tilesIDs.push(gid); + } + } + } + } + } + } + } + } + public function toCSV(?width:Int):String + { + if (width <= 0 || width == null) + { + width = this.widthInTiles; + } + + var counter:Int = 0; + var csv:String = ""; + + for (tile in tilesIDs) + { + var tileGID = tile; + + if (counter >= width) + { + // remove the last "," + csv = csv.substr(0, csv.length - 1); + + // add a new line and reset counter + csv += '\n'; + counter = 0; + } + + csv += tileGID; + csv += ','; + + counter++; + } + + // remove the last "," + csv = csv.substr(0, csv.length - 1); + + return csv; + } + +override public function dispose():Void +{ + GL.deleteBuffer(indexBuffer); + GL.deleteBuffer(vertexBuffer); + super.dispose(); + +} +} \ No newline at end of file diff --git a/src/com/engine/render/VertexBuffer.hx b/src/com/engine/render/VertexBuffer.hx new file mode 100755 index 0000000..da58c53 --- /dev/null +++ b/src/com/engine/render/VertexBuffer.hx @@ -0,0 +1,332 @@ +package com.engine.render; + +import flash.geom.Matrix3D; + +import openfl.display.OpenGLView; +import openfl.gl.GL; +import openfl.gl.GLBuffer; +import openfl.gl.GLProgram; +import openfl.gl.GLTexture; +import openfl.gl.GLUniformLocation; +import openfl.utils.Float32Array; +import openfl.utils.UInt8Array; +import openfl.utils.Int16Array; +import openfl.display.FPS; + +import com.engine.math.Matrix; +import com.engine.render.BlendMode; + +/** + * ... + * @author djoker + */ +class VertexBuffer +{ +private var vertexBuffer:GLBuffer; +private var indexBuffer:GLBuffer; + +public var vertexAttribute:Int=0; +public var textureAttribute :Int=1; +public var colorAttribute:Int=2; + +public var vertices:Float32Array; + + public var vertexDeclaration:Array; + public var vertexStrideSize:Int; + + +private var imageUniform:GLUniformLocation; +private var modelViewMatrixUniform:GLUniformLocation; +private var projectionMatrixUniform:GLUniformLocation; +private var shaderProgram:GLProgram; + + + private var size:Int; + private var vertSize:Int; + private var numVerts:Int; + private var numIndices:Int; + private var idx:Int = 0; + private var primitiveCount:Int = 0; + + public function new() + { + + + + size = 1000; + vertSize = 6; + numVerts = size * 4 * vertSize; + numIndices = size * 6; + +vertices = new Float32Array(numVerts); + + +var indices:Int16Array = new Int16Array(numIndices); +var j:Int = 0; +var i:Int = 0; + for (count in 0...numIndices) + { + indices[i] = j + 0; i++; + indices[i] = j + 1; i++; + indices[i] = j + 2; i++; + indices[i] = j + 0; i++; + indices[i] = j + 2; i++; + indices[i] = j + 3; i++; + + j += 4; + } + + + + +primitiveCount = 0; + + + + vertexDeclaration = [3, 2,4]; + vertexStrideSize = 9 * 4 ; // 9 floats (x, y, z,u,v, r, g, b, a) + + + + + if (!initializeShaders()) return; + + +vertexBuffer = GL.createBuffer(); +GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); +GL.bufferData(GL.ARRAY_BUFFER, vertices, GL.DYNAMIC_DRAW); +GL.bindBuffer(GL.ARRAY_BUFFER, null); + + indexBuffer= GL.createBuffer(); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer); + GL.bufferData(GL.ELEMENT_ARRAY_BUFFER, indices, GL.STATIC_DRAW); + + + + } + + + public function RenderNormal( x:Float, y:Float,w:Float,h:Float) +{ + + + var u:Float = 0; + var v:Float = 1; + var u2:Float = 1; + var v2:Float = 0; + + var fx2:Float = x + w; + var fy2:Float = y + h; + + +var index:Int = primitiveCount * vertexStrideSize; + +vertices[index++] = x; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v; +vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1;vertices[index++] = 1; + +vertices[index++] = x; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = fy2; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v2; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; + +vertices[index++] = fx2; +vertices[index++] = y; +vertices[index++] = 0; +vertices[index++] = u2;vertices[index++] = v; +vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; vertices[index++] = 1; +/* + +vertices[idx++] = x; +vertices[idx++] = y; +vertices[idx++] = 0; +vertices[idx++] = u;vertices[idx++] = v; +vertices[idx++] = 1;vertices[idx++] = 1;vertices[idx++] = 1;vertices[idx++] = 1; + +vertices[idx++] = x; +vertices[idx++] = fy2; +vertices[idx++] = 0; +vertices[idx++] = u;vertices[idx++] = v2; +vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; + +vertices[idx++] = fx2; +vertices[idx++] = fy2; +vertices[idx++] = 0; +vertices[idx++] = u2;vertices[idx++] = v2; +vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; + +vertices[idx++] = fx2; +vertices[idx++] = y; +vertices[idx++] = 0; +vertices[idx++] = u2;vertices[idx++] = v; +vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; vertices[idx++] = 1; +*/ + +primitiveCount++; + +} + + public function Begin(matProj:Matrix3D,matView:Matrix3D) + { + primitiveCount = 0; + idx = 0; + + +GL.useProgram (shaderProgram); +GL.enableVertexAttribArray(vertexAttribute); +GL.enableVertexAttribArray(textureAttribute); +GL.enableVertexAttribArray(colorAttribute); + + +GL.activeTexture (GL.TEXTURE0); +GL.enable (GL.TEXTURE_2D); + + + + GL.bindBuffer(GL.ARRAY_BUFFER, vertexBuffer); + GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, indexBuffer); + +GL.vertexAttribPointer(vertexAttribute, 3, GL.FLOAT, false, vertexStrideSize,0); +GL.vertexAttribPointer(textureAttribute,2, GL.FLOAT, false, vertexStrideSize,3*4); +GL.vertexAttribPointer(colorAttribute ,4, GL.FLOAT, false, vertexStrideSize,(3+2) * 4); + +GL.uniformMatrix3D (projectionMatrixUniform, false, matProj); +GL.uniformMatrix3D (modelViewMatrixUniform, false, matView); +GL.uniform1i (imageUniform, 0); + + + + } + public function End() + { + + GL.bufferSubData(GL.ARRAY_BUFFER, 0, vertices); + GL.drawElements(GL.TRIANGLES, primitiveCount * 6, GL.UNSIGNED_SHORT, 0); + + +GL.bindBuffer (GL.ARRAY_BUFFER, null); +GL.bindTexture (GL.TEXTURE_2D, null); + + +GL.disable (GL.TEXTURE_2D); + +GL.disableVertexAttribArray (vertexAttribute); +GL.disableVertexAttribArray (textureAttribute); +GL.disableVertexAttribArray (colorAttribute); +GL.useProgram (null); + } + + +private function initializeShaders ():Bool { + +var vertexShaderSource = + +"attribute vec3 aVertexPosition; + attribute vec2 aTexCoord; + attribute vec4 aColor; + +varying vec2 vTexCoord; +varying vec4 vColor; + +uniform mat4 uModelViewMatrix; +uniform mat4 uProjectionMatrix; +void main(void) +{ +vColor = aColor; +vTexCoord = aTexCoord; +gl_Position = uProjectionMatrix * uModelViewMatrix * vec4 (aVertexPosition, 1.0); +}"; + +var vertexShader = GL.createShader (GL.VERTEX_SHADER); +GL.shaderSource (vertexShader, vertexShaderSource); +GL.compileShader (vertexShader); + +if (GL.getShaderParameter (vertexShader, GL.COMPILE_STATUS) == 0) { + +throw "Error compiling vertex shader"; + +} + +var fragmentShaderSource = + +#if !desktop +"precision mediump float;" + +#end +"varying vec2 vTexCoord; +varying vec4 vColor; +uniform sampler2D uImage0; +void main(void) +{ + vec4 texColor = texture2D(uImage0, vTexCoord); + gl_FragColor = vColor * texColor; + // gl_FragColor = texColor *vec4(1.0, 1.0, 1.0, 1.0); + +//gl_FragColor = texture2D (uImage0, vTexCoord); +}"; + +var fragmentShader = GL.createShader (GL.FRAGMENT_SHADER); +GL.shaderSource (fragmentShader, fragmentShaderSource); +GL.compileShader (fragmentShader); + +if (GL.getShaderParameter (fragmentShader, GL.COMPILE_STATUS) == 0) { + +throw "Error compiling fragment shader"; + +} + +shaderProgram = GL.createProgram (); +GL.attachShader (shaderProgram, vertexShader); +GL.attachShader (shaderProgram, fragmentShader); +GL.linkProgram (shaderProgram); + +if (GL.getProgramParameter (shaderProgram, GL.LINK_STATUS) == 0) { + +throw "Unable to initialize the shader program."; + +} + +vertexAttribute = GL.getAttribLocation (shaderProgram, "aVertexPosition"); +textureAttribute = GL.getAttribLocation (shaderProgram, "aTexCoord"); +//colorAttribute = GL.getAttribLocation (shaderProgram, "aColor"); + +//GL.bindAttribLocation(shaderProgram, vertexAttribute, "aVertexPosition"); +//GL.bindAttribLocation(shaderProgram,textureAttribute, "aTexCoord"); +GL.bindAttribLocation(shaderProgram, colorAttribute, "aColor"); + + +trace(vertexAttribute); +trace(textureAttribute); +trace(colorAttribute); + +projectionMatrixUniform = GL.getUniformLocation (shaderProgram, "uProjectionMatrix"); +modelViewMatrixUniform = GL.getUniformLocation (shaderProgram, "uModelViewMatrix"); +imageUniform = GL.getUniformLocation (shaderProgram, "uImage0"); +return true; +} + + +public function addVertex(index:Int, x:Float, y:Float, u:Float, v:Float, r:Float, g:Float, b:Float, a:Float ) +{ + var offset = index * 9; + vertices[offset] = x; + vertices[offset + 1] = y; + vertices[offset + 2] = 0; + vertices[offset + 3] = u; + vertices[offset + 4] = v; + vertices[offset + 5] = r; + vertices[offset + 6] = g; + vertices[offset + 7] = b; + vertices[offset + 8] = a; + + } + +} \ No newline at end of file