0

我在这里读书。该initBuffers函数用于将我们需要绘制的对象的顶点存储到Buffer中。

var triangleVertexPositionBuffer;
var triangleVertexColorBuffer;
function initBuffers() {
    triangleVertexPositionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
    var vertices = [
         0.0, 1.0, 0.0,
        -1.0, -1.0, 0.0,
         1.0, -1.0, 0.0
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    triangleVertexPositionBuffer.itemSize = 3;
    triangleVertexPositionBuffer.numItems = 3;

    triangleVertexColorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
    var colors = [
        1.0, 0.0, 0.0, 1.0,
        0.0, 1.0, 0.0, 1.0,
        0.0, 0.0, 1.0, 1.0,
    ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
    triangleVertexColorBuffer.itemSize = 4;
    triangleVertexColorBuffer.numItems = 3;
}

现在这是为三角形定义的某种“形状”。现在,如果我想要所有类型和大小的形状,我必须triangleVertexPositionBuffer为每个形状保留一个缓冲区,对吧?它必须被初始化

每个新形状的新缓冲区对象是必须的吗?

我计划创建一个系统,可以在运行时使用按钮创建各种形状。那么这个问题有解决方案吗?如何在运行时创建新的缓冲区?是否有一个常见的现有解决方案?

如果我创建一个缓冲区对象数组,它会影响性能吗?

4

1 回答 1

2

WebGl 不在乎你是否每帧都调用 initBuffers。嗯,性能可能。

由于 javascript 是解释性语言,因此实际上并不存在运行时与编译时的概念。然而,一件先进的事情是,webgl 所需的着色器可以从“文字”字符串生成,在运行时生成,也可以从外部文件和 html 元素生成。

有可用的 webgl 基础设施,例如three.js,但我认为 Javascript 本身就是答案。

编辑:关于您在评论中的其他问题。OpenGL 和 WebGL 基本上按照您所描述的方式工作,但使用矩阵比仅仅为对象提供偏移更灵活。还有“索引缓冲区”,有助于在三角形之间共享顶点。

CubeCorners = [0,0,0,   0,0,1,  0,1,0,  0,1,1,  1,0,0,  1,0,1,  1,1,0,  1,1,1 ]; 
// There are 8 corners in a cube
//              0----1  <-- vertices (aka corners, with x=0)
//             /|   /|
//            4-+--5 |
//            | 2--|-3
//            |/   |/
//            6----7 
Triangles = [0,1,2, 1,3,2, 6,4,2, 2,4,0, 5,4,7, 4,6,7,  ... + 6 other triangles ];
//
TransScaleMatrix = [X,0,0,0, 0,Y,0,0, 0,0,Z,0, ox,oy,oz,1];
// scales the object and sets an internal origin (around which object is rotated)
RotMatrix = [rx,ry,rz, 0, ux,uy,yz,0, tx,ty,tz, 0, Ox,Oy,Oz,1];
// aligns the objects orthogonal up,right,toward vectors to r,u,t, (i.e. rotates it)
// and translates it to new origin O.
CameraOrientationMatrix = [  ... ... ];
// sets cameras lookat, up and right vector + position
PerspectiveMatrix = [ ... ...];
// transforms viewing frustums 6 planes left,right,top,bottom,near and far planes
// to unit cube. (objects outside this cube are clipped away)

使用这些数组,通常会渲染一个分层场景,其中顶点和对象被重用。On 不仅可以立方体放置在两个不同的位置,还可以放置到不同的比例和不同的方向。然后,一旦场景在“世界坐标”中建模,将相机放置到某个位置和某个方向,并应用透视矩阵将坐标转换为模拟屏幕坐标 x、y 和深度 z 的“剪辑空间”。

这些矩阵的美妙之处在于可以将它们中的每一个预乘到一个矩阵中来执行所有提到的事情。或者可以将这一操作链拆分为尽可能多的操作,这些操作要么在着色器中动态计算,要么在顶点缓冲区中预先计算。人们应该仔细考虑重用对象的最佳平衡,因为渲染的瓶颈通常是 drawElements/drawArray -calls 和状态更改 (gl.useProgram) 的数量,而不是每个对象的顶点数。

于 2012-10-13T07:26:43.753 回答