如何在javascript中阅读webgl GL.bufferData

时间:2015-08-10 13:55:28

标签: javascript webgl

我想在javascript中读回存储在GL.bufferData数组中的数据。

这是我的代码

var TRIANGLE_VERTEX = geometryNode["triangle_buffer"]; GL.bindBuffer(GL.ARRAY_BUFFER, TRIANGLE_VERTEX); GL.bufferData(GL.ARRAY_BUFFER,new Float32Array(vertices),GL.STATIC_DRAW);

是否可以在webgl中读回GPU中的缓冲区数据? 如果可能的话,请用示例代码向我解释。

如何在运行时知道webgl中Gpu的内存大小(已填充和空闲)以及如何在webgl中调试GPU中的着色器代码和数据。

1 个答案:

答案 0 :(得分:2)

直接在WebGL1中读取数据是不可能的。 (参见下面的WebGL2)。这是WebGL所基于的OpenGL ES 2.0的限制。

有一些解决方法:

  1. 您可以尝试将该数据渲染为纹理,然后使用readPixels来读取数据。

    您必须在着色器中将数据编码为字节,因为WebGL中的readPixels只能读取字节

  2. 您可以自己包装WebGL以存储数据,如

    var buffers = {};
    var nextId = 1;
    var targets = {};
    
    function copyBuffer(buffer) {
       // make a Uint8 view of buffer in case it's not already
       var view = new Uint8Buffer(buffer.buffer); 
       // now copy it
       return new UintBuffer(view);
    }
    
    gl.bindBuffer = function(oldBindBufferFn) {
      return function(target, buffer) {
        targets[target] = new Uint8Buffer(buffer.buffer);
        oldBindBufferFn(target, buffer);
      };
    }(gl.bindBuffer.bind(gl));
    
    gl.bufferData = function(oldBufferDataFn) {
       return function(target, data, hint) {
         var buffer = targets[target];
         if (!buffer.id) {
           buffer.id = nextId++;
         }
         buffers[buffer.id] = copyBuffer(data);
         oldBufferDataFn(target, data, hint);
       };
    }(gl.bufferData.bind(gl)));
    

    现在您可以使用

    获取数据
    data = buffers[someBuffer.id];
    

    这可能是the WebGL Inspector所做的事情

    请注意,上面的代码存在一些问题。一,它不检查错误。检查错误会使速度变慢但如果代码生成错误,则不检查错误会导致错误的结果。一个简单的例子

    gl.bufferData(someBuffer, someData, 123456);
    

    这会产生INVALID_ENUM错误而不会更新someBuffer中的数据,但我们的代码没有检查错误,因此它会将someData放入buffers并且如果您读取该数据,则与WebGL中的数据不匹配。

    注意上面的代码是伪代码。例如,我没有为gl.bufferSubData提供包装器。

  3. WebGL2

    在WebGL2中有一个函数gl.getBufferSubData,它允许您读取缓冲区的内容。请注意,WebGL2即使基于OpenGL ES 3.0也不支持gl.mapBuffer,因为没有高效且安全的方式来公开该功能。