playcanvas
Version:
PlayCanvas WebGL game engine
78 lines (75 loc) • 2.6 kB
JavaScript
import { BUFFER_GPUDYNAMIC, PRIMITIVE_POINTS } from './constants.js';
import { VertexBuffer } from './vertex-buffer.js';
import { Shader } from './shader.js';
import { ShaderDefinitionUtils } from './shader-definition-utils.js';
class TransformFeedback {
constructor(inputBuffer, outputBuffer, usage = BUFFER_GPUDYNAMIC){
if (outputBuffer !== undefined && !(outputBuffer instanceof VertexBuffer)) {
usage = outputBuffer;
outputBuffer = undefined;
}
this.device = inputBuffer.device;
const gl = this.device.gl;
const outVB = outputBuffer ?? inputBuffer;
if (usage === BUFFER_GPUDYNAMIC && outVB.usage !== usage) {
gl.bindBuffer(gl.ARRAY_BUFFER, outVB.impl.bufferId);
gl.bufferData(gl.ARRAY_BUFFER, outVB.storage, gl.DYNAMIC_COPY);
}
this._inputBuffer = inputBuffer;
this._destroyOutputBuffer = !outputBuffer;
this._outputBuffer = outputBuffer ?? new VertexBuffer(inputBuffer.device, inputBuffer.format, inputBuffer.numVertices, {
usage: usage,
data: inputBuffer.storage
});
}
static createShader(graphicsDevice, vertexCode, name, feedbackVaryings) {
return new Shader(graphicsDevice, ShaderDefinitionUtils.createDefinition(graphicsDevice, {
name,
vertexCode,
feedbackVaryings,
useTransformFeedback: true,
fragmentCode: 'void main(void) {gl_FragColor = vec4(0.0);}'
}));
}
destroy() {
if (this._destroyOutputBuffer) {
this._outputBuffer.destroy();
}
}
process(shader, swap = true) {
const device = this.device;
const oldRt = device.getRenderTarget();
device.setRenderTarget(null);
device.updateBegin();
device.setVertexBuffer(this._inputBuffer);
device.setRaster(false);
device.setTransformFeedbackBuffer(this._outputBuffer);
device.setShader(shader);
device.draw({
type: PRIMITIVE_POINTS,
base: 0,
baseVertex: 0,
count: this._inputBuffer.numVertices,
indexed: false
});
device.setTransformFeedbackBuffer(null);
device.setRaster(true);
device.updateEnd();
device.setRenderTarget(oldRt);
if (swap) {
let tmp = this._inputBuffer.impl.bufferId;
this._inputBuffer.impl.bufferId = this._outputBuffer.impl.bufferId;
this._outputBuffer.impl.bufferId = tmp;
tmp = this._inputBuffer.impl.vao;
this._inputBuffer.impl.vao = this._outputBuffer.impl.vao;
this._outputBuffer.impl.vao = tmp;
}
}
get inputBuffer() {
return this._inputBuffer;
}
get outputBuffer() {
return this._outputBuffer;
}
}
export { TransformFeedback };