JOGL v2.6.0-rc-20250706
JOGL, High-Performance Graphics Binding for Java™ (public API).
GPURendererListenerBase01.java
Go to the documentation of this file.
1/**
2 * Copyright 2010-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;
32
33import com.jogamp.opengl.FPSCounter;
34import com.jogamp.opengl.GL;
35import com.jogamp.opengl.GL2ES2;
36import com.jogamp.opengl.GLAnimatorControl;
37import com.jogamp.opengl.GLAutoDrawable;
38import com.jogamp.opengl.GLEventListener;
39import com.jogamp.opengl.GLException;
40import com.jogamp.opengl.GLPipelineFactory;
41import com.jogamp.opengl.GLRunnable;
42
43import com.jogamp.graph.curve.Region;
44import com.jogamp.graph.curve.opengl.GLRegion;
45import com.jogamp.graph.curve.opengl.RegionRenderer;
46import com.jogamp.graph.curve.opengl.RenderState;
47import com.jogamp.graph.font.FontScale;
48import com.jogamp.math.FloatUtil;
49import com.jogamp.math.Recti;
50import com.jogamp.math.Vec3f;
51import com.jogamp.math.geom.AABBox;
52import com.jogamp.math.util.PMVMatrix4f;
53import com.jogamp.newt.Window;
54import com.jogamp.newt.event.KeyEvent;
55import com.jogamp.newt.event.KeyListener;
56import com.jogamp.newt.opengl.GLWindow;
57import com.jogamp.opengl.util.GLReadBufferUtil;
58
59/**
60 *
61 * Action Keys:
62 * - 1/2: zoom in/out
63 * - 6/7: 2nd pass texture size
64 * - 0/9: rotate
65 * - Q/W: change weight
66 * - v: toggle v-sync
67 * - s: screenshot
68 */
69public abstract class GPURendererListenerBase01 implements GLEventListener {
70 private final RegionRenderer renderer;
71 private final int renderModes;
72 private final boolean debug;
73 private final boolean trace;
74
75 protected GLRegion region;
76
77 private final GLReadBufferUtil screenshot;
78
79 private KeyAction keyAction;
80
81 private volatile GLAutoDrawable autoDrawable = null;
82
83 private final float[] position = new float[] {0,0,0};
84
85 protected final float zNear = 0.1f, zFar = 7000f;
86 /** Describing the bounding box in model-coordinates of the near-plane parallel at distance one. */
87 protected final AABBox nearPlane1Box;
88
89 private float xTran = -10;
90 private float yTran = 10;
91 private float ang = 0f;
92 private float zTran = -70f;
93
94 protected volatile float weight = 1.0f;
95 boolean ignoreInput = false;
96
97 public GPURendererListenerBase01(final RegionRenderer renderer, final int renderModes, final boolean debug, final boolean trace) {
98 this.renderer = renderer;
99 this.renderModes = renderModes;
100 this.debug = debug;
101 this.trace = trace;
102 this.screenshot = new GLReadBufferUtil(false, false);
103 nearPlane1Box = new AABBox();
104 }
105
106 public final RegionRenderer getRenderer() { return renderer; }
107 public final int getRenderModes() { return renderModes; }
108 public final float getZTran() { return zTran; }
109 public final float getXTran() { return xTran; }
110 public final float getYTran() { return yTran; }
111 public final float getAngleDeg() { return ang; }
112 public final float getAngleRad() { return FloatUtil.adegToRad(ang); }
113 public final float[] getPosition() { return position; }
114
115 public void setMatrix(final float xtrans, final float ytrans, final float zTran, final float angle) {
116 this.xTran = xtrans;
117 this.yTran = ytrans;
118 this.zTran = zTran;
119 this.ang = angle;
120 }
121
122 @Override
123 public void init(final GLAutoDrawable drawable) {
124 final Object upObj = drawable.getUpstreamWidget();
125 if( upObj instanceof Window ) {
126 final Window window = (Window) upObj;
127 final float[] sPpMM = window.getPixelsPerMM(new float[2]);
128 final float[] sDPI = FontScale.ppmmToPPI( new float[] { sPpMM[0], sPpMM[1] } );
129 System.err.println("DPI "+sDPI[0]+" x "+sDPI[1]+", "+sPpMM[0]+" x "+sPpMM[1]+" pixel/mm");
130
131 final float[] hasSurfacePixelScale1 = window.getCurrentSurfaceScale(new float[2]);
132 System.err.println("HiDPI PixelScale: "+hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)");
133 }
134 autoDrawable = drawable;
135 GL2ES2 gl = drawable.getGL().getGL2ES2();
136 if(debug) {
137 gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Debug", null, gl, null) ).getGL2ES2();
138 }
139 if(trace) {
140 gl = gl.getContext().setGL( GLPipelineFactory.create("com.jogamp.opengl.Trace", null, gl, new Object[] { System.err } ) ).getGL2ES2();
141 }
142 System.err.println("*** "+gl.getContext().getGLVersion());
143 System.err.println("*** GLDebugMessage "+gl.getContext().isGLDebugMessageEnabled());
144 MSAATool.dump(drawable);
145 gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
146 getRenderer().init(gl);
147 }
148
149 public static void mapWin2ObjectCoords(final PMVMatrix4f pmv, final Recti view,
150 final float zNear, final float zFar,
151 final float orthoX, final float orthoY, final float orthoDist,
152 final float[] winZ, final Vec3f objPos) {
153 winZ[0] = (1f/zNear-1f/orthoDist)/(1f/zNear-1f/zFar);
154 pmv.mapWinToObj(orthoX, orthoY, winZ[0], view, objPos);
155 }
156
157 @Override
158 public void reshape(final GLAutoDrawable drawable, final int xstart, final int ystart, final int width, final int height) {
159 final PMVMatrix4f pmv = renderer.getMatrix();
160 renderer.reshapePerspective(FloatUtil.QUARTER_PI, width, height, zNear, zFar);
161 pmv.loadMvIdentity();
162 System.err.printf("Reshape: zNear %f, zFar %f%n", zNear, zFar);
163 System.err.printf("Reshape: Frustum: %s%n", pmv.getFrustum());
164 {
165 final float orthoDist = 1f;
166 final Vec3f obj00Coord = new Vec3f();
167 final Vec3f obj11Coord = new Vec3f();
168 final float[] winZ = new float[1];
169 final Recti view = new Recti(0, 0, width, height);
170
171 mapWin2ObjectCoords(pmv, view, zNear, zFar, 0f, 0f, orthoDist, winZ, obj00Coord);
172 System.err.printf("Reshape: mapped.00: [%f, %f, %f], winZ %f -> [%s]%n", 0f, 0f, orthoDist, winZ[0], obj00Coord);
173
174 mapWin2ObjectCoords(pmv, view, zNear, zFar, width, height, orthoDist, winZ, obj11Coord);
175 System.err.printf("Reshape: mapped.11: [%f, %f, %f], winZ %f -> [%s]%n", (float)width, (float)height, orthoDist, winZ[0], obj11Coord);
176
177 nearPlane1Box.setSize( obj00Coord, obj11Coord );
178 System.err.printf("Reshape: dist1Box: %s%n", nearPlane1Box);
179 }
180
181 dumpMatrix();
182 // System.err.println("Reshape: "+renderer.getRenderState());
183 }
184
185 @Override
186 public void dispose(final GLAutoDrawable drawable) {
187 autoDrawable = null;
188 final GL2ES2 gl = drawable.getGL().getGL2ES2();
189 if(null != region) {
190 region.destroy(gl);
191 }
192 screenshot.dispose(gl);
193 renderer.destroy(gl);
194 }
195
196 public void zoom(final int v){
197 zTran += v;
198 dumpMatrix();
199 }
200
201 public void move(final float x, final float y){
202 xTran += x;
203 yTran += y;
204 dumpMatrix();
205 }
206 public void rotate(final float delta){
207 ang += delta;
208 ang %= 360.0f;
209 dumpMatrix();
210 }
211 public void editGlobalWeight(final float delta) {
212 if( !RenderState.isWeightValid(weight+delta) ) {
213 return;
214 }
215 weight += delta;
216 System.err.println("Global Weight: "+ weight);
217 }
218
219 void dumpMatrix() {
220 System.err.println("Matrix: " + xTran + " / " + yTran + " / "+zTran + " @ "+ang);
221 }
222
223 /** Attach the input listener to the window */
224 public void attachInputListenerTo(final GLWindow window) {
225 if ( null == keyAction ) {
226 keyAction = new KeyAction();
227 window.addKeyListener(keyAction);
228 }
229 }
230
231 public void detachInputListenerFrom(final GLWindow window) {
232 if ( null == keyAction ) {
233 return;
234 }
235 window.removeKeyListener(keyAction);
236 }
237
238 public void printScreen(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha) throws GLException, IOException {
239 final String sw = String.format("_q%01d_s%02d-%s-Z%04d-snap%02d-%03dx%03d",
240 getRenderer().getAAQuality(), getRenderer().getSampleCount(), objName, (int)Math.abs(zTran),
241 screenshot_num++, drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
242 final String filename = dir + tech + sw +".png";
243 if(screenshot.readPixels(drawable.getGL(), false)) {
244 screenshot.write(new File(filename));
245 }
246 }
247 private int screenshot_num = 0;
248
249 public void printScreenOnGLThread(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha) {
250 drawable.invoke(true, new GLRunnable() {
251 @Override
252 public boolean run(final GLAutoDrawable drawable) {
253 try {
254 printScreen(drawable, dir, tech, objName, exportAlpha);
255 } catch (final GLException e) {
256 e.printStackTrace();
257 } catch (final IOException e) {
258 e.printStackTrace();
259 }
260 return true;
261 }
262 });
263 }
264
265 public void setIgnoreInput(final boolean v) {
266 ignoreInput = v;
267 }
268 public boolean getIgnoreInput() {
269 return ignoreInput;
270 }
271
272 public class KeyAction implements KeyListener {
273 @Override
274 public void keyPressed(final KeyEvent arg0) {
275 if(ignoreInput) {
276 return;
277 }
278
279 if(arg0.getKeyCode() == KeyEvent.VK_1){
280 zoom(10);
281 }
282 else if(arg0.getKeyCode() == KeyEvent.VK_2){
283 zoom(-10);
284 }
285 else if(arg0.getKeyCode() == KeyEvent.VK_UP){
286 move(0, -1);
287 }
288 else if(arg0.getKeyCode() == KeyEvent.VK_DOWN){
289 move(0, 1);
290 }
291 else if(arg0.getKeyCode() == KeyEvent.VK_LEFT){
292 move(-1, 0);
293 }
294 else if(arg0.getKeyCode() == KeyEvent.VK_RIGHT){
295 move(1, 0);
296 }
297 else if(arg0.getKeyCode() == KeyEvent.VK_6){
298 getRenderer().setSampleCount( getRenderer().getSampleCount() - 1 );
299 System.err.println("Sample Count: " + getRenderer().getSampleCount());
300 }
301 else if(arg0.getKeyCode() == KeyEvent.VK_7){
302 getRenderer().setSampleCount( getRenderer().getSampleCount() + 1 );
303 System.err.println("Sample Count: " + getRenderer().getSampleCount());
304 }
305 else if(arg0.getKeyCode() == KeyEvent.VK_0){
306 rotate(1);
307 }
308 else if(arg0.getKeyCode() == KeyEvent.VK_9){
309 rotate(-1);
310 }
311 else if(arg0.getKeyCode() == KeyEvent.VK_Q){
312 editGlobalWeight(-0.1f);
313 }
314 else if(arg0.getKeyCode() == KeyEvent.VK_W){
315 editGlobalWeight(0.1f);
316 }
317 else if(arg0.getKeyCode() == KeyEvent.VK_V) {
318 if(null != autoDrawable) {
319 autoDrawable.invoke(false, new GLRunnable() {
320 @Override
321 public boolean run(final GLAutoDrawable drawable) {
322 final GL gl = drawable.getGL();
323 final int _i = gl.getSwapInterval();
324 final int i;
325 switch(_i) {
326 case 0: i = -1; break;
327 case -1: i = 1; break;
328 case 1: i = 0; break;
329 default: i = 1; break;
330 }
331 gl.setSwapInterval(i);
332
333 final GLAnimatorControl a = drawable.getAnimator();
334 if( null != a ) {
335 a.resetFPSCounter();
336 }
337 if(drawable instanceof FPSCounter) {
338 ((FPSCounter)drawable).resetFPSCounter();
339 }
340 System.err.println("Swap Interval: "+_i+" -> "+i+" -> "+gl.getSwapInterval());
341 return true;
342 }
343 });
344 }
345 }
346 else if(arg0.getKeyCode() == KeyEvent.VK_S){
347 if(null != autoDrawable) {
348 final String modeS = Region.getRenderModeString(renderModes);
349 final String type = modeS + ( Region.hasVariableWeight(renderModes) ? "-vc" : "-uc" ) ;
350 printScreenOnGLThread(autoDrawable, "./", "demo-"+type, "", false);
351 }
352 }
353 }
354 @Override
355 public void keyReleased(final KeyEvent arg0) {}
356 }
357}
Abstract Outline shape representation define the method an OutlineShape(s) is bound and rendered.
Definition: Region.java:62
static boolean hasVariableWeight(final int renderModes)
Returns true if render mode capable of variable weights, i.e.
Definition: Region.java:222
static String getRenderModeString(final int renderModes)
Returns a unique technical description string for renderModes as follows:
Definition: Region.java:251
A GLRegion is the OGL binding of one or more OutlineShapes Defined by its vertices and generated tria...
Definition: GLRegion.java:70
final void destroy(final GL2ES2 gl)
Delete and clear the associated OGL objects.
Definition: GLRegion.java:460
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...
final void init(final GL2ES2 gl)
Initialize shader and bindings for GPU based rendering bound to the given GL object's GLContext if no...
final void reshapePerspective(final float angle_rad, final int width, final int height, final float near, final float far)
Perspective projection, method also calls reshapeNotify(int, int, int, int).
final void destroy(final GL2ES2 gl)
Deletes all ShaderPrograms and nullifies its references including RenderState#destroy(GL2ES2).
The RenderState is owned by RegionRenderer.
static boolean isWeightValid(final float v)
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
Basic Float math utility functions.
Definition: FloatUtil.java:83
static final float QUARTER_PI
The value PI/4, i.e.
static float adegToRad(final float arc_degree)
Converts arc-degree to radians.
Rectangle with x, y, width and height integer components.
Definition: Recti.java:34
3D Vector based upon three float components.
Definition: Vec3f.java:37
Axis Aligned Bounding Box.
Definition: AABBox.java:54
final AABBox setSize(final float[] low, final float[] high)
Set size of the AABBox specifying the coordinates of the low and high.
Definition: AABBox.java:173
PMVMatrix4f implements the basic computer graphics Matrix4f pack using projection (P),...
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 boolean mapWinToObj(final float winx, final float winy, final float winz, final Recti viewport, final Vec3f objPos)
Map window coordinates to object coordinates.
static final short VK_RIGHT
Constant for the cursor- or numerical-pad right arrow key.
Definition: KeyEvent.java:817
static final short VK_W
See VK_A.
Definition: KeyEvent.java:639
static final short VK_2
See VK_0.
Definition: KeyEvent.java:557
static final short VK_UP
Constant for the cursor- or numerical-pad up arrow key.
Definition: KeyEvent.java:814
static final short VK_LEFT
Constant for the cursor- or numerical-pad left arrow key.
Definition: KeyEvent.java:811
static final short VK_DOWN
Constant for the cursor- or numerical pad down arrow key.
Definition: KeyEvent.java:820
static final short VK_9
See VK_0.
Definition: KeyEvent.java:571
static final short VK_0
VK_0 thru VK_9 are the same as UTF16/ASCII '0' thru '9' [0x30 - 0x39].
Definition: KeyEvent.java:553
static final short VK_S
See VK_A.
Definition: KeyEvent.java:631
static final short VK_Q
See VK_A.
Definition: KeyEvent.java:627
static final short VK_V
See VK_A.
Definition: KeyEvent.java:637
static final short VK_1
See VK_0.
Definition: KeyEvent.java:555
final short getKeyCode()
Returns the virtual key code using a fixed mapping to the US keyboard layout.
Definition: KeyEvent.java:195
static final short VK_7
See VK_0.
Definition: KeyEvent.java:567
static final short VK_6
See VK_0.
Definition: KeyEvent.java:565
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
abstract boolean isGLDebugMessageEnabled()
abstract GL setGL(GL gl)
Sets the GL pipeline object for this GLContext.
final String getGLVersion()
Returns a valid OpenGL version string, ie
Definition: GLContext.java:769
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Factory for pipelining GL instances.
static final GL create(final String pipelineClazzBaseName, final Class<?> reqInterface, final GL downstream, final Object[] additionalArgs)
Creates a pipelined GL instance using the given downstream downstream and optional arguments addition...
void keyPressed(final KeyEvent arg0)
A key has been pressed, excluding auto-repeat modifier keys.
void keyReleased(final KeyEvent arg0)
A key has been released, excluding auto-repeat modifier keys.
GPURendererListenerBase01(final RegionRenderer renderer, final int renderModes, final boolean debug, final boolean trace)
void printScreenOnGLThread(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha)
void setMatrix(final float xtrans, final float ytrans, final float zTran, final float angle)
void dispose(final GLAutoDrawable drawable)
Notifies the listener to perform the release of all OpenGL resources per GLContext,...
final AABBox nearPlane1Box
Describing the bounding box in model-coordinates of the near-plane parallel at distance one.
static void mapWin2ObjectCoords(final PMVMatrix4f pmv, final Recti view, final float zNear, final float zFar, final float orthoX, final float orthoY, final float orthoDist, final float[] winZ, final Vec3f objPos)
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 init(final GLAutoDrawable drawable)
Called by the drawable immediately after the OpenGL context is initialized.
void printScreen(final GLAutoDrawable drawable, final String dir, final String tech, final String objName, final boolean exportAlpha)
void attachInputListenerTo(final GLWindow window)
Attach the input listener to the window.
static void dump(final GLAutoDrawable drawable)
Definition: MSAATool.java:51
Utility to read out the current FB to TextureData, optionally writing the data back to a texture obje...
void write(final File dest)
Write the TextureData filled by readPixels(GLAutoDrawable, boolean) to file.
boolean readPixels(final GL gl, final boolean mustFlipVertically)
Read the drawable's pixels to TextureData and Texture, if requested at construction.
float[] getCurrentSurfaceScale(final float[] result)
Returns the current pixel scale of the associated NativeSurface.
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...
Listener for KeyEvents.
FPSCounter feature.
Definition: FPSCounter.java:37
void resetFPSCounter()
Reset all performance counter (startTime, currentTime, frame number)
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) ...
boolean invoke(boolean wait, GLRunnable glRunnable)
Enqueues a one-shot GLRunnable, which will be executed within the next display() call after all regis...
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.
void setSwapInterval(int interval)
Set the swap interval of the current context and attached onscreen GLDrawable.
GLContext getContext()
Returns the GLContext associated which this GL object.
int getSwapInterval()
Return the current swap interval.
Declares events which client code can use to manage OpenGL rendering into a GLAutoDrawable.
void glClearColor(float red, float green, float blue, float alpha)
Entry point to C language function: void {@native glClearColor}(GLfloat red, GLfloat green,...