321 lines
8.3 KiB
Haxe
321 lines
8.3 KiB
Haxe
package;
|
|
|
|
|
|
import format.png.Reader;
|
|
import format.png.Tools;
|
|
import haxe.io.Bytes;
|
|
import haxe.io.BytesData;
|
|
import haxe.io.BytesInput;
|
|
import lime.gl.GL;
|
|
import lime.gl.GLBuffer;
|
|
import lime.gl.GLProgram;
|
|
import lime.gl.GLTexture;
|
|
import lime.gl.GLUniformLocation;
|
|
import lime.utils.ByteArray;
|
|
import lime.utils.Matrix3D;
|
|
import lime.utils.Assets;
|
|
import lime.utils.Float32Array;
|
|
import lime.utils.UInt8Array;
|
|
import lime.Lime;
|
|
|
|
|
|
class Main {
|
|
|
|
|
|
private var imageData:UInt8Array;
|
|
private var imageHeight:Int;
|
|
private var imageWidth:Int;
|
|
private var imageUniform:GLUniformLocation;
|
|
private var lime:Lime;
|
|
private var modelViewMatrixUniform:GLUniformLocation;
|
|
private var projectionMatrixUniform:GLUniformLocation;
|
|
private var shaderProgram:GLProgram;
|
|
private var texCoordAttribute:Int;
|
|
private var texCoordBuffer:GLBuffer;
|
|
private var texture:GLTexture;
|
|
private var vertexAttribute:Int;
|
|
private var vertexBuffer:GLBuffer;
|
|
|
|
|
|
public function new () {}
|
|
|
|
|
|
private function createBuffers ():Void {
|
|
|
|
var vertices = [
|
|
|
|
imageWidth, imageHeight, 0,
|
|
0, imageHeight, 0,
|
|
imageWidth, 0, 0,
|
|
0, 0, 0
|
|
|
|
];
|
|
|
|
vertexBuffer = GL.createBuffer ();
|
|
GL.bindBuffer (GL.ARRAY_BUFFER, vertexBuffer);
|
|
GL.bufferData (GL.ARRAY_BUFFER, new Float32Array (cast vertices), GL.STATIC_DRAW);
|
|
GL.bindBuffer (GL.ARRAY_BUFFER, null);
|
|
|
|
var texCoords = [
|
|
|
|
1, 1,
|
|
0, 1,
|
|
1, 0,
|
|
0, 0,
|
|
|
|
];
|
|
|
|
texCoordBuffer = GL.createBuffer ();
|
|
GL.bindBuffer (GL.ARRAY_BUFFER, texCoordBuffer);
|
|
GL.bufferData (GL.ARRAY_BUFFER, new Float32Array (cast texCoords), GL.STATIC_DRAW);
|
|
GL.bindBuffer (GL.ARRAY_BUFFER, null);
|
|
|
|
}
|
|
|
|
|
|
private function createTexture ():Void {
|
|
|
|
texture = GL.createTexture ();
|
|
GL.bindTexture (GL.TEXTURE_2D, texture);
|
|
GL.texImage2D (GL.TEXTURE_2D, 0, GL.RGBA, imageHeight, imageHeight, 0, GL.RGBA, GL.UNSIGNED_BYTE, imageData);
|
|
GL.texParameteri (GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.LINEAR);
|
|
GL.texParameteri (GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.LINEAR);
|
|
GL.bindTexture (GL.TEXTURE_2D, null);
|
|
|
|
}
|
|
|
|
|
|
private function initializeShaders ():Void {
|
|
|
|
var vertexShaderSource = "";
|
|
|
|
#if lime_html5
|
|
vertexShaderSource += "precision mediump float;";
|
|
#end
|
|
|
|
vertexShaderSource += "attribute vec3 aVertexPosition;
|
|
attribute vec2 aTexCoord;
|
|
varying vec2 vTexCoord;
|
|
|
|
uniform mat4 uModelViewMatrix;
|
|
uniform mat4 uProjectionMatrix;
|
|
|
|
void main(void) {
|
|
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 lime_html5
|
|
fragmentShaderSource += "precision mediump float;";
|
|
#end
|
|
|
|
fragmentShaderSource +=
|
|
"varying vec2 vTexCoord;
|
|
uniform sampler2D uImage0;
|
|
|
|
void main(void)
|
|
{
|
|
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");
|
|
texCoordAttribute = GL.getAttribLocation (shaderProgram, "aTexCoord");
|
|
projectionMatrixUniform = GL.getUniformLocation (shaderProgram, "uProjectionMatrix");
|
|
modelViewMatrixUniform = GL.getUniformLocation (shaderProgram, "uModelViewMatrix");
|
|
imageUniform = GL.getUniformLocation (shaderProgram, "uImage0");
|
|
|
|
}
|
|
|
|
|
|
#if lime_html5
|
|
|
|
function load_image(_id:String, onload:Void->Void) {
|
|
|
|
var image: js.html.ImageElement = js.Browser.document.createImageElement();
|
|
|
|
image.onload = function(a) {
|
|
|
|
try {
|
|
|
|
var tmp_canvas = js.Browser.document.createCanvasElement();
|
|
tmp_canvas.width = image.width;
|
|
tmp_canvas.height = image.height;
|
|
|
|
var tmp_context = tmp_canvas.getContext2d();
|
|
tmp_context.clearRect( 0,0, tmp_canvas.width, tmp_canvas.height );
|
|
tmp_context.drawImage( image, 0, 0, image.width, image.height );
|
|
|
|
var image_bytes = tmp_context.getImageData( 0, 0, tmp_canvas.width, tmp_canvas.height );
|
|
var haxe_bytes = new lime.utils.UInt8Array( image_bytes.data );
|
|
|
|
imageData = haxe_bytes;
|
|
imageHeight = image.width;
|
|
imageWidth = image.height;
|
|
|
|
tmp_canvas = null;
|
|
tmp_context = null;
|
|
haxe_bytes = null;
|
|
image_bytes = null;
|
|
|
|
onload();
|
|
|
|
} catch(e:Dynamic) {
|
|
|
|
trace(e);
|
|
var tips = '- textures might require power of two sizes\n';
|
|
tips += '- textures served from file:/// throw security errors\n';
|
|
tips += '- textures served over http:// work for cross origin';
|
|
|
|
trace(tips);
|
|
throw e;
|
|
|
|
}
|
|
|
|
} //image.onload
|
|
|
|
//source comes after the onload being set, for race conditions
|
|
image.src = _id;
|
|
|
|
} //load_html5_image
|
|
|
|
#else
|
|
|
|
function load_image(_id:String, onload:Void->Void) {
|
|
|
|
var bytes : ByteArray = Assets.getBytes (_id);
|
|
var byteInput = new BytesInput ( bytes, 0, bytes.length);
|
|
var png = new Reader (byteInput).read ();
|
|
var data = Tools.extract32 (png);
|
|
var header = Tools.getHeader (png);
|
|
|
|
imageWidth = header.width;
|
|
imageHeight = header.height;
|
|
imageData = new UInt8Array (data.getData ());
|
|
|
|
var image_length = imageWidth * imageHeight;
|
|
|
|
//bytes are returned in a different order, bgra
|
|
//so we swap back to rgba
|
|
for(i in 0 ... image_length) {
|
|
|
|
var b = imageData[i*4+0];
|
|
var g = imageData[i*4+1];
|
|
var r = imageData[i*4+2];
|
|
var a = imageData[i*4+3];
|
|
|
|
imageData[i*4+0] = r;
|
|
imageData[i*4+1] = g;
|
|
imageData[i*4+2] = b;
|
|
imageData[i*4+3] = a;
|
|
|
|
}
|
|
|
|
onload();
|
|
|
|
}
|
|
|
|
#end //!lime_html5
|
|
|
|
var loaded = false;
|
|
|
|
public function ready (lime:Lime):Void {
|
|
|
|
this.lime = lime;
|
|
|
|
//we load the image with a callback,
|
|
//because on html5 it is asynchronous and we want
|
|
//to only try and use it when it's done loading
|
|
load_image("assets/lime.png", function(){
|
|
|
|
initializeShaders ();
|
|
|
|
createBuffers ();
|
|
createTexture ();
|
|
|
|
loaded = true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
private function render ():Void {
|
|
|
|
if(!loaded) {
|
|
return;
|
|
}
|
|
|
|
GL.viewport (0, 0, lime.config.width, lime.config.height);
|
|
|
|
GL.clearColor (1.0, 1.0, 1.0, 1.0);
|
|
GL.clear (GL.COLOR_BUFFER_BIT);
|
|
|
|
var positionX = (lime.config.width - imageWidth) / 2;
|
|
var positionY = (lime.config.height - imageHeight) / 2;
|
|
|
|
var projectionMatrix = Matrix3D.createOrtho (0, lime.config.width, lime.config.height, 0, 1000, -1000);
|
|
var modelViewMatrix = Matrix3D.create2D (positionX, positionY, 1, 0);
|
|
|
|
GL.useProgram (shaderProgram);
|
|
GL.enableVertexAttribArray (vertexAttribute);
|
|
GL.enableVertexAttribArray (texCoordAttribute);
|
|
|
|
GL.activeTexture (GL.TEXTURE0);
|
|
GL.bindTexture (GL.TEXTURE_2D, texture);
|
|
|
|
GL.bindBuffer (GL.ARRAY_BUFFER, vertexBuffer);
|
|
GL.vertexAttribPointer (vertexAttribute, 3, GL.FLOAT, false, 0, 0);
|
|
GL.bindBuffer (GL.ARRAY_BUFFER, texCoordBuffer);
|
|
GL.vertexAttribPointer (texCoordAttribute, 2, GL.FLOAT, false, 0, 0);
|
|
|
|
GL.uniformMatrix3D (projectionMatrixUniform, false, projectionMatrix);
|
|
GL.uniformMatrix3D (modelViewMatrixUniform, false, modelViewMatrix);
|
|
GL.uniform1i (imageUniform, 0);
|
|
|
|
GL.drawArrays (GL.TRIANGLE_STRIP, 0, 4);
|
|
|
|
GL.bindBuffer (GL.ARRAY_BUFFER, null);
|
|
GL.bindTexture (GL.TEXTURE_2D, null);
|
|
|
|
GL.disableVertexAttribArray (vertexAttribute);
|
|
GL.disableVertexAttribArray (texCoordAttribute);
|
|
GL.useProgram (null);
|
|
|
|
}
|
|
|
|
|
|
}
|