javascript 我可以用两个独立的vshadders和程序在Webgl中创建两个独立的对象吗?

2izufjch  于 2023-05-05  发布在  Java
关注(0)|答案(1)|浏览(163)

我试图在webgl中创建一个圆圈,然后让用户单击3次,在他们使用LINE_LOOP单击的位置出现一个三角形。我创建了2个vshader和2个程序,但点击3次后,圆圈消失了。我试着在主函数中声明这两个程序,然后在click函数中为三角形做所有的缓冲区。在click函数中,我找到用户单击的x,y位置,然后将这些值推送到一个顶点数组中,我试图使用它来输出三角形。我很确定这个函数的逻辑基本上是正确的,因为我在过去创建的另一个代码中有一个类似的函数。我希望用户看到整个时间的圆圈,然后看到一个三角形创建后,他们点击3次点击。
下面是着色器的声明

var circlevertices_length;
        var gl = null;
        var program = 0;
        var program2 = 0;
        var divisions = 0;
        var tcount = 0;
        var tmax = 3;
    
        var trivert = [
            0.0, 0.0, 0.0,
            0.0, 0.0, 0.0,
            0.0, 0.0, 0.0
            ];

        var VSHADER_SOURCE = `
       precision highp float;
           attribute vec3 coordinates;

        void main(){
               gl_Position = vec4(coordinates, 1.0);
        }
        `;

        var VSHADER_SOURCE_TRIANGLE = `
             precision highp float;
             attribute vec3 coordinates2;

        void main() {
             gl_Position = vec4(coordinates2, 1.0);
         }
         `;

        var FSHADER_SOURCE = `
        precision highp float;
        uniform vec4 color;

        void main(){
         gl_FragColor = color;
        }

以下是我的主要功能:

function main(){
    var canvas = document.getElementById("MyCircle");
    gl = getWebGLContext(canvas);
    
    program1 = createProgram(gl, VSHADER_SOURCE, FSHADER_SOURCE);
    program2 = createProgram(gl, VSHADER_SOURCE_TRIANGLE, FSHADER_SOURCE);

    gl.useProgram(program);
    
    
    //register event handler to be called on a mouse click
        canvas.onmousedown = function(ev){
            click(ev, gl, canvas)
        };

    render();   
    
    return;
     }

下面是我创建三角形所做的一切:

function click(ev, gl, canvas){
    gl.useProgram(program2);

    var x = ev.clientX;
    var y = ev.clientY;
    var rect = ev.target.getBoundingClientRect();

    if(tcount < tmax){
        x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);
        y = (canvas.height/2 - (y-rect.top))/(canvas.height/2);
        z = 0.0;

        trivert[tcount * 3 + 0] = x;
        trivert[tcount * 3 + 1] = y;
        trivert[tcount * 3 + 2] = z;

        tcount++;
    }

    if(tcount == tmax){
        alert(trivert[0],trivert[1],trivert[2])
        var buff = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, buff);
        gl.bufferData(gl.ARRAY_BUFFER, trivert, gl.STATIC_DRAW);

        const position_loc = gl.getAttribLocation(program2, "coordinates2");
        gl.enableVertexAttribArray(position_loc);
        gl.vertexAttribPointer(position_loc, 3, gl.FLOAT, false, 0, 0);

        const color_loc2 = gl.getUniformLocation(program2, 'color');
        gl.uniform4f(color_loc2, 1.0, 1.0, 1.0, 1.0);

        gl.drawArrays(gl.LINE_LOOP, 0, tcount);

        gl.disableVertexAttribArray(position_loc);
        tcount = 0;
    }
    }
qvsjd97n

qvsjd97n1#

您不需要两个不同的程序来完成此操作,而是需要两个不同的缓冲区。每次都要画圆。就像这样:

function paint() {
  gl.useProgram(prg)
  const position_loc = gl.getAttribLocation(prg, "coordinates")
  gl.enableVertexAttribArray(position_loc);
  gl.vertexAttribPointer(position_loc, 3, gl.FLOAT, false, 0, 0);

  gl.bindBuffer(gl.ARRAY_BUFFER, circleBuffer)
  gl.drawArrays(gl.LINE_LOOP, 0, circleVerticesCount)

  gl.bindBuffer(gl.ARRAY_BUFFER, triangleBuffer)
  gl.dataBuffer(gl.ARRAY_BUFFER, trivert, gl.DYNAMIC_DRAW)
  gl.drawArrays(gl.LINE_LOOP, 0, tCount)
}

相关问题