本文介绍了GL_INVALID_OPERATION:缺少片段着色器输出的活动绘制缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在查看器中创建网格线时出现以下错误。
[.WebGL-000043380413A900]GL_INVALID_OPERATION:缺少片段着色器输出的活动绘制缓冲区。
我使用了此页面中的代码。https://forge.autodesk.com/blog/consume-aec-data-which-are-model-derivative-api
我可以知道解决此问题的方法吗?
谢谢
推荐答案
更新2021-06-26
此版本包括以下改进:
- 修复受https://stackoverflow.com/a/57571964启发的文本对齐问题
- 删除
THREE.TextGeometry
和THREE.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:缺少片段着色器输出的活动绘制缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!