Here is the new listing:
package;
import lime.Assets;
import lime.app.Application;
import lime.graphics.Image;
import lime.graphics.Renderer;
import lime.graphics.GLRenderContext;
import lime.graphics.opengl.*;
import lime.system.System;
import lime.ui.KeyCode;
import lime.ui.KeyModifier;
import lime.ui.Window;
import lime.utils.DataPointer;
import lime.utils.Float32Array;
import lime.utils.GLUtils;
class Main extends Application
{
#if html5
private var gl:WebGL2Context;
#elseif desktop
private var gl:GLRenderContext;
#else
private var gl:GLES2Context;
#end
private var glProgram:GLProgram;
private var glVertexAttribute:Int;
private var glTexCoordAttribute:Int;
private var glCameraMatrixUniform:GLUniformLocation;
private var glObjectMatrixUniform:GLUniformLocation;
private var glTextureUniform:GLUniformLocation;
private var glObjectMaterialUniform:GLUniformLocation;
private var glVertexBuffer:GLBuffer;
private var glTexCoordBuffer:GLBuffer;
private var glTexture:GLTexture;
private var cameraMatrix:Matrix;
private var objectMatrix:Matrix;
private var vertexBuffer:Float32Array;
private var texCoordBuffer:Float32Array;
private var materialBuffer:Float32Array;
private var image:Image;
private var mainContextNotInited:Bool;
private var width:Int;
private var height:Int;
private var angle:Float;
private var icoVertexes:Float32Array;
private var icoTexCoords:Float32Array;
var isReady = false;
public function new()
{
super();
mainContextNotInited = true;
angle = 0.0;
}
override public function onWindowCreate(window:Window):Void
{
// super.onWindowCreate(window);
switch(window.renderer.context)
{
case OPENGL(opengl):
gl = opengl;
default:
}
}
public override function update(delta:Int):Void
{
// super.update(delta);
angle += delta / 1000.0;
if(angle >= 360.0)
angle %= 360.0;
}
public override function render(renderer:Renderer)
{
// super.render(renderer);
if(!preloader.complete)
{
return;
}
gl.useProgram(glProgram);
gl.enableVertexAttribArray(glVertexAttribute);
gl.enableVertexAttribArray(glTexCoordAttribute);
#if desktop
gl.enable(gl.TEXTURE_2D);
#end
mainContextRender();
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
#if desktop
gl.disable(gl.TEXTURE_2D);
#end
gl.disableVertexAttribArray(glVertexAttribute);
gl.disableVertexAttribArray(glTexCoordAttribute);
gl.useProgram(null);
}
public override function onKeyDown(window:Window, keyCode:KeyCode, modifier:KeyModifier)
{
// super.onKeyDown(window, keyCode, modifier);
if(keyCode == APP_CONTROL_BACK || keyCode == ESCAPE)
{
System.exit(0);
}
}
override public function onWindowResize(window:Window, width:Int, height:Int)
{
this.width = width;
this.height = height;
}
override public function onPreloadComplete()
{
width = window.width;
height = window.height;
var vertSource =
#if (mobile || html5)
"precision mediump float;" +
#end
"attribute vec4 aVertex;
attribute vec2 aTexCoord;
uniform mat4 uCameraMatrix;
uniform mat4 uObjectMatrix;
uniform vec4 uObjectMaterial;
varying vec2 vTexCoord;
varying vec4 vObjectMaterial;
void main(void)
{
vTexCoord = aTexCoord;
vObjectMaterial = uObjectMaterial;
gl_Position = uCameraMatrix * (uObjectMatrix * aVertex);
}";
var fragSource =
#if (mobile || html5)
"precision mediump float;" +
#end
"varying vec2 vTexCoord;
varying vec4 vObjectMaterial;
uniform sampler2D uTexture;
void main(void)
{
gl_FragColor = vObjectMaterial * texture2D(uTexture, vTexCoord);
}";
glProgram = GLUtils.createProgram(vertSource, fragSource);
glVertexAttribute = gl.getAttribLocation(glProgram, "aVertex");
glTexCoordAttribute = gl.getAttribLocation(glProgram, "aTexCoord");
glCameraMatrixUniform = gl.getUniformLocation(glProgram, "uCameraMatrix");
glObjectMatrixUniform = gl.getUniformLocation(glProgram, "uObjectMatrix");
glObjectMaterialUniform = gl.getUniformLocation(glProgram, "uObjectMaterial");
glTextureUniform = gl.getUniformLocation(glProgram, "uTexture");
glVertexBuffer = gl.createBuffer();
glTexCoordBuffer = gl.createBuffer();
glTexture = gl.createTexture();
gl.frontFace(gl.CCW);
gl.cullFace(gl.BACK);
gl.enable(gl.CULL_FACE);
gl.depthFunc(gl.LESS);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
var X = 0.525731112119133606;
var Z = 0.850650808352039932;
var icosaedronVertex = [
X, 0.0, Z, 0.0, Z, X, -X, 0.0, Z, // 1, 4, 0
0.0, Z, X, -Z, X, 0.0, -X, 0.0, Z, // 4, 9, 0
0.0, Z, X, 0.0, Z, -X, -Z, X, 0.0, // 4, 5, 9
Z, X, 0.0, 0.0, Z, -X, 0.0, Z, X, // 8, 5, 4
X, 0.0, Z, Z, X, 0.0, 0.0, Z, X, // 1, 8, 4
X, 0.0, Z, Z, -X, 0.0, Z, X, 0.0, // 1, 10, 8
Z, -X, 0.0, X, 0.0, -Z, Z, X, 0.0, // 10, 3, 8
Z, X, 0.0, X, 0.0, -Z, 0.0, Z, -X, // 8, 3, 5
X, 0.0, -Z, -X, 0.0, -Z, 0.0, Z, -X, // 3, 2, 5
X, 0.0, -Z, 0.0, -Z, -X, -X, 0.0, -Z, // 3, 7, 2
X, 0.0, -Z, Z, -X, 0.0, 0.0, -Z, -X, // 3, 10, 7
Z, -X, 0.0, 0.0, -Z, X, 0.0, -Z, -X, // 10, 6, 7
0.0, -Z, X, -Z, -X, 0.0, 0.0, -Z, -X, // 6, 11, 7
0.0, -Z, X, -X, 0.0, Z, -Z, -X, 0.0, // 6, 0, 11
0.0, -Z, X, X, 0.0, Z, -X, 0.0, Z, // 6, 1, 0
Z, -X, 0.0, X, 0.0, Z, 0.0, -Z, X, // 10, 1, 6
-Z, -X, 0.0, -X, 0.0, Z, -Z, X, 0.0, // 11, 0, 9
-X, 0.0, -Z, -Z, -X, 0.0, -Z, X, 0.0, // 2, 11, 9
0.0, Z, -X, -X, 0.0, -Z, -Z, X, 0.0, // 5, 2, 9
-Z, -X, 0.0, -X, 0.0, -Z, 0.0, -Z, -X]; // 11, 2, 7
var icasaedronTexCoord = [
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
0.0, 0.0, 1.0, 0.0, 1.0, 1.0];
icoVertexes = new Float32Array(icosaedronVertex);
icoTexCoords = new Float32Array(icasaedronTexCoord);
image = Assets.getImage("assets/lime.png");
}
public function mainContextRender():Void
{
setViewport(0, 0, width, height);
setClearColor(1.0, 0.0, 0.0, 1.0);
setClearDepth(1.0);
clear();
var ratio = height / width;
cameraMatrix = Matrix.initFromPerspective(-6.0, 6.0, -6.0 * ratio, 6.0 * ratio, 20.0, 100.0);
cameraMatrix = Matrix.initFromTranslation(0.0, 0.0, -30.0) * cameraMatrix;
cameraMatrix = Matrix.initFromXRotation(0.15) * cameraMatrix;
setObjectVertex(icoVertexes);
setObjectTexture(image, icoTexCoords);
objectMatrix = Matrix.initFromYRotation(angle);
setObjectMaterial(0.0, 0.0, 1.0, 1.0);
renderObject();
objectMatrix = Matrix.initFromYRotation(angle);
objectMatrix = Matrix.initFromTranslation(3.0, 0.0, 3.0) * objectMatrix;
setObjectMaterial(1.0, 1.0, 0.0, 1.0);
renderObject();
objectMatrix = Matrix.initFromYRotation(angle);
objectMatrix = Matrix.initFromTranslation(3.0, 0.0, -3.0) * objectMatrix;
setObjectMaterial(1.0, 0.0, 1.0, 1.0);
renderObject();
objectMatrix = Matrix.initFromYRotation(angle);
objectMatrix = Matrix.initFromTranslation(-3.0, 0.0, 3.0) * objectMatrix;
setObjectMaterial(0.0, 1.0, 1.0, 1.0);
renderObject();
objectMatrix = Matrix.initFromYRotation(angle);
objectMatrix = Matrix.initFromTranslation(-3.0, 0.0, -3.0) * objectMatrix;
setObjectMaterial(0.0, 1.0, 0.0, 1.0);
renderObject();
flush();
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
public function setViewport(x:Int, y:Int, w:Int, h:Int)
{
gl.viewport(x, y, w, h);
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
public function setClearColor(r:Float, g:Float, b:Float, a:Float)
{
gl.clearColor(Math.floor(r * 255.0), Math.floor(g * 255.0), Math.floor(b * 255.0), Math.floor(a * 255.0));
}
public function setClearDepth(d:Float)
{
#if html5
gl.clearDepth(d);
#else
gl.clearDepthf(d);
#end
}
public function clear()
{
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
public function flush()
{
gl.flush();
}
// ------------------------------------------------------------------------------------------------------------------------------------------------------
public function setObjectVertex(vertex:Float32Array)
{
vertexBuffer = vertex;
gl.bindBuffer(gl.ARRAY_BUFFER, glVertexBuffer);
#if html5
gl.bufferData(gl.ARRAY_BUFFER, vertexBuffer, gl.STATIC_DRAW);
#else
gl.bufferData(gl.ARRAY_BUFFER, vertexBuffer.length * Float32Array.BYTES_PER_ELEMENT, DataPointer.fromArrayBufferView(vertexBuffer), gl.STATIC_DRAW);
#end
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
public function setObjectTexture(image:Image, texCoord:Float32Array)
{
gl.bindTexture(gl.TEXTURE_2D, glTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
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);
#if html5
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.width, image.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, image.data);
#else
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.width, image.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, DataPointer.fromArrayBufferView(image.data));
#end
gl.bindTexture(gl.TEXTURE_2D, null);
texCoordBuffer = texCoord;
gl.bindBuffer(gl.ARRAY_BUFFER, glTexCoordBuffer);
#if html5
gl.bufferData(gl.ARRAY_BUFFER, texCoordBuffer, gl.STATIC_DRAW);
#else
gl.bufferData(gl.ARRAY_BUFFER, texCoordBuffer.length * Float32Array.BYTES_PER_ELEMENT, DataPointer.fromArrayBufferView(texCoordBuffer), gl.STATIC_DRAW);
#end
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
public function setObjectMaterial(r:Float, g:Float, b:Float, a:Float)
{
materialBuffer = new Float32Array([r, g, b, a]);
}
public function renderObject()
{
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, glTexture);
gl.bindBuffer(gl.ARRAY_BUFFER, glVertexBuffer);
gl.vertexAttribPointer(glVertexAttribute, 3, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, glTexCoordBuffer);
gl.vertexAttribPointer(glTexCoordAttribute, 2, gl.FLOAT, false, 0, 0);
#if html5
gl.uniformMatrix4fv(glCameraMatrixUniform, false, cameraMatrix);
gl.uniformMatrix4fv(glObjectMatrixUniform, false, objectMatrix);
gl.uniform4fv(glObjectMaterialUniform, materialBuffer);
#else
gl.uniformMatrix4fv(glCameraMatrixUniform, 1, false, DataPointer.fromArrayBufferView(cameraMatrix));
gl.uniformMatrix4fv(glObjectMatrixUniform, 1, false, DataPointer.fromArrayBufferView(objectMatrix));
gl.uniform4fv(glObjectMaterialUniform, 1, DataPointer.fromArrayBufferView(materialBuffer));
#end
gl.uniform1i(glTextureUniform, 0);
gl.drawArrays(gl.TRIANGLES, 0, Math.round(vertexBuffer.length / 3));
}
}
It works with Neko on Windows, HTML5, and Android (finally!).
There’s still one thing: if I type ‘lime build html5’, and then double-click the generated ‘index.html’, the browser window contents remain blank. It does not happen if I type ‘lime test html5’, though.