JOGL v2.6.0-rc-20250712
JOGL, High-Performance Graphics Binding for Java™ (public API).
TestTextRendererNEWTBugXXXX.java
Go to the documentation of this file.
1/**
2 * Copyright 2012-2024 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.test.junit.graph;
29
30import java.io.File;
31import java.io.IOException;
32import java.util.Locale;
33
34import com.jogamp.opengl.GL;
35import com.jogamp.opengl.GL2ES2;
36import com.jogamp.opengl.GLCapabilities;
37import com.jogamp.opengl.GLDrawable;
38import com.jogamp.opengl.GLException;
39import com.jogamp.opengl.GLProfile;
40
41import org.junit.Assert;
42import org.junit.Test;
43import org.junit.FixMethodOrder;
44import org.junit.runners.MethodSorters;
45
46import com.jogamp.graph.curve.Region;
47import com.jogamp.graph.curve.opengl.RenderState;
48import com.jogamp.graph.curve.opengl.RegionRenderer;
49import com.jogamp.graph.curve.opengl.TextRegionUtil;
50import com.jogamp.graph.font.Font;
51import com.jogamp.math.geom.AABBox;
52import com.jogamp.math.util.PMVMatrix4f;
53import com.jogamp.opengl.test.junit.util.NEWTGLContext;
54import com.jogamp.opengl.test.junit.util.UITestCase;
55import com.jogamp.opengl.util.GLReadBufferUtil;
56
57
58@FixMethodOrder(MethodSorters.NAME_ASCENDING)
60 static long duration = 100; // ms
61 static boolean forceES2 = false;
62 static boolean forceGL3 = false;
63 static boolean mainRun = false;
64 static boolean useMSAA = true;
65 static boolean onlyIssues = false;
66
67 static final float fontSize = 24;
68
69 static int atoi(final String a) {
70 try {
71 return Integer.parseInt(a);
72 } catch (final Exception ex) { throw new RuntimeException(ex); }
73 }
74
75 public static void main(final String args[]) throws IOException {
76 mainRun = true;
77 for(int i=0; i<args.length; i++) {
78 if(args[i].equals("-time")) {
79 i++;
80 duration = atoi(args[i]);
81 } else if(args[i].equals("-noMSAA")) {
82 useMSAA = false;
83 } else if(args[i].equals("-es2")) {
84 forceES2 = true;
85 } else if(args[i].equals("-gl3")) {
86 forceGL3 = true;
87 }
88 }
89 final String tstname = TestTextRendererNEWTBugXXXX.class.getName();
90 org.junit.runner.JUnitCore.main(tstname);
91 }
92
93 static void sleep() {
94 try {
95 System.err.println("** new frame ** (sleep: "+duration+"ms)");
96 Thread.sleep(duration);
97 } catch (final InterruptedException ie) {}
98 }
99
100 @Test
101 public void test00All() throws InterruptedException, GLException, IOException {
102 testTextRendererImpl(FontSet01.getSet01(), Region.VBAA_RENDERING_BIT, 4, false);
103 }
104 @Test
105 public void test01OnlyIssues() throws InterruptedException, GLException, IOException {
106 testTextRendererImpl(FontSet01.getSet01(), Region.VBAA_RENDERING_BIT, 4, true);
107 }
108 void testTextRendererImpl(final Font[] fonts, final int renderModes, final int sampleCount, final boolean onlyIssues) throws InterruptedException, GLException, IOException {
109 final GLProfile glp;
110 if(forceGL3) {
111 glp = GLProfile.get(GLProfile.GL3);
112 } else if(forceES2) {
114 } else {
115 glp = GLProfile.getGL2ES2();
116 }
117
118 final GLCapabilities caps = new GLCapabilities( glp );
119 caps.setAlphaBits(4);
120 if( 0 < sampleCount && !Region.isVBAA(renderModes) ) {
121 caps.setSampleBuffers(true);
122 caps.setNumSamples(sampleCount);
123 }
124 caps.setOnscreen(false);
125 System.err.println("Requested: "+caps);
126 System.err.println("Requested: "+Region.getRenderModeString(renderModes));
127
128 final int totalHeight = ( (int)fontSize + 1 ) * ( onlyIssues ? 3 : 6 ) * fonts.length;
129 final NEWTGLContext.WindowContext winctx =
130 NEWTGLContext.createWindow(caps, 800, totalHeight, true);
131 final GLDrawable drawable = winctx.context.getGLDrawable();
132 final GL2ES2 gl = winctx.context.getGL().getGL2ES2();
133
134 Assert.assertEquals(GL.GL_NO_ERROR, gl.glGetError());
135
136 System.err.println("Chosen: "+winctx.window.getChosenCapabilities());
137
138 final RegionRenderer renderer = RegionRenderer.create(RegionRenderer.defaultBlendEnable, RegionRenderer.defaultBlendDisable);
139 renderer.setHintBits(RenderState.BITHINT_GLOBAL_DEPTH_TEST_ENABLED);
140 final TextRegionUtil textRenderUtil = new TextRegionUtil(renderModes);
141
142 // init
143 gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
144 renderer.init(gl);
145 renderer.setColorStatic(0.1f, 0.1f, 0.1f, 1.0f);
146 screenshot = new GLReadBufferUtil(false, false);
147
148 // reshape
149 gl.glViewport(0, 0, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
150
151 // renderer.reshapePerspective(gl, 45.0f, drawable.getWidth(), drawable.getHeight(), 0.1f, 1000.0f);
152 renderer.reshapeOrtho(drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), 0.1f, 1000.0f);
153
154 final int[] sampleCountIO = { sampleCount };
155 // display
156 gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
157 for(int i=0; i<fonts.length; i++) {
158 final Font font = fonts[i];
159 renderString(drawable, gl, renderer, font, textRenderUtil, font.getFullFamilyName()+": "+issues, 0, 0==i?0:-1, -1000, sampleCountIO);
160 if(!onlyIssues) {
161 renderString(drawable, gl, renderer, font, textRenderUtil, "012345678901234567890123456789", 0, -1, -1000, sampleCountIO);
162 renderString(drawable, gl, renderer, font, textRenderUtil, "abcdefghijklmnopqrstuvwxyz", 0, -1, -1000, sampleCountIO);
163 renderString(drawable, gl, renderer, font, textRenderUtil, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, -1, -1000, sampleCountIO);
164 }
165 renderString(drawable, gl, renderer, font, textRenderUtil, "", 0, -1, -1000, sampleCountIO);
166 renderString(drawable, gl, renderer, font, textRenderUtil, "", 0, -1, -1000, sampleCountIO);
167 }
168
169 drawable.swapBuffers();
170 printScreen(renderModes, drawable, gl, false, sampleCount);
171
172 sleep();
173
174 // dispose
175 screenshot.dispose(gl);
176 renderer.destroy(gl);
177
178 NEWTGLContext.destroyWindow(winctx);
179 }
180
181 private static final String issues = "m M n u 8 g q Q";
182 private GLReadBufferUtil screenshot;
183 int lastRow = -1;
184
185 void renderString(final GLDrawable drawable, final GL2ES2 gl, final RegionRenderer renderer, final Font font, final TextRegionUtil textRenderUtil, final String text, final int column, int row, final int z0, final int[] sampleCount) {
186 final int height = drawable.getSurfaceHeight();
187
188 float dx = 0;
189 float dy = height;
190 if(0>row) {
191 row = lastRow + 1;
192 }
193 final AABBox textBox = font.getMetricBounds(text);
194 dx += fontSize * font.getAdvanceWidth( font.getGlyphID( 'X' ) ) * column;
195 dy -= fontSize * textBox.getHeight() * ( row + 1 );
196
197 final PMVMatrix4f pmv = renderer.getMatrix();
198 pmv.loadMvIdentity();
199 pmv.translateMv(dx, dy, z0);
200 {
201 final float sxy = fontSize / font.getMetrics().getUnitsPerEM();
202 pmv.scaleMv(sxy, sxy, 1.0f);
203 }
204 textRenderUtil.drawString3D(gl, renderer, font, text, null);
205
206 lastRow = row;
207 }
208
209 private int screenshot_num = 0;
210
211 public void printScreen(final int renderModes, final GLDrawable drawable, final GL gl, final boolean exportAlpha, final int sampleCount) throws GLException, IOException {
212 final String dir = "./";
213 final String objName = getSimpleTestName(".")+"-snap"+screenshot_num;
214 screenshot_num++;
215 final String modeS = Region.getRenderModeString(renderModes);
216 final String bname = String.format((Locale)null, "%s-msaa%02d-fontsz%02.1f-%03dx%03d-%s%04d", objName,
217 drawable.getChosenGLCapabilities().getNumSamples(),
218 TestTextRendererNEWTBugXXXX.fontSize, drawable.getSurfaceWidth(), drawable.getSurfaceHeight(), modeS, sampleCount);
219 final String filename = dir + bname +".png";
220 if(screenshot.readPixels(gl, false)) {
221 screenshot.write(new File(filename));
222 }
223 }
224
225}
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
static final int VBAA_RENDERING_BIT
Rendering-Mode bit for Region.
Definition: Region.java:115
void setAlphaBits(final int alphaBits)
Sets the number of bits requested for the color buffer's alpha component.
void setOnscreen(final boolean onscreen)
Sets whether the surface shall be on- or offscreen.
Specifies a set of OpenGL capabilities.
void setNumSamples(final int numSamples)
If sample buffers are enabled, indicates the number of buffers to be allocated.
void setSampleBuffers(final boolean enable)
Defaults to false.
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Specifies the the OpenGL profile.
Definition: GLProfile.java:77
static final String GL3
The desktop OpenGL core profile 3.x, with x >= 1.
Definition: GLProfile.java:576
static final String GLES2
The embedded OpenGL profile ES 2.x, with x >= 0.
Definition: GLProfile.java:585
static GLProfile get(final AbstractGraphicsDevice device, String profile)
Returns a GLProfile object.
static GLProfile getGL2ES2(final AbstractGraphicsDevice device)
Returns the GL2ES2 profile implementation, hence compatible w/ GL2ES2.
Definition: GLProfile.java:913
void printScreen(final int renderModes, final GLDrawable drawable, final GL gl, final boolean exportAlpha, final int sampleCount)
Interface wrapper for font implementation.
Definition: Font.java:60
An abstraction for an OpenGL rendering target.
Definition: GLDrawable.java:51