I'm trying to generate a random color everytime the code executes and passing it to the fragment shader(to draw a triangle). Reading other posts, I've decided that the most effective solutions seems to be:
- set a uniform variable in the fragment shader
- link it to a javascript variable
- write to the fragment shader with uniform4f providing the data
Trying to structure this, my snippet doesn't display the triangle but only the background. If I take away all the lines that deal with the color, the triangle appears again.
var can = document.getElementById('cont');
var gl = can.getContext('experimental-webgl');
gl.clearColor(0.0, 0.1, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
red = Math.random();
green = Math.random();
blue = Math.random();
alpha = Math.random();
var vertices = [-1,-1,1,-1,0,0.5];
var colorData = [red,green,blue,alpha];
//Create color buffer
var cbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,cbo);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(colorData),gl.STATIC_DRAW);
//Create vertex buffer
var vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,vbo);
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);
//Shaders
var vshaderCode = 'attribute vec2 pos;' + 'void main() {gl_Position = vec4 (pos,0.,1.);}';
var fshaderCode = 'precision mediump float;' + 'uniform vec4 uColor' + 'void main() {gl_FragColor = uColor;}';
function getShader(shaderSource,type) {
var shad = gl.createShader(type);
gl.shaderSource(shad,shaderSource);
gl.compileShader(shad);
return shad;
}
var vertexShader = getShader (vshaderCode,gl.VERTEX_SHADER);
var fragmentShader = getShader (fshaderCode,gl.FRAGMENT_SHADER);
//Create the program to link shaders
var prog = gl.createProgram();
gl.attachShader(prog,vertexShader);
gl.attachShader(prog,fragmentShader);
gl.linkProgram(prog);
var _position = gl.getAttribLocation(prog, "pos");
var u_ColorLocation = gl.getUniformLocation(prog, "uColor");
//Draw
gl.enableVertexAttribArray(_position);
gl.useProgram(prog);
gl.vertexAttribPointer(_position, 2, gl.FLOAT, false, 0,0);
gl.uniform4f(u_ColorLocation, colorData);
gl.drawArrays(gl.TRIANGLES, 0, 3);
The console says that gl.uniform4f(u_ColorLocation, colorData); wants five arguments. That point is not clear to me.
Even if I change that line to something like gl.uniform4f(u_colorLocation, 0, 0, 1, 1); the program doesn't link.
How do I pass then my values from javascript to the fragment on the gpu so that my triangle has only one color, driven by javascript variables?