缺少片段着色器输出的活动绘制缓冲区

缺少片段着色器输出的活动绘制缓冲区

本文介绍了GL_INVALID_OPERATION:缺少片段着色器输出的活动绘制缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在查看器中创建网格线时出现以下错误。

[.WebGL-000043380413A900]GL_INVALID_OPERATION:缺少片段着色器输出的活动绘制缓冲区。

我使用了此页面中的代码。https://forge.autodesk.com/blog/consume-aec-data-which-are-model-derivative-api

我可以知道解决此问题的方法吗?

谢谢

GL_INVALID_OPERATION

推荐答案

更新2021-06-26

此版本包括以下改进:

  • 修复受https://stackoverflow.com/a/57571964启发的文本对齐问题
    • 删除THREE.TextGeometryTHREE.Font的依赖项。
    • 无需使用ES6模块加载此扩展。
  • 修复空位置转换问题。
/////////////////////////////////////////////////////////////////////
// Copyright (c) Autodesk, Inc. All rights reserved
// Written by Forge Partner Development
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
/////////////////////////////////////////////////////////////////////

class AecGridsExtension extends Autodesk.Viewing.Extension {
    constructor(viewer, options) {
        super(viewer, options);

        this.modelBuilder = null;
        this.idPrefix = 100;
    }

    async load() {
        const modelBuilderExt = await this.viewer.loadExtension('Autodesk.Viewing.SceneBuilder');
        const modelBuilder = await modelBuilderExt.addNewModel({
            conserveMemory: false,
            modelNameOverride: 'Grids'
        });

        this.modelBuilder = modelBuilder;

        if (!this.viewer.isLoadDone()) {
            this.viewer.addEventListener(
                Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
                () => this.createGrids(),
                { once: true }
            );
        } else {
            this.createGrids();
        }

        return true;
    }

    unload() {
        this.viewer.impl.unloadModel(this.modelBuilder.model);

        delete this.linesMaterial;
        this.linesMaterial = null;
        return true;
    }

    createMaterials() {
        const matName = 'grid-line-mat';
        const linesMaterial = new THREE.LineBasicMaterial({
            color: 0xff0000,
            linewidth: 2
        });
        this.modelBuilder.addMaterial(matName, linesMaterial);
        this.linesMaterial = this.modelBuilder.findMaterial(matName);
    }

    createLabel(params) {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        const size = 256;
        canvas.width = canvas.height = size;

        // draw/fill the circle
        ctx.beginPath();
        ctx.arc(canvas.width / 2, canvas.height / 2, canvas.width / 2, 0, 2 * Math.PI);
        ctx.fillStyle = 'yellow';
        ctx.fill();

        // draw the number
        const fontSize = size / 2;
        ctx.fillStyle = 'black';
        ctx.font = `${fontSize}px sans-serif`;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText(params.text, canvas.width / 2, canvas.height / 2);
        const labelBlobUrl = canvas.toDataURL();

        const image = new Image();
        const texture = new THREE.Texture();

        texture.image = image;
        image.src = labelBlobUrl;
        image.onload = function () {
            texture.needsUpdate = true;
        };

        const labelDbId = this.idPrefix++;
        const matName = `label-mat-${labelDbId}`;
        const material = new THREE.MeshPhongMaterial({ map: texture, side: THREE.DoubleSide, opacity: 0.8, transparent: true });
        this.modelBuilder.addMaterial(matName, material);
        const labelMat = this.modelBuilder.findMaterial(matName);

        const circleGeo = new THREE.BufferGeometry().fromGeometry(new THREE.CircleGeometry(3, 32));
        const circle = new THREE.Mesh(circleGeo, labelMat);

        circle.matrix = new THREE.Matrix4().compose(
            params.circlePos,
            new THREE.Quaternion(0, 0, 0, 1),
            new THREE.Vector3(1, 1, 1)
        );
        circle.dbId = labelDbId;
        this.modelBuilder.addMesh(circle);
    }

