I have a webgl program that displays some information on the screen. I have provided an example (not functional) which demonstrates the kind of program I’m trying to integrate with Threejs. Please note the example serves as a generic template, I will need to combine Threejs with other types webgl programs (much more complicated). What is the general approach? Can multiple program objects with different shaders be used?
var TEXT_VSHADER =
'attribute vec4 a_Position;\n' +
'attribute vec2 a_TexCoord;\n' +
'uniform mat4 u_ViewMatrix;\n' +
'uniform mat4 u_ModelMatrix;\n' +
'uniform mat4 u_ProjectionMatrix;\n' +
'varying vec2 v_TexCoord;\n' +
'void main() {\n' +
' gl_Position = a_Position * u_ViewMatrix;\n' +
'v_TexCoord = a_TexCoord;\n' +
'}\n';
var TEXT_FSHADER =
'#ifdef GL_ES\n' +
'precision mediump float;\n' +
'#endif\n' +
'uniform sampler2D u_Sampler;\n' +
'uniform vec4 u_FragColor;\n' +
'varying vec2 v_TexCoord;\n' +
'void main() {\n' +
' gl_FragColor = vec4(u_FragColor.rgb , u_FragColor.a);\n' +
'}\n';
var canvas;
var textCtx;
function main() {
var elementArray = ['123', '246', '369'];
var vertices = new Float32Array([0.0, 0.5, 12.0, 12.5, 40.0, 45.5]);
var vshader;
var fshader;
var compiled;
var message;
var textProgram;
var linked;
var a_Position;
var u_FragColor;
var u_ViewMatrix;
var u_ProjectionMatrix;
var viewMatrix;
var vertexBuffer;
var textBufferInfo;
canvas = document.getElementById('webgl');
var gl = WebGLDebugUtils.makeDebugContext(canvas.getContext("webgl"));
textCtx = document.createElement("canvas").getContext("2d");
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
vshader = gl.createShader(gl.VERTEX_SHADER);
fshader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vshader, TEXT_VSHADER);
gl.shaderSource(fshader, TEXT_FSHADER);
gl.compileShader(vshader);
compiled = gl.getShaderParameter(vshader, gl.COMPILE_STATUS);
if (!compiled) {
var error = gl.getShaderInfoLog(vshader);
console.log('Failed to compile shader: ' + error);
gl.deleteShader(vshader);
return null;
}
message = gl.getShaderInfoLog(vshader);
gl.compileShader(fshader);
compiled = gl.getShaderParameter(fshader, gl.COMPILE_STATUS);
if (!compiled) {
var error = gl.getShaderInfoLog(fshader);
console.log('Failed to compile shader: ' + error);
gl.deleteShader(fshader);
return null;
}
message = gl.getShaderInfoLog(fshader);
textProgram = gl.createProgram();
if (textProgram == null) {
}
gl.attachShader(textProgram, vshader);
gl.attachShader(textProgram, fshader);
gl.linkProgram(textProgram);
linked = gl.getProgramParameter(textProgram, gl.LINK_STATUS);
if (!linked) {
var error = gl.getProgramInfoLog(textProgram);
console.log('Failed to link program: ' + error);
gl.deleteProgram(textProgram);
gl.deleteShader(fshader);
gl.deleteShader(vshader);
}
gl.useProgram(textProgram);
gl.program = textProgram;
viewMatrix = new Matrix4();
viewMatrix.setLookAt(0, 0, 0, 0, -1, 0, 0, 1, 0);
// ' u_FragColor = texture2D(u_Sampler, v_TexCoord);\n' +
u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (u_FragColor == null) {
console.log('Fail to get the storage location of u_FragColor')
return;
}
u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix')
if (u_ViewMatrix == null) {
console.log('Fail to get the storage location of u_ViewMatrix')
return;
}
gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
console.log('Failed to create vertex buffer object');
return (-1);
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
console.log('Fail to get the storage location of a_Position')
return;
}
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);
var textTextures = [
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9"
].map(function (elementArray) {
var textCanvas = makeTextCanvas(elementArray, 10, 26);
var textWidth = textCanvas.width;
var textHeight = textCanvas.height;
var elementIDtexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, elementIDtexture);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textCanvas);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
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);
return {
texture: elementIDtexture,
width: textWidth,
height: textHeight,
};
});
// gl.resizeCanvasToDisplaySize(gl.canvas);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.enable(gl.CULL_FACE);
gl.enable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
gl.depthMask(true);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// gl.drawArrays(gl.TRIANGLES, 0, 3);
gl.drawElements(gl.TRIANGLES, 3, gl.UNSIGNED_SHORT, 0);
}
function makeTextCanvas(text, width, height) {
textCtx.canvas.width = width;
textCtx.canvas.height = height;
textCtx.font = "20px monospace";
textCtx.textAlign = "center";
textCtx.textBaseline = "middle";
textCtx.fillStyle = "black";
textCtx.clearRect(0, 0, textCtx.canvas.width, textCtx.canvas.height);
textCtx.fillText(text, width / 2, height / 2);
return textCtx.canvas;
}
main()