/*---------------------------------------------------------------------------------------------
* 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
 */
import { assert, dispose } from "@itwin/core-bentley";
import { RenderMode } from "@itwin/core-common";
import { TextureHandle } from "./Texture";
import { BufferHandle, BufferParameters, BuffersContainer } from "./AttributeBuffers";
import { MeshGeometry } from "./MeshGeometry";
import { AttributeMap } from "./AttributeMap";
import { GL } from "./GL";
import { System } from "./System";
import { ColorInfo } from "./ColorInfo";
import { lineCodeFromLinePixels } from "../../../common/internal/render/LineCode";
/** @see [[EdgeTable]]
 * @internal
 */
export class EdgeLUT {
    texture;
    numSegments;
    silhouettePadding;
    constructor(texture, numSegments, silhouettePadding) {
        this.texture = texture;
        this.numSegments = numSegments;
        this.silhouettePadding = silhouettePadding;
    }
    [Symbol.dispose]() {
        dispose(this.texture);
    }
    static create(table) {
        const texture = TextureHandle.createForData(table.width, table.height, table.data);
        return texture ? new EdgeLUT(texture, table.numSegments, table.silhouettePadding) : undefined;
    }
    get bytesUsed() {
        return this.texture.bytesUsed;
    }
    get isDisposed() {
        return this.texture.isDisposed;
    }
}
/** @see [[IndexedEdgeParams]]
 * @internal
 */
export class IndexedEdgeGeometry extends MeshGeometry {
    _buffers;
    _indices;
    _colorInfo;
    _width;
    _lineCode;
    edgeLut;
    get lutBuffers() { return this._buffers; }
    get asIndexedEdge() { return this; }
    constructor(mesh, indices, numIndices, lut, appearance) {
        super(mesh, numIndices);
        this.edgeLut = lut;
        this._buffers = BuffersContainer.create();
        const attrPos = AttributeMap.findAttribute("a_pos", 6 /* TechniqueId.IndexedEdge */, false);
        assert(undefined !== attrPos);
        this._buffers.addBuffer(indices, [BufferParameters.create(attrPos.location, 3, GL.DataType.UnsignedByte, false, 0, 0, false)]);
        this._indices = indices;
        this._colorInfo = appearance?.color ? ColorInfo.createFromColorDef(appearance.color) : mesh.lut.colorInfo;
        this._width = appearance?.width ?? mesh.edgeWidth;
        this._lineCode = appearance?.linePixels ? lineCodeFromLinePixels(appearance?.linePixels) : mesh.edgeLineCode;
    }
    [Symbol.dispose]() {
        dispose(this._buffers);
        dispose(this._indices);
        dispose(this.edgeLut);
    }
    get isDisposed() {
        return this._buffers.isDisposed && this._indices.isDisposed && this.edgeLut.isDisposed;
    }
    static create(mesh, params) {
        const indexBuffer = BufferHandle.createArrayBuffer(params.indices.data);
        const lut = EdgeLUT.create(params.edges);
        return indexBuffer && lut ? new IndexedEdgeGeometry(mesh, indexBuffer, params.indices.length, lut, params.appearance) : undefined;
    }
    collectStatistics(stats) {
        stats.addIndexedEdges(this._indices.bytesUsed);
        stats.addEdgeTable(this.edgeLut.bytesUsed);
    }
    _draw(numInstances, instances) {
        const bufs = instances ?? this._buffers;
        bufs.bind();
        System.instance.drawArrays(GL.PrimitiveType.Triangles, 0, this._numIndices, numInstances);
        bufs.unbind();
    }
    _wantWoWReversal() { return true; }
    _getLineCode(params) {
        return params.target.computeEdgeLineCode(params.renderPass, this._lineCode);
    }
    _getLineWeight(params) {
        return params.target.computeEdgeWeight(params.renderPass, this._width);
    }
    getColor(target) {
        return target.computeEdgeColor(this._colorInfo);
    }
    get techniqueId() { return 6 /* TechniqueId.IndexedEdge */; }
    getPass(target) { return this.computeEdgePass(target); }
    get renderOrder() { return this.isPlanar ? 14 /* RenderOrder.PlanarEdge */ : 6 /* RenderOrder.Edge */; }
    wantMonochrome(target) { return target.currentViewFlags.renderMode === RenderMode.Wireframe; }
}
//# sourceMappingURL=IndexedEdgeGeometry.js.map