如何阅读 javascript 中的 webgl GL.bufferData
How to read webgl GL.bufferData in javascript
我想读回 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中的bufferdata?
如果可能,请用示例代码向我解释一下。
如何在运行时知道webgl中Gpu的内存大小(已满和空闲)以及如何在webgl中调试GPU中的着色器代码和数据。
无法直接在 WebGL1 中读回数据。 (请参阅下面的 WebGL2)。这是基于 WebGL 的 OpenGL ES 2.0 的限制。
有一些解决方法:
您可以尝试将该数据渲染为纹理,然后使用 readPixels
读取数据。
您必须在着色器中将数据编码为字节,因为 WebGL 中的 readPixels
只能读取字节
你可以包装你的 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
提供包装器。
WebGL2
在 WebGL2 中有一个函数 gl.getBufferSubData
可以让您读取缓冲区的内容。请注意,WebGL2,即使它基于 OpenGL ES 3.0 也不支持 gl.mapBuffer
,因为没有高性能和安全的方法来公开该功能。
我想读回 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中的bufferdata? 如果可能,请用示例代码向我解释一下。
如何在运行时知道webgl中Gpu的内存大小(已满和空闲)以及如何在webgl中调试GPU中的着色器代码和数据。
无法直接在 WebGL1 中读回数据。 (请参阅下面的 WebGL2)。这是基于 WebGL 的 OpenGL ES 2.0 的限制。
有一些解决方法:
您可以尝试将该数据渲染为纹理,然后使用
readPixels
读取数据。您必须在着色器中将数据编码为字节,因为 WebGL 中的
readPixels
只能读取字节你可以包装你的 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
提供包装器。
WebGL2
在 WebGL2 中有一个函数 gl.getBufferSubData
可以让您读取缓冲区的内容。请注意,WebGL2,即使它基于 OpenGL ES 3.0 也不支持 gl.mapBuffer
,因为没有高性能和安全的方法来公开该功能。