【问题标题】:How to draw various shapes of various sizes during runtime in WebGl?如何在WebGl运行时绘制各种大小的各种形状?
【发布时间】:2012-10-14 14:51:05
【问题描述】:

我正在阅读hereinitBuffers函数用于存储我们需要绘制到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,对吗?而且它必须被初始化正确

每个新形状都必须要有新的缓冲区对象吗?

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

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

【问题讨论】:

    标签: javascript opengl-es webgl


    【解决方案1】:

    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) 的数量,而不是每个对象的顶点数。

    【讨论】:

    • 嗨。我可以通过创建缓冲区对象的array 来实现我想要的,这些对象存储赋予它形状的对象的顶点。我制作了另一个array,它存储了相应对象的坐标。因此,当我需要绘制某些东西时,第二个array 将用于转换为坐标。将使用第一个阵列的形状。这是一种阻碍性能的方式吗?有没有更好的方法来做同样的事情?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多