    createGrid(grid) {
        //draw each segment one by one
        const segments = grid.segments;
        const offsetMatrix = this.viewer.model.getModelToViewerTransform() || new THREE.Matrix4().identity();

        for (let i = 0; i < segments.length; i++) {
            const seg = segments[i];
            //start and end point
            const { start, end } = seg.points;
            const startPoint = new THREE.Vector3(start[0], start[1], start[2]).applyMatrix4(offsetMatrix);
            const endPoint = new THREE.Vector3(end[0], end[1], end[2]).applyMatrix4(offsetMatrix);

            //grid line
            const lineGeo = new THREE.BufferGeometry();

            const lineIndices = [];
            const lineVertices = [];
            lineVertices.push(...startPoint.toArray());
            lineVertices.push(...endPoint.toArray());
            lineIndices.push(0, 1);

            lineGeo.addAttribute('index', new THREE.BufferAttribute(new Uint32Array(lineIndices), 1));
            lineGeo.addAttribute('position', new THREE.BufferAttribute(new Float32Array(lineVertices), 3));
            lineGeo.isLines = true;

            var line = new THREE.Mesh(lineGeo, this.linesMaterial);
            line.dbId = this.idPrefix++;
            this.modelBuilder.addMesh(line);

            let lineDir = endPoint.clone().sub(startPoint.clone()).normalize();
            let circlePos = endPoint.clone().add(lineDir.clone().multiplyScalar(3));

            this.createLabel({
                circlePos,
                text: grid.label
            });
        }
    }

    async createGrids() {
        const aecdata = await this.viewer.model.getDocumentNode().getDocument().downloadAecModelData();
        const grids = aecdata.grids;

        this.createMaterials();

        for (let i = 0; i < grids.length; i++) {
            const grid = grids[i];
            this.createGrid(grid);
        }
    }

    lockSelection() {
        const dbIds = this.modelBuilder.model.getFragmentList().fragments.fragId2dbId;
        const model = this.modelBuilder.model;
        this.viewer.lockSelection(dbIds, true, model);
    }

    unlockSelection() {
        const dbIds = this.modelBuilder.model.getFragmentList().fragments.fragId2dbId;
        const model = this.modelBuilder.model;
        this.viewer.unlockSelection(dbIds, model);
    }
}

Autodesk.Viewing.theExtensionManager.registerExtension('AecGridsExtension', AecGridsExtension);
快照:

=

Forge查看器现在需要THREE.BufferGeometry,而不是THRE.XXXGeometry。以下是https://forge.autodesk.com/blog/consume-aec-data-which-are-model-derivative-api

的修订版
/////////////////////////////////////////////////////////////////////
// Copyright (c) Autodesk, Inc. All rights reserved
// Written by Forge Partner Development
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
/////////////////////////////////////////////////////////////////////

import {
    Font,
    TextGeometry
} from 'https://unpkg.com/three-full/builds/Three.es.js';
import FontJson from 'https://unpkg.com/[email protected]/examples/fonts/helvetiker_bold.typeface.json' assert { type: 'json' };


export default class AecGridsExtension extends Autodesk.Viewing.Extension {
    constructor(viewer, options) {
        super(viewer, options);

        this.modelBuilder = null;
        this.idPrefix = 100;
    }

    async load() {
        const modelBuilderExt = await this.viewer.loadExtension('Autodesk.Viewing.SceneBuilder');
        const modelBuilder = await modelBuilderExt.addNewModel({
            conserveMemory: false,
            modelNameOverride: 'Grids'
        });

        this.modelBuilder = modelBuilder;

        if (!this.viewer.isLoadDone()) {
            this.viewer.addEventListener(
                Autodesk.Viewing.GEOMETRY_LOADED_EVENT,
                () => this.createGrids(),
                { once: true }
            );
        } else {
            this.createGrids();
        }

        return true;
    }

    unload() {
        return true;
    }

    createMaterials() {
        const linesMaterial = new THREE.LineBasicMaterial({
            color: 0xff0000,
            linewidth: 2
        });
        this.linesMaterial = linesMaterial;

        const circleMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
        this.circleMaterial = circleMaterial;

        const textMaterial = new THREE.MeshPhongMaterial({
            specular: new THREE.Color(0x00ffff),
            side: THREE.DoubleSide,
            reflectivity: 0.0,
            color: 0x00ffff
        });

        this.textMaterial = textMaterial;
    }

