UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

78 lines (75 loc) 2.6 kB
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 };