Skip to content

Commit 4239cbc

Browse files
authored
Merge branch 'master' into env-mapping-pass
2 parents 1036d52 + 91cc4d1 commit 4239cbc

File tree

2 files changed

+257
-2
lines changed

2 files changed

+257
-2
lines changed

examples/examples.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@
112112
"target": "label3d-example",
113113
"title": "Label 3D",
114114
"object": "Label3DExample",
115-
"caption": "Static/dynamic text that can be positioned in 3D space.",
116-
"disabled": true
115+
"caption": "Static/dynamic text that can be positioned in 3D space."
117116
}
118117
]

examples/label3d-example.ts

+256
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
2+
/* spellchecker: disable */
3+
4+
import { auxiliaries } from 'webgl-operate';
5+
6+
import {
7+
Camera,
8+
Canvas,
9+
Context,
10+
DefaultFramebuffer,
11+
FontFace,
12+
Invalidate,
13+
Label,
14+
LabelRenderPass,
15+
MouseEventProvider,
16+
Navigation,
17+
Position3DLabel,
18+
Renderer,
19+
Text,
20+
Wizard,
21+
} from 'webgl-operate';
22+
23+
import { vec3 } from 'gl-matrix';
24+
import { Example } from './example';
25+
26+
/* spellchecker: enable */
27+
28+
// tslint:disable:max-classes-per-file
29+
30+
31+
class Label3DRenderer extends Renderer {
32+
33+
protected _extensions = false;
34+
35+
protected _labelPass: LabelRenderPass;
36+
37+
protected _labelWrap: Position3DLabel;
38+
protected _labelCentered: Position3DLabel;
39+
40+
protected _camera: Camera;
41+
protected _navigation: Navigation;
42+
43+
protected _defaultFBO: DefaultFramebuffer;
44+
45+
protected _fontFace: FontFace | undefined;
46+
47+
/**
48+
* Initializes and sets up rendering passes, navigation, loads a font face and links shaders with program.
49+
* @param context - valid context to create the object for.
50+
* @param identifier - meaningful name for identification of this instance.
51+
* @param mouseEventProvider - required for mouse interaction
52+
* @returns - whether initialization was successful
53+
*/
54+
protected onInitialize(context: Context, callback: Invalidate, mouseEventProvider: MouseEventProvider,
55+
/* keyEventProvider: KeyEventProvider, */
56+
/* touchEventProvider: TouchEventProvider */): boolean {
57+
58+
/* Create framebuffers, textures, and render buffers. */
59+
60+
this._defaultFBO = new DefaultFramebuffer(this._context, 'DefaultFBO');
61+
this._defaultFBO.initialize();
62+
63+
/* Create and configure test navigation. */
64+
65+
this._camera = new Camera();
66+
this._camera.eye = vec3.fromValues(0.0, 0.0, 1.0);
67+
this._camera.center = vec3.fromValues(0.0, 0.0, 0.0);
68+
this._camera.up = vec3.fromValues(0.0, 1.0, 0.0);
69+
this._camera.near = 0.1;
70+
this._camera.far = 4.0;
71+
72+
this._navigation = new Navigation(callback, mouseEventProvider);
73+
this._navigation.camera = this._camera;
74+
75+
/* Create and configure label pass. */
76+
77+
this._labelPass = new LabelRenderPass(context);
78+
this._labelPass.initialize();
79+
this._labelPass.camera = this._camera;
80+
this._labelPass.target = this._defaultFBO;
81+
this._labelPass.depthMask = false;
82+
83+
FontFace.fromFile('./data/opensans2048p160d16.fnt', context)
84+
.then((fontFace) => {
85+
for (const label of this._labelPass.labels) {
86+
label.fontFace = fontFace;
87+
}
88+
this._fontFace = fontFace;
89+
this.updateLabels();
90+
this.invalidate();
91+
})
92+
.catch((reason) => auxiliaries.log(auxiliaries.LogLevel.Error, reason));
93+
94+
this.setupScene();
95+
96+
return true;
97+
}
98+
99+
/**
100+
* Uninitializes Buffers, Textures, and Program.
101+
*/
102+
protected onUninitialize(): void {
103+
super.uninitialize();
104+
105+
this._defaultFBO.uninitialize();
106+
this._labelPass.uninitialize();
107+
}
108+
109+
/**
110+
* This is invoked in order to check if rendering of a frame is required by means of implementation specific
111+
* evaluation (e.g., lazy non continuous rendering). Regardless of the return value a new frame (preparation,
112+
* frame, swap) might be invoked anyway, e.g., when update is forced or canvas or context properties have
113+
* changed or the renderer was invalidated @see{@link invalidate}.
114+
* @returns whether to redraw
115+
*/
116+
protected onUpdate(): boolean {
117+
this._navigation.update();
118+
119+
for (const label of this._labelPass.labels) {
120+
if (label.altered || label.color.altered) {
121+
return true;
122+
}
123+
}
124+
return this._altered.any || this._camera.altered;
125+
}
126+
127+
/**
128+
* This is invoked in order to prepare rendering of one or more frames, regarding multi-frame rendering and
129+
* camera-updates.
130+
*/
131+
protected onPrepare(): void {
132+
133+
if (this._altered.canvasSize) {
134+
this._camera.aspect = this._canvasSize[0] / this._canvasSize[1];
135+
this._camera.viewport = this._canvasSize;
136+
137+
this.updateLabels();
138+
}
139+
140+
if (this._altered.clearColor) {
141+
this._defaultFBO.clearColor(this._clearColor);
142+
}
143+
144+
this._labelPass.update();
145+
146+
this._altered.reset();
147+
this._camera.altered = false;
148+
}
149+
150+
/**
151+
* After (1) update and (2) preparation are invoked, a frame is invoked. Renders both 2D and 3D labels.
152+
* @param frameNumber - for intermediate frames in accumulation rendering
153+
*/
154+
protected onFrame(frameNumber: number): void {
155+
const gl = this._context.gl;
156+
157+
gl.viewport(0, 0, this._camera.viewport[0], this._camera.viewport[1]);
158+
159+
this._defaultFBO.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT, true, false);
160+
this._labelPass.frame();
161+
}
162+
163+
/**
164+
* Sets up an example scene with 2D and 3D labels and sets the corresponding data on LabelGeometries. The
165+
* FontFace is set on each label by the LabelRenderPass.
166+
*/
167+
protected setupScene(): void {
168+
169+
/** Wrapped labels, showcasing Ellipsis and NewLine */
170+
171+
const kafka = 'One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in \
172+
his bed into a horrible vermin. He lay on his armour-like back, and if he lifted his head a little he could see his \
173+
brown belly, slightly domed and divided by arches into stiff sections.';
174+
175+
this._labelWrap = new Position3DLabel(new Text(`Wrap: ${kafka}`), Label.Type.Dynamic);
176+
this._labelWrap.wrap = true;
177+
this._labelWrap.lineWidth = 0.8;
178+
179+
this._labelCentered = new Position3DLabel(new Text(`Label.LineAnchor\n+\nLabel.Alignment.Center`),
180+
Label.Type.Dynamic);
181+
this._labelCentered.lineAnchor = Label.LineAnchor.Center;
182+
this._labelCentered.alignment = Label.Alignment.Center;
183+
184+
this._labelPass.labels = [this._labelWrap, this._labelCentered];
185+
186+
for (const label of this._labelPass.labels) {
187+
label.fontSize = 0.05;
188+
label.color.fromHex('#fff');
189+
label.fontSizeUnit = Label.Unit.World;
190+
}
191+
}
192+
193+
protected updateLabels(): void {
194+
if (!this._labelWrap.valid) {
195+
return;
196+
}
197+
198+
this._labelWrap.position = [-0.3, 0.0, 0.0];
199+
this._labelWrap.up = [0.0, 0.0, -1.0];
200+
201+
this._labelCentered.position = [0.0, 0.0, 0.0];
202+
}
203+
204+
}
205+
206+
207+
export class Label3DExample extends Example {
208+
209+
private _canvas: Canvas;
210+
private _renderer: Label3DRenderer;
211+
212+
initialize(element: HTMLCanvasElement | string): boolean {
213+
214+
this._canvas = new Canvas(element, { antialias: false });
215+
this._canvas.controller.multiFrameNumber = 1;
216+
this._canvas.framePrecision = Wizard.Precision.byte;
217+
this._canvas.frameScale = [1.0, 1.0];
218+
219+
this._renderer = new Label3DRenderer();
220+
this._canvas.renderer = this._renderer;
221+
222+
// Create a target cross as reference for coordinate origin [0,0,0]
223+
224+
const hlStyle = 'z-index: 1; position: absolute; width: 100%; margin: 0; margin-left: 0%;'
225+
+ 'border: none; border-bottom: 1pt solid #1c75bc; border-top: 1pt solid #1c75bc;';
226+
const vlStyle = 'z-index: 1; position: absolute; height: 100%; margin: 0; margin-top: 0%;'
227+
+ 'border: none; border-left: 1pt solid #1cbc75; border-right: 1pt solid #1cbc75;';
228+
229+
const hl = document.createElement('hl');
230+
hl.setAttribute('style', `${hlStyle} top: 50%;`);
231+
const vl = document.createElement('vl');
232+
vl.setAttribute('style', `${vlStyle} left: 50%;`);
233+
234+
235+
const parent = this._canvas.element!.parentElement!;
236+
const reference = this._canvas.element!;
237+
parent.insertBefore(hl, reference);
238+
parent.insertBefore(vl, reference);
239+
240+
return true;
241+
}
242+
243+
uninitialize(): void {
244+
this._canvas.dispose();
245+
(this._renderer as Renderer).uninitialize();
246+
}
247+
248+
get canvas(): Canvas {
249+
return this._canvas;
250+
}
251+
252+
get renderer(): Label3DRenderer {
253+
return this._renderer;
254+
}
255+
256+
}

0 commit comments

Comments
 (0)