    createText(params) {
        params.font = new Font(FontJson);
        const geometry = new THREE.BufferGeometry().fromGeometry(new TextGeometry(params.text, params));

        const text = new THREE.Mesh(geometry, this.textMaterial);
        text.matrix = new THREE.Matrix4().compose(
            new THREE.Vector3(params.position.x, params.position.y, params.position.z),
            new THREE.Quaternion(0, 0, 0, 1),
            new THREE.Vector3(1, 1, 1)
        );

        text.dbId = this.idPrefix++;
        this.modelBuilder.addMesh(text);
    }

    createGrid(grid) {
        //draw each segment one by one
        const segments = grid.segments;
        const offsetMatrix = this.viewer.model.getData().placementWithOffset;

        for (let i = 0; i < segments.length; i++) {
            const seg = segments[i];
            //start and end point
            const { start, end } = seg.points;
            const startPoint = new THREE.Vector3(start[0], start[1], start[2]).applyMatrix4(offsetMatrix);
            const endPoint = new THREE.Vector3(end[0], end[1], end[2]).applyMatrix4(offsetMatrix);

            //grid line
            const lineGeo = new THREE.BufferGeometry();

            const lineIndices = [];
            const lineVertices = [];
            lineVertices.push(...startPoint.toArray());
            lineVertices.push(...endPoint.toArray());
            lineIndices.push(0, 1);

            lineGeo.addAttribute('index', new THREE.BufferAttribute(new Uint32Array(lineIndices), 1));
            lineGeo.addAttribute('position', new THREE.BufferAttribute(new Float32Array(lineVertices), 3));
            lineGeo.isLines = true;

            var line = new THREE.Mesh(lineGeo, this.linesMaterial);
            line.dbId = this.idPrefix++;
            this.modelBuilder.addMesh(line);

            let lineDir = endPoint.clone().sub(startPoint.clone()).normalize();
            let circlePos = endPoint.clone().add(lineDir.clone().multiplyScalar(3));
            //grid circle
            let circleGeo = new THREE.BufferGeometry().fromGeometry(new THREE.CircleGeometry(3, 32));
            let circle = new THREE.Mesh(circleGeo, this.circleMaterial);

            circle.matrix = new THREE.Matrix4().compose(
                circlePos,
                new THREE.Quaternion(0, 0, 0, 1),
                new THREE.Vector3(1, 1, 1)
            );
            circle.dbId = this.idPrefix++;
            this.modelBuilder.addMesh(circle);

            //transform the circle to the position of max point of bounding box of this grid.

            //get extension of drawing text
            //draw text
            this.createText({
                //intensionally to adjust the position of the text
                //will need to improve to make it more elegant
                position: endPoint.clone().add(lineDir.clone().multiplyScalar(3)),
                text: grid.label,
                size: 2,
                height: 0.01,
                curveSegments: 12,
                font: 'helvetiker',
                weight: 'Regular',
                bevelEnabled: false,
                bevelThickness: 0.1,
                bevelSize: 0.1,
                bevelSegments: 10,
            });
        }
    }

    async createGrids() {
        const aecdata = await this.viewer.model.getDocumentNode().getDocument().downloadAecModelData();
        const grids = aecdata.grids;

        this.createMaterials();

        for (let i = 0; i < grids.length; i++) {
            const grid = grids[i];
            this.createGrid(grid);
        }

        // uncomment to prevent selection on grids
        // const dbIds = this.modelBuilder.model.getFragmentList().fragments.fragId2dbId;
        // const model = this.modelBuilder.model;
        // this.viewer.lockSelection(dbIds, true, model);
    }
}

Autodesk.Viewing.theExtensionManager.registerExtension('Autodesk.ADN.AecGridsExtension', AecGridsExtension);

最后,在浏览器中加载为模块:

<script type="module" src="AecGridsExtension.js"></script> 

这篇关于GL_INVALID_OPERATION:缺少片段着色器输出的活动绘制缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-29 13:31