Hi,
I’m trying to build a rendering layer on top of Lime, and quickly realized that meant I had to learn OpenGL. At first, the program worked on HTML5 and Android, but not Mac/Windows. The only issue it had was that it didn’t display my texture at all.
After about a day of debugging I realized that switching two seemingly unrelated lines in my shaders fixed Mac/Windows, and broke it on Android, and switching two more lines in my other shader fixed all platforms. Am I doing something strictly wrong in my code? The lines in question are 43 and 44, and 65 and 66, and this is the configuration that doesn’t work on Mac/Windows. Flip 43 and 44 to make it work on native platforms, and break Android. Then flip 65 and 66 to fix it on all platforms.
package app;
import lime.app.Application;
import lime.graphics.WebGLRenderContext;
import lime.graphics.RenderContext;
import lime.graphics.opengl.GLProgram;
import lime.graphics.opengl.GLBuffer;
import lime.graphics.opengl.GLTexture;
import lime.utils.Float32Array;
import lime.math.Matrix4;
import lime.graphics.Image;
import lime.utils.Assets;
class Main extends Application {
var gl:WebGLRenderContext;
var colorProgram:GLProgram;
var textureProgram:GLProgram;
var buffer:GLBuffer;
var buffer2:GLBuffer;
var vertexLocationIndex1:Int;
var vertexColorIndex1:Int;
var vertexLocationIndex2:Int;
var vertexTextureIndex2:Int;
var verticies:Array<Float> = [100,200,0.0,1.0,0.0, 200,200,0.0,1.0,0.0, 150,100,0.0,0.0,0.0];
var squareVerts:Array<Float> = [100,300,0,0, 200,300,1,0, 100,400,0,1, 200,400,1,1];
var width:Int;
var height:Int;
public function new() {
super();
}
public function init() {
var colorVertexShader =
"attribute vec2 aPos;
attribute vec3 aColor;
uniform mat4 uMatrix;
varying vec3 finalColor;
void main() {
finalColor = aColor;
gl_Position = uMatrix * vec4(aPos, 0.0, 1.0);
}";
var colorFragmentShader =
#if (!desktop || rpi)
"precision mediump float;" +
#end
"varying vec3 finalColor;
void main() {
gl_FragColor = vec4(finalColor,1.0);
}";
var textureVertexShader =
"attribute vec2 aPos;
attribute vec2 aTexCoord;
uniform mat4 uMatrix;
varying vec2 finalTex;
void main() {
finalTex = aTexCoord;
gl_Position = uMatrix * vec4(aPos, 0.0, 1.0);
}";
var textureFragmentShader =
#if (!desktop || rpi)
"precision mediump float;" +
#end
"varying vec2 finalTex;
uniform sampler2D uImage0;
void main() {
gl_FragColor = texture2D(uImage0, finalTex);
}";
//creating program just for colors
colorProgram = GLProgram.fromSources(gl, colorVertexShader, colorFragmentShader);
gl.useProgram(colorProgram);
//creating viewport matrix
var orthoMatrix = new Matrix4();
orthoMatrix.createOrtho(0, window.width, window.height, 0, -1000, 1000);
var matrixLocation = gl.getUniformLocation(colorProgram, "uMatrix");
gl.uniformMatrix4fv(matrixLocation, false, orthoMatrix);
//detailing input to shaders
vertexLocationIndex1 = gl.getAttribLocation(colorProgram, "aPos");
vertexColorIndex1 = gl.getAttribLocation(colorProgram, "aColor");
//creating program just for textures
textureProgram = GLProgram.fromSources(gl, textureVertexShader, textureFragmentShader);
gl.useProgram(textureProgram);
//viewport matrix again
matrixLocation = gl.getUniformLocation(textureProgram, "uMatrix");
gl.uniformMatrix4fv(matrixLocation, false, orthoMatrix);
//detailing input again
vertexLocationIndex2 = gl.getAttribLocation(colorProgram, "aPos");
//create our buffer
buffer = gl.createBuffer();
//basic gl setup
gl.clearColor (1, 1, 1, 1);
gl.blendFunc (gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.enable (gl.BLEND);
}
public function loadTexture(image:Image) {
vertexTextureIndex2 = gl.getAttribLocation(textureProgram, "aTexCoord");
width = image.width*7;
height = image.height*7;
squareVerts[4] = 100+width;
squareVerts[9] = 300+height;
squareVerts[12] = 100+width;
squareVerts[13] = 300+height;
var imageUniform = gl.getUniformLocation(textureProgram, "uImage0");
gl.uniform1i(imageUniform, 0);
var texture:GLTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
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 js
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image.src);
#else
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, image.buffer.width, image.buffer.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, image.data);
#end
}
override public function onPreloadComplete() {
var img:Image = Assets.getImage("assets/1.png");
loadTexture(img);
}
override public function onWindowCreate() {
gl = this.window.context.webgl;
this.init();
}
override public function render(context:RenderContext) {
if (gl == null) return;
//set view, and clear colors
gl.viewport(0,0,window.width,window.height);
gl.clear (gl.COLOR_BUFFER_BIT);
//update buffer data
verticies[10] += 1;
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticies), gl.DYNAMIC_DRAW);
//draw our triangle
gl.useProgram(colorProgram);
gl.enableVertexAttribArray(vertexLocationIndex1);
gl.enableVertexAttribArray(vertexColorIndex1);
gl.vertexAttribPointer(vertexLocationIndex1, 2, gl.FLOAT, false, 5*Float32Array.BYTES_PER_ELEMENT, 0);
gl.vertexAttribPointer(vertexColorIndex1, 3, gl.FLOAT, false, 5*Float32Array.BYTES_PER_ELEMENT, 2*Float32Array.BYTES_PER_ELEMENT);
gl.drawArrays(gl.TRIANGLE_STRIP,0,3);
gl.disableVertexAttribArray(vertexLocationIndex1);
gl.disableVertexAttribArray(vertexColorIndex1);
//draw a textured triangle
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(squareVerts), gl.DYNAMIC_DRAW);
gl.useProgram(textureProgram);
gl.enableVertexAttribArray(vertexLocationIndex2);
gl.enableVertexAttribArray(vertexTextureIndex2);
gl.vertexAttribPointer(vertexLocationIndex2, 2, gl.FLOAT, false, 4*Float32Array.BYTES_PER_ELEMENT, 0);
gl.vertexAttribPointer(vertexTextureIndex2, 2, gl.FLOAT, false, 4*Float32Array.BYTES_PER_ELEMENT, 2*Float32Array.BYTES_PER_ELEMENT);
gl.drawArrays(gl.TRIANGLE_STRIP,0,4);
gl.disableVertexAttribArray(vertexLocationIndex2);
gl.disableVertexAttribArray(vertexTextureIndex2);
}
}