@itwin/core-frontend
Version:
iTwin.js frontend components
296 lines • 10.6 kB
JavaScript
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module WebGL
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.QBufferHandle3d = exports.QBufferHandle2d = exports.BufferHandle = exports.VAOHandle = exports.BuffersContainer = exports.BufferParameters = void 0;
exports.qparams2dToArray = qparams2dToArray;
exports.qorigin3dToArray = qorigin3dToArray;
exports.qscale3dToArray = qscale3dToArray;
exports.qparams3dToArray = qparams3dToArray;
const core_bentley_1 = require("@itwin/core-bentley");
const GL_1 = require("./GL");
const System_1 = require("./System");
/** Provides convenience methods for creating a BufferHandleLinkage interface. */
class BufferHandleLinkage {
constructor() { }
static create(buffer, params) {
return { buffer, params };
}
static clone(linkage) {
const clonedParams = [];
for (const param of linkage.params) {
clonedParams.push(BufferParameters.clone(param));
}
return BufferHandleLinkage.create(linkage.buffer, clonedParams);
}
}
/**
* Provides convenience methods for creating a BuffersParameter interface.
* @internal
*/
var BufferParameters;
(function (BufferParameters) {
function create(glAttribLoc, glSize, glType, glNormalized, glStride, glOffset, glInstanced) {
return { glAttribLoc, glSize, glType, glNormalized, glStride, glOffset, glInstanced };
}
BufferParameters.create = create;
function clone(params) {
return BufferParameters.create(params.glAttribLoc, params.glSize, params.glType, params.glNormalized, params.glStride, params.glOffset, params.glInstanced);
}
BufferParameters.clone = clone;
})(BufferParameters || (exports.BufferParameters = BufferParameters = {}));
/**
* An abstract class which specifies an interface for binding and unbinding vertex buffers and their associated state.
* @internal
*/
class BuffersContainer {
linkages = [];
_vao;
_context;
static create() {
return new BuffersContainer(System_1.System.instance.context);
}
constructor(context) {
this._context = context;
this._vao = new VAOHandle(this._context);
}
/** @deprecated in 5.0 - will not be removed until after 2026-06-13. Use [Symbol.dispose] instead. */
dispose() {
this[Symbol.dispose]();
}
// NB: BufferHandle objects contained within BufferHandleLinkage entries are disposed where they are created because they could be shared among multiple BuffersContainer objects.
[Symbol.dispose]() {
this._vao[Symbol.dispose]();
}
get isDisposed() {
return this._vao.isDisposed;
}
addBuffer(buffer, params) {
const linkage = BufferHandleLinkage.create(buffer, params);
this.linkages.push(linkage);
this._bindLinkage(linkage);
}
appendLinkages(linkages) {
for (const linkage of linkages) {
this.linkages.push(BufferHandleLinkage.clone(linkage));
this._bindLinkage(linkage);
}
}
_bindLinkage(linkage) {
this.bind();
linkage.buffer.bind();
for (const p of linkage.params) {
System_1.System.instance.context.enableVertexAttribArray(p.glAttribLoc);
if (p.glInstanced) {
System_1.System.instance.vertexAttribDivisor(p.glAttribLoc, 1);
}
System_1.System.instance.context.vertexAttribPointer(p.glAttribLoc, p.glSize, p.glType, p.glNormalized, p.glStride, p.glOffset);
}
this.unbind();
}
bind() {
this._vao.bind();
}
unbind() {
VAOHandle.unbind(this._context);
}
}
exports.BuffersContainer = BuffersContainer;
/** A handle to a WebGLVertexArrayObjectOES.
* The WebGLVertexArrayObjectOES is allocated by the constructor and should be freed by a call to dispose().
* @internal
*/
class VAOHandle {
_context;
_arrayObject;
/** Allocates the WebGLVertexArrayObjectOES using the supplied context. Free the WebGLVertexArrayObjectOES using dispose() */
constructor(context) {
this._context = context;
const arrayObject = this._context.createVertexArray();
// vaoExt.createVertexArrayOES() returns WebGLVertexArrayObjectOES | null...
if (null !== arrayObject) {
this._arrayObject = arrayObject;
}
else {
this._arrayObject = undefined;
}
(0, core_bentley_1.assert)(!this.isDisposed);
}
get isDisposed() { return this._arrayObject === undefined; }
/** @deprecated in 5.0 - will not be removed until after 2026-06-13. Use [Symbol.dispose] instead. */
dispose() {
this[Symbol.dispose]();
}
/** Frees the WebGL vertex array object */
[Symbol.dispose]() {
if (!this.isDisposed) {
this._context.deleteVertexArray(this._arrayObject);
this._arrayObject = undefined;
}
}
/** Binds this vertex array object */
bind() {
if (undefined !== this._arrayObject) {
this._context.bindVertexArray(this._arrayObject);
}
}
/** Ensures no vertex array object is bound */
static unbind(context) {
context.bindVertexArray(null);
}
}
exports.VAOHandle = VAOHandle;
/**
* A handle to a WebGLBuffer, such as a vertex or index buffer.
* The WebGLBuffer is allocated by the constructor and should be freed by a call to dispose().
* @internal
*/
class BufferHandle {
_target;
_glBuffer;
_bytesUsed = 0;
/** Allocates the WebGLBuffer using the supplied context. Free the WebGLBuffer using dispose() */
constructor(target) {
this._target = target;
const glBuffer = System_1.System.instance.context.createBuffer();
// gl.createBuffer() returns WebGLBuffer | null...
if (null !== glBuffer) {
this._glBuffer = glBuffer;
}
else {
this._glBuffer = undefined;
}
(0, core_bentley_1.assert)(!this.isDisposed);
}
get isDisposed() { return this._glBuffer === undefined; }
get bytesUsed() { return this._bytesUsed; }
/** Frees the WebGL buffer */
[Symbol.dispose]() {
if (!this.isDisposed) {
System_1.System.instance.context.deleteBuffer(this._glBuffer);
this._glBuffer = undefined;
this._bytesUsed = 0;
}
}
/** Binds this buffer to the target specified during construction */
bind() {
if (undefined !== this._glBuffer) {
System_1.System.instance.context.bindBuffer(this._target, this._glBuffer);
}
}
/** Sets the specified target to be bound to no buffer */
unbind() { System_1.System.instance.context.bindBuffer(this._target, null); }
/** Binds this buffer to the target specified at construction and sets the buffer's data store. */
bindData(data, usage = GL_1.GL.Buffer.Usage.StaticDraw) {
this.bind();
System_1.System.instance.context.bufferData(this._target, data, usage);
this.unbind();
this._bytesUsed = data.byteLength;
}
/** Creates a BufferHandle and binds its data */
static createBuffer(target, data, usage = GL_1.GL.Buffer.Usage.StaticDraw) {
const handle = new BufferHandle(target);
if (handle.isDisposed) {
return undefined;
}
handle.bindData(data, usage);
return handle;
}
/** Creates a BufferHandle and binds its data */
static createArrayBuffer(data, usage = GL_1.GL.Buffer.Usage.StaticDraw) {
return BufferHandle.createBuffer(GL_1.GL.Buffer.Target.ArrayBuffer, data, usage);
}
isBound(binding) { return System_1.System.instance.context.getParameter(binding) === this._glBuffer; }
}
exports.BufferHandle = BufferHandle;
function setScale(index, value, array) {
array[index] = 0.0 !== value ? 1.0 / value : value;
}
/**
* Converts 2d quantization parameters to a format appropriate for submittal to the GPU.
* params[0] = origin.x
* params[1] = origin.y
* params[2] = scale.x
* params[3] = scale.y
* @internal
*/
function qparams2dToArray(params) {
const arr = new Float32Array(4);
arr[0] = params.origin.x;
arr[1] = params.origin.y;
setScale(2, params.scale.x, arr);
setScale(3, params.scale.y, arr);
return arr;
}
/** @internal */
function qorigin3dToArray(qorigin) {
const origin = new Float32Array(3);
origin[0] = qorigin.x;
origin[1] = qorigin.y;
origin[2] = qorigin.z;
return origin;
}
/** @internal */
function qscale3dToArray(qscale) {
const scale = new Float32Array(3);
setScale(0, qscale.x, scale);
setScale(1, qscale.y, scale);
setScale(2, qscale.z, scale);
return scale;
}
/** Converts 3d quantization params to a pair of Float32Arrays
* @internal
*/
function qparams3dToArray(params) {
const origin = qorigin3dToArray(params.origin);
const scale = qscale3dToArray(params.scale);
return { origin, scale };
}
/** A handle to a WebGLBuffer intended to hold quantized 2d points
* @internal
*/
class QBufferHandle2d extends BufferHandle {
params;
constructor(qParams) {
super(GL_1.GL.Buffer.Target.ArrayBuffer);
this.params = qparams2dToArray(qParams);
}
static create(qParams, data) {
const handle = new QBufferHandle2d(qParams);
if (handle.isDisposed) {
return undefined;
}
handle.bindData(data);
return handle;
}
}
exports.QBufferHandle2d = QBufferHandle2d;
/* A handle to a WebGLBuffer intended to hold quantized 3d points
* @internal
*/
class QBufferHandle3d extends BufferHandle {
/** The quantization origin in x, y, and z */
origin;
/** The quantization scale in x, y, and z */
scale;
constructor(qParams) {
super(GL_1.GL.Buffer.Target.ArrayBuffer);
this.origin = qorigin3dToArray(qParams.origin);
this.scale = qscale3dToArray(qParams.scale);
}
static create(qParams, data) {
const handle = new QBufferHandle3d(qParams);
if (handle.isDisposed) {
return undefined;
}
handle.bindData(data);
return handle;
}
}
exports.QBufferHandle3d = QBufferHandle3d;
//# sourceMappingURL=AttributeBuffers.js.map