【问题标题】:GL_INVALID_OPERATION: Active draw buffers with missing fragment shader outputsGL_INVALID_OPERATION:缺少片段着色器输出的活动绘制缓冲区
【发布时间】:2021-09-08 16:00:10
【问题描述】:

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

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

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

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

谢谢

GL_INVALID_OPERATION

【问题讨论】:

    标签: autodesk-forge


    【解决方案1】:

    2021-06-26 更新

    此版本包括以下改进:

    • 修复受https://stackoverflow.com/a/57571964启发的文本对齐问题
      • 移除THREE.TextGeometryTHREE.Font的依赖。
      • 无需使用 ES6 模块来加载此扩展。
    • 修复 null placementTransform 问题。
    /////////////////////////////////////////////////////////////////////
    // 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 Viewer 现在需要 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/three@0.113.2/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> 
    

    【讨论】:

    • 加载“Autodesk.ADN.AecGridsExtension”时出现以下错误。因此,我检查了断点,该错误出现在 modelBuilderExt.addNewModel 之后。 AEC.min.js:19 Uncaught (in promise) TypeError: Cannot read property 'getModelKey' of null at c. (AEC.min.js:19) at l (viewer3D.min.js:33) at Generator ._invoke (viewer3D.min.js:33) 在 Generator.forEach.e. [as next] (viewer3D.min.js:33) 在 co (AEC.min.js:19) 在 s (AEC. min.js:19) at AEC.min.js:19 at new Promise () at c. (AEC.min.js:19)
    • 此时请忽略。我稍后会向我们的工程团队报告。错误是使用SceneBuilder时其他内置扩展引起的,但不会影响我分享的网格扩展。
    猜你喜欢
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多