Reputation: 800
I am a newbie, I am trying to draw a point of size 10, in WebGL, every time on MouseClick. At the point where I click. But Due to some logical error, it behaves a bit differently, it draws two points on click. Also I pass the colour black. It sometimes draws point of different colour(like green).
<html>
<head>
<meta charset="utf-8">
<script id="vertex" type="x-shader">
attribute vec2 aVertexPosition;
attribute vec4 vColor;
varying vec4 fColor;
void main() {
gl_Position = vec4(aVertexPosition, 0.0, 1.0);
gl_PointSize = 10.0;
fColor = vColor;
}
</script>
<script id="fragment" type="x-shader">
#ifdef GL_ES
precision highp float;
#endif
varying vec4 fColor;
void main() {
gl_FragColor = fColor;
}
</script>
<script type="text/javascript">
var points = [];
var index = 0;
function init1(){
var canvas = document.getElementById("mycanvas");
gl = canvas.getContext("experimental-webgl");
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
var v = document.getElementById("vertex").firstChild.nodeValue;
var f = document.getElementById("fragment").firstChild.nodeValue;
var vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, v);
gl.compileShader(vs);
var fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fs, f);
gl.compileShader(fs);
var program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
gl.useProgram(program);
color= [0.0, 0.0, 0.0, 1.0];
var vbuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
gl.bufferData(gl.ARRAY_BUFFER, 8*200, gl.STATIC_DRAW);
program.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
gl.enableVertexAttribArray(program.aVertexPosition);
gl.vertexAttribPointer(program.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
var cBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
gl.bufferData(gl.ARRAY_BUFFER, 16*200, gl.STATIC_DRAW);
program.vColor = gl.getAttribLocation(program, "vColor");
gl.enableVertexAttribArray(program.vColor);
gl.vertexAttribPointer(program.vColor, 3, gl.FLOAT, false, 0, 0);
var flattenedVertices = [];
var idx = 0;
canvas.addEventListener("mousedown", function(event){
x=2*event.clientX/canvas.width-1;
y=2*(canvas.height-event.clientY)/canvas.height-1;
var pts = [x, y];
points.push(pts);
gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 8*index++, new Float32Array(pts));
gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 16*index++, new Float32Array(color));
});
render();
}
function render(){
gl.clear( gl.COLOR_BUFFER_BIT );
gl.drawArrays(gl.POINTS, 0, index);
window.requestAnimationFrame(render);
}
</script>
</head>
<body onload="init1()">
<canvas id="mycanvas" width="800" height="500"></canvas>
</body>
Above is my code, if anybody can help me fine tune it to work exactly what I want. There are a few problems I face,
1)I suspect that it draws two points on every click.
2)If I change the number 3 to 4 in line gl.vertexAttribPointer(program.vColor, 3, gl.FLOAT, false, 0, 0);
it only draws one point, the initial one and does not draws any point on successive clicks.
Kindly help.
Upvotes: 2
Views: 3811
Reputation: 3364
You are incrementing index
twice with 2 index++
calls. Do it like this instead:
var i = index;
gl.bindBuffer(gl.ARRAY_BUFFER, vbuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 8*i, new Float32Array(pts));
gl.bindBuffer(gl.ARRAY_BUFFER, cBuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 16*i, new Float32Array(color));
index ++;
And I suspect you meant gl.vertexAttribPointer(program.vColor, 4, gl.FLOAT, false, 0, 0);
rather than gl.vertexAttribPointer(program.vColor, 3, gl.FLOAT, false, 0, 0);
Since your color is 4 elems: var color= [0.0, 0.0, 0.0, 1.0];
Also, use appropriate hint when allocating a new BufferData. If your data is not static (like how you are changing the buffer when "drawing" a new point) use gl.STREAM_DRAW
or gl.DYNAMIC_DRAW
. Using wrong hint can have a 5-10x performance loss.
Upvotes: 2