无法通过沿轴旋转在 WebGL 中创建 3D Koch
Unable to create 3D Koch in WebGL with rotation along axis
最近我选择了 WebGL 来将我的 C++ 游戏移植到 JS。我成功地为 3D Koch 曲线创建并旋转了基础四面体。再一次,由于 WebGL 中的着色器,我无法翻译代码。我解决这个问题的方法与在 OpenGL 中一样,计算新的几何点,然后,一旦形成三角形,我就绘制它。这在 WebGL 中似乎不起作用。
这是代码...
https://github.com/Horopter/koch-snowflake/blob/master/koch/koch3d.cpp
在我成功之前,这是 WebGL 的代码。具体来说,我需要翻译功能方面的帮助...
所以这是 index.html
//compiled by Santosh. Title : main.js
var gl;
function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch (e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.viewport(0, 0, canvas.width, canvas.height);
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var shaderProgram;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
}
var mvMatrix = mat4.create();
var mvMatrixStack = [];
var pMatrix = mat4.create();
function mvPushMatrix() {
var copy = mat4.create();
mat4.set(mvMatrix, copy);
mvMatrixStack.push(copy);
}
function mvPopMatrix() {
if (mvMatrixStack.length == 0) {
throw "Invalid popMatrix!";
}
mvMatrix = mvMatrixStack.pop();
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
var pyramidVertexPositionBuffer;
var pyramidVertexColorBuffer;
function initBuffers() {
pyramidVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer);
var vertices = [
// Front face
1.0, 1.0, 1.0,//a
1.0, -1.0, -1.0,//b
-1.0, 1.0, -1.0,//c
// Right face
1.0, -1.0, -1.0,//b
-1.0, 1.0, -1.0,//c
-1.0, -1.0, 1.0,//d
// Left face
1.0, 1.0, 1.0,//a
-1.0, -1.0, 1.0,//d
1.0, -1.0, -1.0,//b
// Back face
-1.0, 1.0, -1.0,//c
-1.0, -1.0, 1.0,//d
1.0, 1.0, 1.0//a
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
pyramidVertexPositionBuffer.itemSize = 3;
pyramidVertexPositionBuffer.numItems = 12;
pyramidVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer);
var colors = [
// Front face
1.0, 0.0, 0.0, 1.0,//a
0.0, 1.0, 0.0, 1.0,//b
0.0, 0.0, 1.0, 1.0,//c
// Right face
0.0, 1.0, 0.0, 1.0,//b
0.0, 0.0, 1.0, 1.0,//c
1.0, 1.0, 1.0, 1.0,//d
// Left face
1.0, 0.0, 0.0, 1.0,//a
1.0, 1.0, 1.0, 1.0,//d
0.0, 1.0, 0.0, 1.0,//b
// Back face
0.0, 0.0, 1.0, 1.0,//c
1.0, 1.0, 1.0, 1.0,//d
1.0, 0.0, 0.0, 1.0,//a
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
pyramidVertexColorBuffer.itemSize = 4;
pyramidVertexColorBuffer.numItems = 12;
}
var rPyramid = 0;
function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0.0, 2.0, -8.0]);
mat4.scale(mvMatrix,[0.7,0.7,0.7]);
mvPushMatrix();
mat4.rotate(mvMatrix, degToRad(rPyramid), [0, 1, 0]);
gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, pyramidVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, pyramidVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES, 0, pyramidVertexPositionBuffer.numItems);
mvPopMatrix();
}
var lastTime = 0;
function animate() {
var timeNow = new Date().getTime();
if (lastTime != 0) {
var elapsed = timeNow - lastTime;
rPyramid += (90 * elapsed) / 1000.0;
}
lastTime = timeNow;
}
function tick() {
requestAnimationFrame(tick);
drawScene();
animate();
}
function webGLStart() {
var canvas = document.getElementById("gameCanvas");
initGL(canvas);
initShaders()
initBuffers();
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.enable(gl.DEPTH_TEST);
tick();
}
webGLStart();
<script src="http://learningwebgl.com/lessons/lesson01/glMatrix-0.9.5.min.js"></script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec4 vColor;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
}
</script>
<canvas id="gameCanvas" style="border: none;" width="800" height="500"> </canvas>
像 OpenGL ES 2.0 及更高版本这样的 WebGL 不再具有固定的功能管道。换句话说,它不支持一次指定 1 个顶点的 glVertex
、glColor
等。原因在于现代 GPU 效率极低且速度极慢。当然,在您的 PC 上,它的速度足以让东西正常工作,但它甚至远不及 GPU 的工作方式,因此 Khronos,设计 OpenGL 的人明智地决定删除这些东西,特别是对于 OpenGL ES,其中 ES = 嵌入式系统 = 智能手机因为超级低效的方法会耗尽用户的电池,而且因为它实际上不是 GPU 工作,所以这也意味着用代码膨胀驱动程序以支持旧的低效方法。
您现在的做法是创建缓冲区(您在上面的示例中所做的)并将数据放入其中。通常,数据只需要创建一次。例如,如果您正在绘制一个金字塔,为什么要在每一帧中指定每个顶点,而您只需指定一次并在之后每次都重复使用它们。效率更高。
因此,您基本上需要将旧的已弃用的 OpenGL C++ 代码重组为新的现代 OpenGL ES 代码。一个简单的方法可能是制作一些缓冲区创建者助手。例子
function OldOpenGLVertexHelper() {
var colors = [];
var vertices = [];
var normals = [];
var currentColor = [1, 1, 1, 1];
var currentNormal = [0, 0, 0];
var mode;
this.color3f = function(r, g, b) {
currentColor = [r, g, b, 1];
}
this.color4f = function(r, g, b, a) {
currentColor = [r, g, b, a];
}
this.color3fv = function(rgb) {
currentColor = rgb.concat(1);
}
this.color4fv = function(rgba) {
currentColor = rgba.slice();
}
this.normal3f = function(x, y, z) {
currentNormal = [x, y, z];
}
this.normal3fv = function(xyz) {
currentNormal = xyz.slice();
}
var vertex3f = function(x, y, z) {
colors.push(currentColor[0],
currentColor[1],
currentColor[2],
currentColor[3]);
normals.push(currentNormal[0],
currentNormal[1],
currentNormal[2]);
vertices.push(x, y, z);
}
this.vertex3f = vertex3f;
this.vertex3fv = function(xyz) {
vertex3f(xyz[0], xyz[1], xyz[2]);
};
this.end = function() {
return {
vertices: new Float32Array(vertices),
normals: new Float32Array(normals),
colors: new Float32Array(colors),
mode: mode,
};
});
this.begin = function(m) {
mode = m;
colors = [];
normals = [];
vertices = [];,
};
}
现在你可以做这样的事情了
var oldGL = new OldOpenGLVertexHelper();
oldGL.color3f(0.0,0.0,0.0);
oldGL.begin(gl.LINES);
oldGL.vertex3fv(a);
oldGL.vertex3fv(b);
oldGL.vertex3fv(b);
oldGL.vertex3fv(c);
oldGL.vertex3fv(c);
oldGL.vertex3fv(d);
oldGL.vertex3fv(d);
oldGL.vertex3fv(a);
oldGL.vertex3fv(a);
oldGL.vertex3fv(c);
oldGL.vertex3fv(b);
oldGL.vertex3fv(d);
var buffers = oldGL.end();
现在您可以使用 buffers.vertices
、buffers.colors
、buffers.normals
等访问创建的缓冲区
您如何处理这些缓冲区由您决定。理想情况下,如果他们不更改每一帧,您将在初始时间创建它们并重新使用它们。查看您在上面发布的代码,它为金字塔创建了一组缓冲区
否则,如果您想执行旧 OpenGL 所做的事情,您可以在那个时候立即绘制
gl.bindBuffer(gl.ARRAY_BUFFER, somebufferForPositions);
gl.bufferData(gl.ARRAY_BUFFER, buffers.vertices, gl.DYNAMIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, somebufferForColors);
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.colors, gl.DYNAMIC_DRAW);
// set your attributes
...
gl.drawArrays(buffers.mode, 0, buffers.vertices.length / 3);
// NOTE: you'll need to change that divided by 3 if buffers.mode
// is lines (2) or points (1)
这基本上就是旧的 OpenGL 驱动程序为您做的事情
我不知道这是否足以帮助您。由于您是 WebGL 的新手,我建议您阅读更多教程。 For drawing multiple objects maybe this will help.
最近我选择了 WebGL 来将我的 C++ 游戏移植到 JS。我成功地为 3D Koch 曲线创建并旋转了基础四面体。再一次,由于 WebGL 中的着色器,我无法翻译代码。我解决这个问题的方法与在 OpenGL 中一样,计算新的几何点,然后,一旦形成三角形,我就绘制它。这在 WebGL 中似乎不起作用。 这是代码... https://github.com/Horopter/koch-snowflake/blob/master/koch/koch3d.cpp 在我成功之前,这是 WebGL 的代码。具体来说,我需要翻译功能方面的帮助...
所以这是 index.html
//compiled by Santosh. Title : main.js
var gl;
function initGL(canvas) {
try {
gl = canvas.getContext("experimental-webgl");
gl.viewportWidth = canvas.width;
gl.viewportHeight = canvas.height;
} catch (e) {
}
if (!gl) {
alert("Could not initialise WebGL, sorry :-(");
}
gl.enable(gl.DEPTH_TEST);
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.viewport(0, 0, canvas.width, canvas.height);
}
function getShader(gl, id) {
var shaderScript = document.getElementById(id);
if (!shaderScript) {
return null;
}
var str = "";
var k = shaderScript.firstChild;
while (k) {
if (k.nodeType == 3) {
str += k.textContent;
}
k = k.nextSibling;
}
var shader;
if (shaderScript.type == "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type == "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
var shaderProgram;
function initShaders() {
var fragmentShader = getShader(gl, "shader-fs");
var vertexShader = getShader(gl, "shader-vs");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Could not initialise shaders");
}
gl.useProgram(shaderProgram);
shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
}
var mvMatrix = mat4.create();
var mvMatrixStack = [];
var pMatrix = mat4.create();
function mvPushMatrix() {
var copy = mat4.create();
mat4.set(mvMatrix, copy);
mvMatrixStack.push(copy);
}
function mvPopMatrix() {
if (mvMatrixStack.length == 0) {
throw "Invalid popMatrix!";
}
mvMatrix = mvMatrixStack.pop();
}
function setMatrixUniforms() {
gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
var pyramidVertexPositionBuffer;
var pyramidVertexColorBuffer;
function initBuffers() {
pyramidVertexPositionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer);
var vertices = [
// Front face
1.0, 1.0, 1.0,//a
1.0, -1.0, -1.0,//b
-1.0, 1.0, -1.0,//c
// Right face
1.0, -1.0, -1.0,//b
-1.0, 1.0, -1.0,//c
-1.0, -1.0, 1.0,//d
// Left face
1.0, 1.0, 1.0,//a
-1.0, -1.0, 1.0,//d
1.0, -1.0, -1.0,//b
// Back face
-1.0, 1.0, -1.0,//c
-1.0, -1.0, 1.0,//d
1.0, 1.0, 1.0//a
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
pyramidVertexPositionBuffer.itemSize = 3;
pyramidVertexPositionBuffer.numItems = 12;
pyramidVertexColorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer);
var colors = [
// Front face
1.0, 0.0, 0.0, 1.0,//a
0.0, 1.0, 0.0, 1.0,//b
0.0, 0.0, 1.0, 1.0,//c
// Right face
0.0, 1.0, 0.0, 1.0,//b
0.0, 0.0, 1.0, 1.0,//c
1.0, 1.0, 1.0, 1.0,//d
// Left face
1.0, 0.0, 0.0, 1.0,//a
1.0, 1.0, 1.0, 1.0,//d
0.0, 1.0, 0.0, 1.0,//b
// Back face
0.0, 0.0, 1.0, 1.0,//c
1.0, 1.0, 1.0, 1.0,//d
1.0, 0.0, 0.0, 1.0,//a
];
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
pyramidVertexColorBuffer.itemSize = 4;
pyramidVertexColorBuffer.numItems = 12;
}
var rPyramid = 0;
function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);
mat4.identity(mvMatrix);
mat4.translate(mvMatrix, [0.0, 2.0, -8.0]);
mat4.scale(mvMatrix,[0.7,0.7,0.7]);
mvPushMatrix();
mat4.rotate(mvMatrix, degToRad(rPyramid), [0, 1, 0]);
gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer);
gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, pyramidVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer);
gl.vertexAttribPointer(shaderProgram.vertexColorAttribute, pyramidVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
setMatrixUniforms();
gl.drawArrays(gl.TRIANGLES, 0, pyramidVertexPositionBuffer.numItems);
mvPopMatrix();
}
var lastTime = 0;
function animate() {
var timeNow = new Date().getTime();
if (lastTime != 0) {
var elapsed = timeNow - lastTime;
rPyramid += (90 * elapsed) / 1000.0;
}
lastTime = timeNow;
}
function tick() {
requestAnimationFrame(tick);
drawScene();
animate();
}
function webGLStart() {
var canvas = document.getElementById("gameCanvas");
initGL(canvas);
initShaders()
initBuffers();
gl.clearColor(0.0, 0.0, 0.0, 0.0);
gl.enable(gl.DEPTH_TEST);
tick();
}
webGLStart();
<script src="http://learningwebgl.com/lessons/lesson01/glMatrix-0.9.5.min.js"></script>
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec3 aVertexPosition;
attribute vec4 aVertexColor;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
varying vec4 vColor;
void main(void) {
gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
vColor = aVertexColor;
}
</script>
<canvas id="gameCanvas" style="border: none;" width="800" height="500"> </canvas>
像 OpenGL ES 2.0 及更高版本这样的 WebGL 不再具有固定的功能管道。换句话说,它不支持一次指定 1 个顶点的 glVertex
、glColor
等。原因在于现代 GPU 效率极低且速度极慢。当然,在您的 PC 上,它的速度足以让东西正常工作,但它甚至远不及 GPU 的工作方式,因此 Khronos,设计 OpenGL 的人明智地决定删除这些东西,特别是对于 OpenGL ES,其中 ES = 嵌入式系统 = 智能手机因为超级低效的方法会耗尽用户的电池,而且因为它实际上不是 GPU 工作,所以这也意味着用代码膨胀驱动程序以支持旧的低效方法。
您现在的做法是创建缓冲区(您在上面的示例中所做的)并将数据放入其中。通常,数据只需要创建一次。例如,如果您正在绘制一个金字塔,为什么要在每一帧中指定每个顶点,而您只需指定一次并在之后每次都重复使用它们。效率更高。
因此,您基本上需要将旧的已弃用的 OpenGL C++ 代码重组为新的现代 OpenGL ES 代码。一个简单的方法可能是制作一些缓冲区创建者助手。例子
function OldOpenGLVertexHelper() {
var colors = [];
var vertices = [];
var normals = [];
var currentColor = [1, 1, 1, 1];
var currentNormal = [0, 0, 0];
var mode;
this.color3f = function(r, g, b) {
currentColor = [r, g, b, 1];
}
this.color4f = function(r, g, b, a) {
currentColor = [r, g, b, a];
}
this.color3fv = function(rgb) {
currentColor = rgb.concat(1);
}
this.color4fv = function(rgba) {
currentColor = rgba.slice();
}
this.normal3f = function(x, y, z) {
currentNormal = [x, y, z];
}
this.normal3fv = function(xyz) {
currentNormal = xyz.slice();
}
var vertex3f = function(x, y, z) {
colors.push(currentColor[0],
currentColor[1],
currentColor[2],
currentColor[3]);
normals.push(currentNormal[0],
currentNormal[1],
currentNormal[2]);
vertices.push(x, y, z);
}
this.vertex3f = vertex3f;
this.vertex3fv = function(xyz) {
vertex3f(xyz[0], xyz[1], xyz[2]);
};
this.end = function() {
return {
vertices: new Float32Array(vertices),
normals: new Float32Array(normals),
colors: new Float32Array(colors),
mode: mode,
};
});
this.begin = function(m) {
mode = m;
colors = [];
normals = [];
vertices = [];,
};
}
现在你可以做这样的事情了
var oldGL = new OldOpenGLVertexHelper();
oldGL.color3f(0.0,0.0,0.0);
oldGL.begin(gl.LINES);
oldGL.vertex3fv(a);
oldGL.vertex3fv(b);
oldGL.vertex3fv(b);
oldGL.vertex3fv(c);
oldGL.vertex3fv(c);
oldGL.vertex3fv(d);
oldGL.vertex3fv(d);
oldGL.vertex3fv(a);
oldGL.vertex3fv(a);
oldGL.vertex3fv(c);
oldGL.vertex3fv(b);
oldGL.vertex3fv(d);
var buffers = oldGL.end();
现在您可以使用 buffers.vertices
、buffers.colors
、buffers.normals
等访问创建的缓冲区
您如何处理这些缓冲区由您决定。理想情况下,如果他们不更改每一帧,您将在初始时间创建它们并重新使用它们。查看您在上面发布的代码,它为金字塔创建了一组缓冲区
否则,如果您想执行旧 OpenGL 所做的事情,您可以在那个时候立即绘制
gl.bindBuffer(gl.ARRAY_BUFFER, somebufferForPositions);
gl.bufferData(gl.ARRAY_BUFFER, buffers.vertices, gl.DYNAMIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, somebufferForColors);
gl.bindBuffer(gl.ARRAY_BUFFER, buffers.colors, gl.DYNAMIC_DRAW);
// set your attributes
...
gl.drawArrays(buffers.mode, 0, buffers.vertices.length / 3);
// NOTE: you'll need to change that divided by 3 if buffers.mode
// is lines (2) or points (1)
这基本上就是旧的 OpenGL 驱动程序为您做的事情
我不知道这是否足以帮助您。由于您是 WebGL 的新手,我建议您阅读更多教程。 For drawing multiple objects maybe this will help.