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 @@
+
+
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