为什么我的所有圈子都在 WebGL 中连接

问题描述 投票:0回答:1

我正在编写一个脚本,该脚本应该使用三角扇生成 10 个圆圈,并且它们具有随机生成的位置和颜色。据我所知,除了我的所有圈子都相互连接这一事实之外,它基本上按预期工作。看起来总有一个点从前一个圆连接到下一个圆。

这是我的JavaScript代码:

var gl;
var points;
var pi = 3.1415;
var rad = 2 * pi / 360;
var colors = [];
var vertices = [];

window.onload = function init() {
    var canvas = document.getElementById("gl-canvas");
    gl = WebGLUtils.setupWebGL(canvas);
    if (!gl) { alert("WebGL isn't available"); }
    for (i = 0; i < 10; i++) {
        var red = Math.random();
        var green = Math.random();
        var blue = Math.random();
        var r = Math.random() / 5 + .1;
        var xOff = Math.random() - .5;
        var yOff = Math.random() - .5;
        vertices.push(xOff);
        vertices.push(yOff);
        colors.push(red);
        colors.push(blue);
        colors.push(green);
        colors.push(1.0);
        for (var theta = 0; theta <= 360; theta += 1) {
            vertices.push(r*Math.cos(rad*theta) + xOff);
            vertices.push(r*Math.sin(rad*theta) + yOff);
            colors.push(red);
            colors.push(blue);
            colors.push(green);
            colors.push(1.0);
        }
    }

    //  Configure WebGL

    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(1.0, 1.0, 1.0, 1.0);
    
    //  Load shaders and initialize attribute buffers
    
    var program = initShaders(gl, "vertex-shader", "fragment-shader");
    gl.useProgram(program);
    
    // Load the data into the GPU
    
    var bufferId = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
    gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices), gl.STATIC_DRAW);  

    // Associate out shader variables with our data buffer
    
    var vPosition = gl.getAttribLocation(program, "vPosition");
    gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vPosition);
    
    var colorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
    
    var aColor = gl.getAttribLocation(program, "aColor");
    gl.vertexAttribPointer(aColor, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(aColor);
    
    render();
};

function render() {
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.drawArrays(gl.TRIANGLE_FAN, 0, 362);
    for (i = 362; i < 3620; i += 362) {
        gl.drawArrays(gl.TRIANGLE_FAN, i + 1, i + 362);
    }
}

我尝试更改起始顶点并手动设置它们,因为我认为圆可能有共享点,但情况似乎并非如此。我也尝试过通过手动选取顶点来制作两个圆圈,但由于某种原因,它制作了第三个圆圈,并且它们仍然相连。我对 WebGL 比较陌生,很可能我误解了渲染和绘图数组的工作原理,但任何提示或见解将不胜感激。

javascript graphics webgl
1个回答
0
投票

drawArrays
最后一个参数是索引的count而不是范围的末尾,当您实际需要渲染“从索引X开始的Y索引”时,您做了“从索引X到索引Y”。

此外,您应该使用

let
const
而不是
var
来避免使用未定义的变量(就像您对循环计数器所做的那样)并污染您的(和全局)范围。为了避免将来出现这些错误,您可以在脚本顶部使用
"use strict";
,或者使用
<script type="module">
将代码作为模块运行。

let gl;
let points;
const pi = Math.PI;
const rad = 2 * pi / 360;
const colors = [];
const vertices = [];

window.onload = function init() {
    const canvas = document.getElementById("gl-canvas");
    // setupWebGL
    gl = canvas.getContext('webgl');
    const br = canvas.getBoundingClientRect();
    gl.canvas.width = br.width;
    gl.canvas.height = br.height;
    
    if (!gl) { alert("WebGL isn't available"); }
    for (let i = 0; i < 10; i++) {
        const red = Math.random();
        const green = Math.random();
        const blue = Math.random();
        const r = Math.random() / 5 + .1;
        const xOff = Math.random() - .5;
        const yOff = Math.random() - .5;
        vertices.push(xOff);
        vertices.push(yOff);
        colors.push(red);
        colors.push(blue);
        colors.push(green);
        colors.push(1.0);
        for (let theta = 0; theta <= 360; theta += 1) {
            vertices.push(r*Math.cos(rad*theta) + xOff);
            vertices.push(r*Math.sin(rad*theta) + yOff);
            colors.push(red);
            colors.push(blue);
            colors.push(green);
            colors.push(1.0);
        }
    }

    //  Configure WebGL

    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(1.0, 1.0, 1.0, 1.0);
    
    //  Load shaders and initialize attribute buffers
    
    const program = gl.createProgram();
    // initShaders
    const vs = gl.createShader(gl.VERTEX_SHADER);
    const fs = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(vs, `
    attribute vec2 vPosition;
    attribute vec4 aColor;
    varying vec4 color;
    void main(){
        color=aColor;
        gl_Position=vec4(vPosition,0,1);
    }`);
    gl.shaderSource(fs, `
    precision mediump float;
    varying vec4 color;
    void main(){gl_FragColor=color;}
    `);
    gl.compileShader(vs);
    gl.compileShader(fs);
    gl.attachShader(program, vs);
    gl.attachShader(program, fs);
    gl.linkProgram(program);
    gl.useProgram(program);
    
    // Load the data into the GPU
    
    const bufferId = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
    gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices), gl.STATIC_DRAW);  

    // Associate out shader variables with our data buffer
    
    const vPosition = gl.getAttribLocation(program, "vPosition");
    gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vPosition);
    
    const colorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
    
    const aColor = gl.getAttribLocation(program, "aColor");
    gl.vertexAttribPointer(aColor, 4, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(aColor);
    
    render();
};

function render() {
    gl.clear(gl.COLOR_BUFFER_BIT);
    for (let i = 0; i < 3620; i+=362)
      gl.drawArrays(gl.TRIANGLE_FAN,i,362);
}
canvas {
  width: 100%;
  height: 100%;
  outline: 1px solid red;
}
<canvas id="gl-canvas"></canvas>

© www.soinside.com 2019 - 2024. All rights reserved.