我正在编写一个脚本,该脚本应该使用三角扇生成 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 比较陌生,很可能我误解了渲染和绘图数组的工作原理,但任何提示或见解将不胜感激。
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>