在 webGL 中点击绘制点 [英] Draw points on click in webGL

查看:32
本文介绍了在 webGL 中点击绘制点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手,每次在鼠标点击时,我都试图在 WebGL 中绘制一个大小为 10 的点.在我点击的地方.但是由于一些逻辑错误,它的行为有点不同,它在点击时绘制了两个点.我也通过了黑色.它有时会绘制不同颜色的点(如绿色).

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)我怀疑它在每次点击时都会绘制两个点.2)如果我将 gl.vertexAttribPointer(program.vColor, 3, gl.FLOAT, false, 0, 0); 行中的数字 3 更改为 4它只绘制一个点,最初的一个点,并且在连续点击时不绘制任何点.请帮忙.

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.

推荐答案

您使用 2 个 index++ 调用将 index 增加了两次.改为这样做:

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 ++;

我怀疑你的意思是 gl.vertexAttribPointer(program.vColor, 4, gl.FLOAT, false, 0, 0); 而不是 gl.vertexAttribPointer(program.vColor, 3, gl.FLOAT, false, 0, 0); 因为你的颜色是 4 个元素:var color= [0.0, 0.0, 0.0, 1.0];

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];

此外,在分配新的 BufferData 时使用适当的提示.如果您的数据不是静态的(例如您在绘制"新点时如何更改缓冲区),请使用 gl.STREAM_DRAWgl.DYNAMIC_DRAW.使用错误的提示可能会导致 5-10 倍的性能损失.

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.

这篇关于在 webGL 中点击绘制点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