JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
GPUTextRendererListenerBase01.java
Go to the documentation of this file.
1/**
2 * Copyright 2010-2023 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28package com.jogamp.opengl.demos.graph;
29
30import java.io.IOException;
31
32import com.jogamp.opengl.GL;
33import com.jogamp.opengl.GL2ES2;
34import com.jogamp.opengl.GLAnimatorControl;
35import com.jogamp.opengl.GLAutoDrawable;
36import com.jogamp.opengl.GLException;
37import com.jogamp.opengl.GLProfile;
38import com.jogamp.common.util.InterruptSource;
39import com.jogamp.graph.curve.Region;
40import com.jogamp.graph.curve.opengl.GLRegion;
41import com.jogamp.graph.curve.opengl.RegionRenderer;
42import com.jogamp.graph.curve.opengl.RenderState;
43import com.jogamp.graph.curve.opengl.TextRegionUtil;
44import com.jogamp.graph.font.Font;
45import com.jogamp.graph.font.FontFactory;
46import com.jogamp.graph.font.FontScale;
47import com.jogamp.graph.font.FontSet;
48import com.jogamp.math.geom.AABBox;
49import com.jogamp.math.geom.plane.AffineTransform;
50import com.jogamp.math.util.PMVMatrix4f;
51import com.jogamp.newt.Window;
52import com.jogamp.newt.event.KeyEvent;
53import com.jogamp.newt.event.KeyListener;
54import com.jogamp.newt.opengl.GLWindow;
55
56/**
57 *
58 * GPURendererListenerBase01 Keys:
59 * - 1/2: zoom in/out
60 * - 6/7: 2nd pass texture size
61 * - 0/9: rotate
62 * - v: toggle v-sync
63 * - s: screenshot
64 *
65 * Additional Keys:
66 * - 3/4: font +/-
67 * - h: toogle draw 'font set'
68 * - f: toggle draw fps
69 * - space: toggle font (ubuntu/java)
70 * - i: live input text input (CR ends it, backspace supported)
71 */
74 private final GLRegion regionFPS, regionHead, regionBottom;
75 int fontSet = FontFactory.UBUNTU;
76 Font font;
77
78 int headType = 1;
79 boolean drawFPS = true;
80 final float fontSizeFName = 10f;
81 final float fontSizeFPS = 10f;
82 float fontSizeHead = 12f;
83 float fontSizeCenter = 16f;
84 float dpiV = 96;
85 float ppmmV = 1;
86 final int fontSizeModulo = 100;
87 String fontName;
88 AABBox fontNameBox;
89 String headtext;
90 AABBox headbox;
91
92 protected final AffineTransform tempT1 = new AffineTransform();
93 protected final AffineTransform tempT2 = new AffineTransform();
94
95 static final String text2 = "The quick brown fox jumps over the lazy dog";
96 public static final String text_help =
97 "JOGL: Java™ Binding for OpenGL®, providing hardware-accelerated 3D graphics.\n\n"+
98 "JOGAMP graph demo using Resolution Independent NURBS\n"+
99 "JOGAMP JOGL - OpenGL ES2 profile\n"+
100 "Press 1/2 to zoom in/out the below text\n"+
101 "Press 3/4 to incr/decs font size (alt: head, w/o bottom)\n"+
102 "Press 6/7 to edit texture size if using VBAA\n"+
103 "Press 0/9 to rotate the below string\n"+
104 "Press s to screenshot\n"+
105 "Press v to toggle vsync\n"+
106 "Press i for live input text input (CR ends it, backspace supported)\n"+
107 "Press f to toggle fps. H for different text, space for font type\n";
108
109 public static final String textX1 =
110 "JOGL: Java™ Binding for OpenGL®, providing hardware-accelerated 3D graphics.\n\n"+
111 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec nec sapien tellus. \n"+
112 "Ut purus odio, rhoncus sit amet commodo eget, ullamcorper vel urna. Mauris ultricies \n"+
113 "quam iaculis urna cursus ornare. Nullam ut felis a ante ultrices ultricies nec a elit. \n"+
114 "In hac habitasse platea dictumst. Vivamus et mi a quam lacinia pharetra at venenatis est. \n"+
115 "Morbi quis bibendum nibh. Donec lectus orci, sagittis in consequat nec, volutpat nec nisi. \n"+
116 "Donec ut dolor et nulla tristique varius. In nulla magna, fermentum id tempus quis, semper \n"+
117 "in lorem. Maecenas in ipsum ac justo scelerisque sollicitudin. Quisque sit amet neque lorem, \n" +
118 "-------Press H to change text---------";
119
120 public static final String textX2 =
121 "I “Ask Jeff” or ‘Ask Jeff’. Take the chef d’œuvre! Two of [of] (of) ‘of’ “of” of? of! of*.\n"+
122 "Les Woëvres, the Fôret de Wœvres, the Voire and Vauvise. Yves is in heaven; D’Amboise is in jail.\n"+
123 "Lyford’s in Texas & L’Anse-aux-Griffons in Québec; the Łyna in Poland. Yriarte, Yciar and Ysaÿe are at Yale.\n"+
124 "Kyoto and Ryotsu are both in Japan, Kwikpak on the Yukon delta, Kvæven in Norway, Kyulu in Kenya, not in Rwanda.…\n"+
125 "Von-Vincke-Straße in Münster, Vdovino in Russia, Ytterbium in the periodic table. Are Toussaint L’Ouverture, Wölfflin, Wolfe,\n"+
126 "Miłosz and Wū Wŭ all in the library? 1510–1620, 11:00 pm, and the 1980s are over. X\n"+
127 "-------Press H to change text---------";
128
129 public static final String textX20 =
130 "I “Ask Jeff” or ‘Ask Jeff’. Take the chef d’œuvre! Two of [of] (of) ‘of’ “of” of? of! of*.\n"+
131 "Two of [of] (of) ‘of’ “of” of? of! of*. Ydes, Yffignac and Ygrande are in France: so are Ypres,\n"+
132 "Les Woëvres, the Fôret de Wœvres, the Voire and Vauvise. Yves is in heaven; D’Amboise is in jail.\n"+
133 "Lyford’s in Texas & L’Anse-aux-Griffons in Québec; the Łyna in Poland. Yriarte, Yciar and Ysaÿe are at Yale.\n"+
134 "Kyoto and Ryotsu are both in Japan, Kwikpak on the Yukon delta, Kvæven in Norway, Kyulu in Kenya, not in Rwanda.…\n"+
135 "Walton’s in West Virginia, but «Wren» is in Oregon. Tlálpan is near Xochimilco in México.\n"+
136 "The Zygos & Xylophagou are in Cyprus, Zwettl in Austria, Fænø in Denmark, the Vøringsfossen and Værøy in Norway.\n"+
137 "Tchula is in Mississippi, the Tittabawassee in Michigan. Twodot is here in Montana, Ywamun in Burma.\n"+
138 "Yggdrasil and Ymir, Yngvi and Vóden, Vídrið and Skeggjöld and Týr are all in the Eddas.\n"+
139 "Tørberget and Våg, of course, are in Norway, Ktipas and Tmolos in Greece, but Vázquez is in Argentina, Vreden in Germany,\n"+
140 "Von-Vincke-Straße in Münster, Vdovino in Russia, Ytterbium in the periodic table. Are Toussaint L’Ouverture, Wölfflin, Wolfe,\n"+
141 "Miłosz and Wū Wŭ all in the library? 1510–1620, 11:00 pm, and the 1980s are over.\n"+
142 "Ut purus odio, rhoncus sit amet commodo eget, ullamcorper vel urna. Mauris ultricies \n"+
143 "-------Press H to change text---------";
144
145 static final String textXLast = "abcdefghijklmnopqrstuvwxyz\nABCDEFGHIJKLMNOPQRSTUVWXYZ\n0123456789.:,;(*!?/\\\")$%^&-+@~#<>{}[]";
146
147 Window upstream_window = null;
148 StringBuilder userString = new StringBuilder(textX1);
149 boolean userInput = false;
150 public GPUTextRendererListenerBase01(final GLProfile glp, final int renderModes, final int aaQuality, final int sampleCount, final boolean blending, final boolean debug, final boolean trace) {
151 // NOTE_ALPHA_BLENDING: We use alpha-blending
153 renderModes, debug, trace);
155 this.textRegionUtil = new TextRegionUtil(renderModes);
156 this.regionFPS = GLRegion.create(glp, renderModes, null, 0, 0);
157 this.regionHead = GLRegion.create(glp, renderModes, null, 0, 0);
158 this.regionBottom = GLRegion.create(glp, renderModes, null, 0, 0);
160 setMatrix(0, 0, 0, 0f);
161 getRenderer().setAAQuality(aaQuality);
162 getRenderer().setSampleCount(sampleCount);
163 }
164
165 void switchHeadBox() {
166 setHeadBox( ( headType + 1 ) % 5, true );
167 }
168 public int getHeadBoxType() { return headType; }
169 public AABBox getHeadBox() { return headbox; }
170 public void setHeadBox(final int choice, final boolean resize) {
171 headType = choice % 5 ;
172 switch(headType) {
173 case 0:
174 headtext = null;
175 break;
176
177 case 1:
178 headtext= textX1;
179 break;
180 case 2:
181 headtext= textX2;
182 break;
183 case 3:
184 headtext= text_help;
185 break;
186
187 default:
188 headtext = textXLast;
189 }
190 if(resize && null != headtext) {
191 headbox = font.getMetricBounds(headtext);
192 if( headtext != text_help ) {
193 final float pxSz = FontScale.toPixels(fontSizeHead, dpiV);
194 upsizeWindowSurface(upstream_window, true, (int)(headbox.getWidth()*pxSz*1.1f), (int)(headbox.getHeight()*pxSz*2f));
195 }
196 }
197 }
198
199 public void setHeadBox(final String text, final boolean resize) {
200 headtext = text;
201 if(resize && null != headtext) {
202 headbox = font.getMetricBounds(headtext);
203 if( headtext != text_help ) {
204 final float pxSz = FontScale.toPixels(fontSizeHead, dpiV);
205 upsizeWindowSurface(upstream_window, true, (int)(headbox.getWidth()*pxSz*1.1f), (int)(headbox.getHeight()*pxSz*2f));
206 }
207 }
208 }
209
210 public static void upsizeWindowSurface(final Window window, final boolean off_thread, final int w, final int h) {
211 if( null == window ) {
212 return;
213 }
214 final int w2 = Math.max(window.getSurfaceWidth(), w);
215 final int h2 = Math.max(window.getSurfaceHeight(), h);
216 System.err.println("upsizeWindowSurface: "+window.getSurfaceWidth()+"x"+window.getSurfaceHeight()+" -> "+w+"x"+h+" -> "+w2+"x"+h2);
217 if( off_thread ) {
218 new InterruptSource.Thread() {
219 @Override
220 public void run() {
221 window.setSurfaceSize(w2, h2);
222 } }.start();
223 } else {
224 window.setSurfaceSize(w2, h2);
225 }
226 }
227
228 @Override
229 public void init(final GLAutoDrawable drawable) {
230 super.init(drawable);
231 final Object upObj = drawable.getUpstreamWidget();
232 if( upObj instanceof Window ) {
233 upstream_window = (Window) upObj;
234 final float[] sPpMM = upstream_window.getPixelsPerMM(new float[2]);
235 final float[] sDPI = FontScale.ppmmToPPI( new float[] { sPpMM[0], sPpMM[1] } );
236 dpiV = sDPI[1];
237 ppmmV = sPpMM[1];
238 System.err.println("Using vertical screen DPI of "+dpiV+", "+ppmmV+" pixel/mm");
239 } else {
240 System.err.println("Using vertical default DPI of "+dpiV+", "+ppmmV+" pixel/mm");
241 }
242 fontNameBox = font.getGlyphBounds(fontName, tempT1, tempT2);
243 setHeadBox(headType, true);
244 {
245 final float pixelSizeFName = FontScale.toPixels(fontSizeFName, dpiV);
246 System.err.println("XXX: fontName size "+fontSizeFName+"pt, dpiV "+dpiV+" -> "+pixelSizeFName+"px");
247 System.err.println("XXX: fontName boxM fu "+font.getMetricBoundsFU(fontName));
248 System.err.println("XXX: fontName boxG fu "+font.getGlyphBoundsFU(fontName, tempT1, tempT2));
249 System.err.println("XXX: fontName boxM em "+font.getMetricBounds(fontName));
250 System.err.println("XXX: fontName boxG em "+font.getGlyphBounds(fontName, tempT1, tempT2));
251 System.err.println("XXX: fontName box height px "+(fontNameBox.getHeight() * pixelSizeFName));
252 }
253 }
254
255 @Override
256 public void reshape(final GLAutoDrawable drawable, final int xstart, final int ystart, final int width, final int height) {
257 super.reshape(drawable, xstart, ystart, width, height);
258 final Object upObj = drawable.getUpstreamWidget();
259 if( upObj instanceof Window ) {
260 upstream_window = (Window) upObj;
261 }
262 final float dist = 100f;
263 nearPlaneX0 = nearPlane1Box.getMinX() * dist;
264 nearPlaneY0 = nearPlane1Box.getMinY() * dist;
265 nearPlaneZ0 = nearPlane1Box.getMinZ() * dist;
266 final float xd = nearPlane1Box.getWidth() * dist;
267 final float yd = nearPlane1Box.getHeight() * dist;
268 nearPlaneSx = xd / width;
269 nearPlaneSy = yd / height;
270 nearPlaneS = nearPlaneSy;
271 System.err.printf("Scale: [%f x %f] / [%d x %d] = [%f, %f] -> %f%n", xd, yd, width, height, nearPlaneSx, nearPlaneSy, nearPlaneS);
272 }
273 float nearPlaneX0, nearPlaneY0, nearPlaneZ0, nearPlaneSx, nearPlaneSy, nearPlaneS;
274
275 @Override
276 public void dispose(final GLAutoDrawable drawable) {
277 upstream_window = null;
278 regionFPS.destroy(drawable.getGL().getGL2ES2());
279 regionHead.destroy(drawable.getGL().getGL2ES2());
280 regionBottom.destroy(drawable.getGL().getGL2ES2());
281 super.dispose(drawable);
282 }
283
284 @Override
285 public void display(final GLAutoDrawable drawable) {
286 final Object upObj = drawable.getUpstreamWidget();
287 if( upObj instanceof Window ) {
288 upstream_window = (Window) upObj;
289 }
290 final int width = drawable.getSurfaceWidth();
291 final int height = drawable.getSurfaceHeight();
292 final GL2ES2 gl = drawable.getGL().getGL2ES2();
293
294 gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
296
297 // final float zDistance0 = 500f;
298 // final float zDistance1 = 400f;
299 // final float[] objPos = new float[3];
300 // final float[] winZ = new float[1];
301 // final int[] view = new int[] { 0, 0, drawable.getWidth(), drawable.getHeight() };
302
303 final RegionRenderer renderer = getRenderer();
304 final PMVMatrix4f pmv = renderer.getMatrix();
305 pmv.loadMvIdentity();
306 renderer.setColorStatic(0.1f, 0.1f, 0.1f, 1.0f);
307 final float pixelSizeFName = FontScale.toPixels(fontSizeFName, dpiV);
308 final float pixelSizeHead = FontScale.toPixels(fontSizeHead, dpiV);
309 final float mmSizeHead = pixelSizeHead / ppmmV;
310 final float pixelSizeCenter = FontScale.toPixels(fontSizeCenter, dpiV);
311 final float mmSizeCenter = pixelSizeCenter / ppmmV;
312 final int pass2AAQual = getRenderer().getAAQuality();
313 final int pass2Samples = getRenderer().getSampleCount();
314
315 renderer.enable(gl, true);
316
317 if( drawFPS ) {
318 pmv.pushMv();
319 final float pixelSizeFPS = FontScale.toPixels(fontSizeFPS, dpiV);
320 final float lfps, tfps;
321 final GLAnimatorControl animator = drawable.getAnimator();
322 if( null != animator ) {
323 lfps = animator.getLastFPS();
324 tfps = animator.getTotalFPS();
325 } else {
326 lfps = 0f;
327 tfps = 0f;
328 }
329 final String modeS = Region.getRenderModeString(regionFPS.getRenderModes())+"-q"+pass2AAQual;
330 final String text = String.format("%03.1f/%03.1f fps, v-sync %d, dpiV %.2f %.2f px/mm, font[head %.1fpt %.2fpx %.2fmm, center %.1fpt %.2fpx %.2fmm], %s-samples[%d], blend %b, alpha %d",
331 lfps, tfps, gl.getSwapInterval(), dpiV, ppmmV,
332 fontSizeHead, pixelSizeHead, mmSizeHead,
333 fontSizeCenter, pixelSizeCenter, mmSizeCenter,
334 modeS, pass2Samples,
337
338 // bottom, half line up
339 pmv.translateMv(nearPlaneX0, nearPlaneY0+(nearPlaneS * pixelSizeFPS / 2f), nearPlaneZ0);
340 {
341 final float sxy = nearPlaneS * pixelSizeFPS;
342 pmv.scaleMv(sxy, sxy, 1.0f);
343 }
344 // No cache, keep region alive!
345 TextRegionUtil.drawString3D(gl, regionFPS.clear(gl), renderer, font, text, null, tempT1, tempT2);
346 pmv.popMv();
347 }
348
349 // float dx = width - ( fontNameBox.getWidth() + font.getAdvanceWidth( Glyph.ID_SPACE ) ) * pixelSizeFName;
350 float dx = width - ( fontNameBox.getWidth() + 2 * font.getAdvanceWidth( font.getGlyphID('X') ) ) * pixelSizeFName;
351 float dy = height - fontNameBox.getHeight() * pixelSizeFName;
352 {
353 pmv.pushMv();
354 pmv.translateMv(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0);
355 {
356 final float sxy = nearPlaneS * pixelSizeFName;
357 pmv.scaleMv(sxy, sxy, 1.0f);
358 }
359 // System.err.printf("FontN: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy));
360 textRegionUtil.drawString3D(gl, renderer, font, fontName, null);
361 pmv.popMv();
362 }
363
364 dx = 10f;
365 dy += -fontNameBox.getHeight() * pixelSizeFName - 10f;
366
367 if(null != headtext) {
368 pmv.pushMv();
369 // System.err.printf("Head: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy));
370 pmv.translateMv(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0);
371 {
372 final float sxy = nearPlaneS * pixelSizeHead;
373 pmv.scaleMv(sxy, sxy, 1.0f);
374 }
375 // pmv.glTranslatef(x0, y1, z0);
376 textRegionUtil.drawString3D(gl, renderer, font, headtext, null);
377 pmv.popMv();
378 }
379
380 dy += ( -headbox.getHeight() - font.getLineHeight() ) * pixelSizeCenter;
381
382 {
383 pmv.pushMv();
384 pmv.translateMv(nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy), nearPlaneZ0);
385 // System.err.printf("Bottom: [%f %f] -> [%f %f]%n", dx, dy, nearPlaneX0+(dx*nearPlaneSx), nearPlaneY0+(dy*nearPlaneSy));
387 pmv.rotateMv(getAngleRad(), 0, 1, 0);
388 {
389 final float sxy = nearPlaneS * pixelSizeCenter;
390 pmv.scaleMv(sxy, sxy, 1.0f);
391 }
392 renderer.setColorStatic(0.9f, 0.0f, 0.0f, 1.0f);
393
394 if( bottomTextUseFrustum ) {
395 regionBottom.setFrustum(pmv.getFrustum());
396 }
397 if(!userInput) {
398 if( bottomTextUseFrustum ) {
399 TextRegionUtil.drawString3D(gl, regionBottom.clear(gl), renderer, font, text2, null, tempT1, tempT2);
400 } else {
401 textRegionUtil.drawString3D(gl, renderer, font, text2, null);
402 }
403 } else {
404 if( bottomTextUseFrustum ) {
405 TextRegionUtil.drawString3D(gl, regionBottom.clear(gl), renderer, font, userString.toString(), null, tempT1, tempT2);
406 } else {
407 textRegionUtil.drawString3D(gl, renderer, font, userString.toString(), null);
408 }
409 }
410 pmv.popMv();
411 }
412 renderer.enable(gl, false);
413 }
414 final boolean bottomTextUseFrustum = true;
415
416 public Font getFont() { return font; }
417 public float getFontSizeHead() { return fontSizeHead; }
418
419 public void fontBottomIncr(final int v) {
420 fontSizeCenter = Math.abs((fontSizeCenter + v) % fontSizeModulo) ;
421 dumpMatrix(true);
422 }
423
424 public void fontHeadIncr(final int v) {
425 fontSizeHead = Math.abs((fontSizeHead + v) % fontSizeModulo) ;
426 updateFontNameBox();
427 if(null != headtext) {
428 headbox = font.getMetricBounds(headtext);
429 }
430 }
431
432 public void setFontHeadSize(final int v) {
433 if( 0 < v ) {
434 fontSizeHead = v % fontSizeModulo;
435 updateFontNameBox();
436 if(null != headtext) {
437 headbox = font.getMetricBounds(headtext);
438 }
439 }
440 }
441
442 public boolean nextFontSet() {
443 try {
444 final int set = ( fontSet == FontFactory.UBUNTU ) ? FontFactory.UBUNTU : FontFactory.UBUNTU ;
445 final Font _font = FontFactory.get(set).getDefault();
446 if(null != _font) {
447 fontSet = set;
448 font = _font;
449 updateFontNameBox();
450 return true;
451 }
452 } catch (final IOException ex) {
453 System.err.println("Caught: "+ex.getMessage());
454 }
455 return false;
456 }
457
458 public boolean setFontSet(final int set, final int family, final int stylebits) {
459 try {
460 final Font _font = FontFactory.get(set).get(family, stylebits);
461 if(null != _font) {
462 fontSet = set;
463 font = _font;
464 updateFontNameBox();
465 return true;
466 }
467 } catch (final IOException ex) {
468 System.err.println("Caught: "+ex.getMessage());
469 }
470 return false;
471 }
472
473 public boolean setFont(final Font _font) {
474 if(null != _font) {
475 // fontSet = ???
476 font = _font;
477 updateFontNameBox();
478 return true;
479 }
480 return false;
481 }
482
483 private void updateFontNameBox() {
484 fontName = font.getFullFamilyName()+" (head "+fontSizeHead+"pt)";
485 fontNameBox = font.getMetricBounds(fontName);
486 }
487
488 public boolean isUserInputMode() { return userInput; }
489
490 void dumpMatrix(final boolean bbox) {
491 System.err.println("Matrix: " + getXTran() + "/" + getYTran() + " x"+getZTran() + " @"+getAngleDeg() +" fontSize "+fontSizeCenter);
492 if(bbox) {
493 System.err.println("bbox em: "+font.getMetricBounds(text2));
494 System.err.println("bbox px: "+font.getMetricBounds(text2).scale( nearPlaneS * FontScale.toPixels(fontSizeCenter, dpiV) ) );
495 }
496 }
497
498 KeyAction keyAction = null;
499
500 @Override
501 public void attachInputListenerTo(final GLWindow window) {
502 if ( null == keyAction ) {
503 keyAction = new KeyAction();
504 window.addKeyListener(keyAction);
505 super.attachInputListenerTo(window);
506 }
507 }
508
509 @Override
510 public void detachInputListenerFrom(final GLWindow window) {
511 super.detachInputListenerFrom(window);
512 if ( null == keyAction ) {
513 return;
514 }
515 window.removeKeyListener(keyAction);
516 }
517
518 @Override
519 public void printScreen(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha) throws GLException, IOException {
520 final String fn = font.getFullFamilyName().replace(' ', '_').replace('-', '_');
521 final String modes = Region.getRenderModeString(getRenderModes());
522 final String fsaa = "fsaa"+drawable.getChosenGLCapabilities().getNumSamples();
523 super.printScreen(drawable, dir, tech+"-"+modes, fsaa+"-"+fn+"-text"+getHeadBoxType()+"-"+objName, exportAlpha);
524 }
525
526 float fontHeadScale = 1f;
527
528 public class KeyAction implements KeyListener {
529 @Override
530 public void keyPressed(final KeyEvent e) {
531 if(userInput) {
532 return;
533 }
534 final short s = e.getKeySymbol();
535 if(s == KeyEvent.VK_3) {
536 if( e.isAltDown() ) {
537 fontHeadIncr(1);
538 } else {
540 }
541 }
542 else if(s == KeyEvent.VK_4) {
543 if( e.isAltDown() ) {
544 fontHeadIncr(-1);
545 } else {
546 fontBottomIncr(-1);
547 }
548 }
549 else if(s == KeyEvent.VK_H) {
550 switchHeadBox();
551 }
552 else if(s == KeyEvent.VK_F) {
553 drawFPS = !drawFPS;
554 }
555 else if(s == KeyEvent.VK_SPACE) {
556 nextFontSet();
557 }
558 else if(s == KeyEvent.VK_I) {
559 userInput = true;
560 setIgnoreInput(true);
561 }
562 }
563
564 @Override
565 public void keyReleased(final KeyEvent e) {
566 if( !e.isPrintableKey() || e.isAutoRepeat() ) {
567 return;
568 }
569 if(userInput) {
570 final short k = e.getKeySymbol();
571 if( KeyEvent.VK_ENTER == k ) {
572 userInput = false;
573 setIgnoreInput(false);
574 } else if( KeyEvent.VK_BACK_SPACE == k && userString.length()>0) {
575 userString.deleteCharAt(userString.length()-1);
576 } else {
577 final char c = e.getKeyChar();
578 if( font.isPrintableChar( c ) ) {
579 userString.append(c);
580 }
581 }
582 }
583 }
584 }
585}
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
Definition: Region.java:62
static String getRenderModeString(final int renderModes)
Returns a unique technical description string for renderModes as follows:
Definition: Region.java:251
final void setFrustum(final Frustum frustum)
Set Frustum culling for addOutlineShape(OutlineShape, AffineTransform, float[]).
Definition: Region.java:407
final int getRenderModes()
Returns bit-field of render modes, see create(..).
Definition: Region.java:344
A GLRegion is the OGL binding of one or more OutlineShapes Defined by its vertices and generated tria...
Definition: GLRegion.java:70
final GLRegion clear(final GL2ES2 gl)
Clears all buffers, i.e.
Definition: GLRegion.java:436
final void destroy(final GL2ES2 gl)
Delete and clear the associated OGL objects.
Definition: GLRegion.java:460
static GLRegion create(final GLProfile glp, int renderModes, final TextureSequence colorTexSeq, final int pass2TexUnit, final int initialVerticesCount, final int initialIndicesCount)
Create a GLRegion using the passed render mode.
Definition: GLRegion.java:109
final void enable(final GL2ES2 gl, final boolean enable)
Enabling or disabling the RenderState's current shader program.
final int getAAQuality()
Returns pass2 AA-quality rendering value for Graph Region AA render-modes: Region#VBAA_RENDERING_BIT.
final void setColorStatic(final Vec4f rgbaColor)
final PMVMatrix4f getMatrix()
Borrow the current PMVMatrix4f.
final int setSampleCount(final int v)
Sets pass2 AA sample count clipped to the range [Region#MIN_AA_SAMPLE_COUNT..Region#MAX_AA_SAMPLE_COU...
static final GLCallback defaultBlendDisable
Default GL#GL_BLEND disable GLCallback, simply turning-off the GL#GL_BLEND state and turning-on depth...
final int setAAQuality(final int v)
Sets pass2 AA-quality rendering value clipped to the range [Region#MIN_AA_QUALITY....
final boolean hintBitsSet(final int mask)
static final GLCallback defaultBlendEnable
Default GL#GL_BLEND enable GLCallback, turning-off depth writing via GL#glDepthMask(boolean) if Rende...
final int getSampleCount()
Returns pass2 AA sample count for Graph Region AA render-modes: VBAA_RENDERING_BIT or Region#MSAA_REN...
static RegionRenderer create()
Create a hardware accelerated RegionRenderer including its RenderState composition.
The RenderState is owned by RegionRenderer.
static final int BITHINT_BLENDING_ENABLED
Bitfield hint, if set stating enabled GL#GL_BLEND, otherwise disabled.
static final int BITHINT_GLOBAL_DEPTH_TEST_ENABLED
Bitfield hint, if set stating globally enabled GL#GL_DEPTH_TEST, otherwise disabled.
Text Type Rendering Utility Class adding the Font.Glyphs OutlineShape to a GLRegion.
AABBox drawString3D(final GL2ES2 gl, final RegionRenderer renderer, final Font font, final CharSequence str, final Vec4f rgbaColor)
Render the string in 3D space w.r.t.
The optional property jogamp.graph.font.ctor allows user to specify the FontConstructor implementatio...
static final FontSet get(final int font)
static final int UBUNTU
Ubuntu is the default font family, {@value}.
Simple static font scale methods for unit conversions.
Definition: FontScale.java:37
static float[] ppmmToPPI(final float[] ppmm)
Converts [1/mm] to [1/inch] in place.
Definition: FontScale.java:105
static float toPixels(final float points, final float res_dpi)
Converts typical font size in points and screen resolution in dpi (pixels-per-inch) to font size in p...
Definition: FontScale.java:76
Axis Aligned Bounding Box.
Definition: AABBox.java:54
final float getWidth()
Definition: AABBox.java:879
final float getHeight()
Definition: AABBox.java:883
final AABBox scale(final float s)
Scale this AABBox by a constant around fixed center.
Definition: AABBox.java:750
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
final PMVMatrix4f translateMv(final float x, final float y, final float z)
Translate the modelview matrix.
final PMVMatrix4f scaleMv(final float x, final float y, final float z)
Scale the modelview matrix.
final PMVMatrix4f rotateMv(final float ang_rad, final float x, final float y, final float z)
Rotate the modelview matrix by the given axis and angle in radians.
final PMVMatrix4f loadMvIdentity()
Load the modelview matrix with the values of the given Matrix4f.
final Frustum getFrustum()
Returns the frustum, derived from projection x modelview.
final PMVMatrix4f popMv()
Pop the modelview matrix from its stack.
final PMVMatrix4f pushMv()
Push the modelview matrix to its stack, while preserving its values.
final boolean isAutoRepeat()
getModifiers() contains AUTOREPEAT_MASK.
final boolean isAltDown()
getModifiers() contains ALT_MASK.
final char getKeyChar()
Returns the UTF-16 character reflecting the key symbol incl.
Definition: KeyEvent.java:161
static final short VK_ENTER
Constant for the ENTER key, i.e.
Definition: KeyEvent.java:446
final short getKeySymbol()
Returns the virtual key symbol reflecting the current keyboard layout.
Definition: KeyEvent.java:176
static final short VK_4
See VK_0.
Definition: KeyEvent.java:561
static final short VK_SPACE
Constant for the SPACE function key.
Definition: KeyEvent.java:505
static final short VK_H
See VK_A.
Definition: KeyEvent.java:609
static final short VK_F
See VK_A.
Definition: KeyEvent.java:605
static boolean isPrintableKey(final short uniChar, final boolean isKeyChar)
Returns true if given uniChar represents a printable character, i.e.
Definition: KeyEvent.java:316
static final short VK_I
See VK_A.
Definition: KeyEvent.java:611
static final short VK_3
See VK_0.
Definition: KeyEvent.java:559
static final short VK_BACK_SPACE
Constant for the BACK SPACE key "\b", matching ASCII.
Definition: KeyEvent.java:431
An implementation of GLAutoDrawable and Window interface, using a delegated Window instance,...
Definition: GLWindow.java:121
final void addKeyListener(final KeyListener l)
Appends the given com.jogamp.newt.event.KeyListener to the end of the list.
Definition: GLWindow.java:902
final void removeKeyListener(final KeyListener l)
Definition: GLWindow.java:912
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
final AABBox nearPlane1Box
Describing the bounding box in model-coordinates of the near-plane parallel at distance one.
void setMatrix(final float xtrans, final float ytrans, final float zTran, final float angle)
void keyReleased(final KeyEvent e)
A key has been released, excluding auto-repeat modifier keys.
void keyPressed(final KeyEvent e)
A key has been pressed, excluding auto-repeat modifier keys.
void printScreen(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha)
void reshape(final GLAutoDrawable drawable, final int xstart, final int ystart, final int width, final int height)
Called by the drawable during the first repaint after the component has been resized.
void attachInputListenerTo(final GLWindow window)
Attach the input listener to the window.
void dispose(final GLAutoDrawable drawable)
Notifies the listener to perform the release of all OpenGL resources per GLContext,...
GPUTextRendererListenerBase01(final GLProfile glp, final int renderModes, final int aaQuality, final int sampleCount, final boolean blending, final boolean debug, final boolean trace)
void init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
boolean setFontSet(final int set, final int family, final int stylebits)
void display(final GLAutoDrawable drawable)
Called by the drawable to initiate OpenGL rendering by the client.
static void upsizeWindowSurface(final Window window, final boolean off_thread, final int w, final int h)
static final int FAMILY_LIGHT
Font family LIGHT, {@value}.
Definition: FontSet.java:39
Font getDefault()
Returns the family FAMILY_REGULAR with STYLE_NONE as retrieved with get(int, int).
Font get(int family, int stylebits)
static final int STYLE_NONE
Zero style, {@value}.
Definition: FontSet.java:51
Interface wrapper for font implementation.
Definition: Font.java:60
AABBox getMetricBounds(final CharSequence string)
Returns metric-bounds in font em-size.
float getLineHeight()
Returns line height, baseline-to-baseline in em-size [0..1], composed from ‘hhea’ table entries.
AABBox getMetricBoundsFU(final CharSequence string)
Returns metric-bounds in font-units.
String getFullFamilyName()
Shall return the family and subfamily name, separated a dash.
AABBox getGlyphBounds(final CharSequence string)
Try using getGlyphBounds(CharSequence, AffineTransform, AffineTransform) to reuse AffineTransform ins...
int getGlyphID(final char codepoint)
Returns the Glyph ID mapped to given UTF16 (unicode) codepoint symbol.
String toString()
Returns getFullFamilyName().
AABBox getGlyphBoundsFU(final CharSequence string)
Try using getGlyphBoundsFU(CharSequence, AffineTransform, AffineTransform) to reuse AffineTransform i...
boolean isPrintableChar(final char c)
float getAdvanceWidth(final int glyphID)
Returns advance-width of given glyphID in font em-size [0..1], sourced from hmtx table - same as Glyp...
int getAlphaBits()
Returns the number of bits for the color buffer's alpha component.
int getSurfaceWidth()
Returns the width of the client area excluding insets (window decorations) in pixel units.
int getSurfaceHeight()
Returns the height of the client area excluding insets (window decorations) in pixel units.
Specifying NEWT's Window functionality:
Definition: Window.java:115
float[] getPixelsPerMM(final float[] ppmmStore)
Returns the pixels per millimeter of this window's NativeSurface according to the main monitor's curr...
void setSurfaceSize(int pixelWidth, int pixelHeight)
Sets the size of the window's surface in pixel units which claims the window's client area excluding ...
Listener for KeyEvents.
An animator control interface, which implementation may drive a com.jogamp.opengl....
A higher-level abstraction than GLDrawable which supplies an event based mechanism (GLEventListener) ...
GLAnimatorControl getAnimator()
GL getGL()
Returns the GL pipeline object this GLAutoDrawable uses.
Object getUpstreamWidget()
Method may return the upstream UI toolkit object holding this GLAutoDrawable instance,...
GL2ES2 getGL2ES2()
Casts this object to the GL2ES2 interface.
int getSwapInterval()
Return the current swap interval.
GLCapabilitiesImmutable getChosenGLCapabilities()
Fetches the GLCapabilitiesImmutable corresponding to the chosen OpenGL capabilities (pixel format / v...
int getSurfaceWidth()
Returns the width of this GLDrawable's surface client area in pixel units.
int getSurfaceHeight()
Returns the height of this GLDrawable's surface client area in pixel units.
static final int GL_COLOR_BUFFER_BIT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_COLOR_BUFFER_BIT" wit...
Definition: GL.java:390
void glClearColor(float red, float green, float blue, float alpha)
Entry point to C language function: void {@native glClearColor}(GLfloat red, GLfloat green,...
void glClear(int mask)
Entry point to C language function: void {@native glClear}(GLbitfield mask) Part of GL_ES_VERSION_...
static final int GL_DEPTH_BUFFER_BIT
GL_ES_VERSION_2_0, GL_VERSION_1_1, GL_VERSION_1_0, GL_VERSION_ES_1_0 Define "GL_DEPTH_BUFFER_BIT" wit...
Definition: GL.java:738