Jogamp
Work on test webstart deploy scripts ..
[jogl.git] / src / newt / classes / com / sun / javafx / newt / opengl / GLWindow.java
CommitLineData
a959c53b
KR
1/*
2 * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * - Redistribution of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * - Redistribution in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * Neither the name of Sun Microsystems, Inc. or the names of
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * This software is provided "AS IS," without a warranty of any kind. ALL
20 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
23 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
24 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
25 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
26 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
27 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
28 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
29 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
30 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31 *
32 */
33
34package com.sun.javafx.newt.opengl;
35
36import com.sun.javafx.newt.*;
37import javax.media.nativewindow.*;
38import javax.media.opengl.*;
39import com.sun.opengl.impl.GLDrawableHelper;
a92906bc 40import java.util.*;
a959c53b
KR
41
42/**
43 * An implementation of {@link Window} which is customized for OpenGL
44 * use, and which implements the {@link
45 * javax.media.opengl.GLAutoDrawable} interface. For convenience, this
46 * window class guarantees that its OpenGL context is current inside
47 * the various EventListeners' callbacks (MouseListener, KeyListener,
a92906bc
SG
48 * etc.).<P>
49 *
50 * Best performance is currently achieved with default settings,
51 * {@link #setEventHandlerMode} to {@link #EVENT_HANDLER_GL_NONE}
52 * and one thread per GLWindow. To ensure compatibility with the
53 * underlying platform, window shall also be created within your
54 * working thread. See comment at {@link #setRunPumpMessages}.
a959c53b
KR
55 */
56public class GLWindow extends Window implements GLAutoDrawable {
57 /**
58 * Event handling mode: EVENT_HANDLER_GL_NONE.
59 * No GL context is current, while calling the EventListener.
60 * This might be inconvenient, but don't impact the performance.
a92906bc 61 * Also
a959c53b
KR
62 *
63 * @see com.sun.javafx.newt.GLWindow#setEventHandlerMode(int)
64 */
65 public static final int EVENT_HANDLER_GL_NONE = 0;
66
67 /**
68 * Event handling mode: EVENT_HANDLER_GL_CURRENT.
69 * The GL context is made current, while calling the EventListener.
70 * This might be convenient, but impacts the performance
71 * due to context switches.
72 *
73 * This is the default setting!
74 *
75 * @see com.sun.javafx.newt.GLWindow#setEventHandlerMode(int)
76 */
77 public static final int EVENT_HANDLER_GL_CURRENT = (1 << 0);
78
a92906bc
SG
79 private static List/*GLWindow*/ glwindows = new ArrayList();
80
a959c53b 81 private Window window;
a92906bc 82 private boolean runPumpMessages = true;
a959c53b
KR
83
84 /** Constructor. Do not call this directly -- use {@link
85 create()} instead. */
86 protected GLWindow(Window window, boolean ownerOfDisplayAndScreen) {
87 this.ownerOfDisplayAndScreen = ownerOfDisplayAndScreen;
88 this.window = window;
89 this.window.setAutoDrawableClient(true);
90 window.addWindowListener(new WindowListener() {
91 public void windowResized(WindowEvent e) {
92 sendReshape = true;
93 }
94
95 public void windowMoved(WindowEvent e) {
96 }
97
98 public void windowGainedFocus(WindowEvent e) {
99 }
100
101 public void windowLostFocus(WindowEvent e) {
102 }
103
104 public void windowDestroyNotify(WindowEvent e) {
105 sendDestroy = true;
106 }
107 });
a92906bc
SG
108
109 List newglw = (List) ((ArrayList) glwindows).clone();
110 newglw.add(this);
111 glwindows=newglw;
a959c53b
KR
112 }
113
114 /** Creates a new GLWindow on the local display, screen 0, with a
115 dummy visual ID, and with the default GLCapabilities. */
116 public static GLWindow create() {
117 return create(null, null, false);
118 }
119
120 public static GLWindow create(boolean undecorated) {
121 return create(null, null, undecorated);
122 }
123
124 /** Creates a new GLWindow referring to the given window. */
125 public static GLWindow create(Window window) {
126 return create(window, null, false);
127 }
128 public static GLWindow create(GLCapabilities caps) {
129 return create(null, caps, false);
130 }
131
132 /** Creates a new GLWindow on the local display, screen 0, with a
133 dummy visual ID, and with the given GLCapabilities. */
134 public static GLWindow create(GLCapabilities caps, boolean undecorated) {
135 return create(null, caps, undecorated);
136 }
137
3cc7335e
SG
138 /** Either or: window (prio), or caps and undecorated (2nd choice) */
139 private static GLWindow create(Window window,
140 GLCapabilities caps,
141 boolean undecorated) {
a92906bc 142 Display display;
a959c53b
KR
143 boolean ownerOfDisplayAndScreen=false;
144 if (window == null) {
3cc7335e
SG
145 if (caps == null) {
146 caps = new GLCapabilities(null); // default ..
147 }
a959c53b 148 ownerOfDisplayAndScreen = true;
a92906bc 149 display = NewtFactory.createDisplay(null); // local display
a959c53b
KR
150 Screen screen = NewtFactory.createScreen(display, 0); // screen 0
151 window = NewtFactory.createWindow(screen, caps, undecorated);
152 }
153
154 return new GLWindow(window, ownerOfDisplayAndScreen);
155 }
156
a92906bc
SG
157 /**
158 * EXPERIMENTAL<br>
159 * Enable or disables running the {@link Display#pumpMessages} in the {@link #display()} call.<br>
160 * The default behavior is to run {@link Display#pumpMessages}.<P>
161 *
162 * The idea was that in a single threaded environment with one {@link Display} and many {@link Window}'s,
163 * a performance benefit was expected while disabling the implicit {@link Display#pumpMessages} and
164 * do it once via {@link GLWindow#runCurrentThreadPumpMessage()} <br>
165 * This could not have been verified. No measurable difference could have been recognized.<P>
166 *
167 * Best performance has been achieved with one GLWindow per thread.<br>
168 *
169 * @deprecated EXPERIMENTAL, semantic is about to be removed after further verification.
170 */
171 public void setRunPumpMessages(boolean onoff) {
172 runPumpMessages = onoff;
173 }
174
3cc7335e 175 protected void createNative(long parentWindowHandle, Capabilities caps) {
a959c53b
KR
176 shouldNotCallThis();
177 }
178
179 protected void closeNative() {
180 shouldNotCallThis();
181 }
182
183 protected void dispose(boolean regenerate) {
184 if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) {
185 Exception e1 = new Exception("GLWindow.dispose("+regenerate+") "+Thread.currentThread().getName()+", 1: "+this);
186 e1.printStackTrace();
187 }
188
189 sendDisposeEvent();
190
191 if (context != null) {
192 context.destroy();
193 }
194 if (drawable != null) {
195 drawable.setRealized(false);
196 }
197
198 if(null!=window) {
199 window.disposeSurfaceHandle();
200 }
201
202 if(regenerate) {
203 if(null==window) {
204 throw new GLException("GLWindow.dispose(true): null window");
205 }
206
207 // recreate GLDrawable, to reflect the new graphics configurations
208 NativeWindow nw;
209 if (window.getWrappedWindow() != null) {
210 nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration());
211 } else {
212 nw = window;
213 }
214 drawable = factory.createGLDrawable(nw);
215 drawable.setRealized(true);
216 if(getSurfaceHandle()==0) {
217 throw new GLException("SurfaceHandle==NULL after setRealize(true) "+this);
218 }
219 context = drawable.createContext(null);
220 sendReshape = true; // ensure a reshape event is send ..
221 }
222
223 if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) {
224 System.out.println("GLWindow.dispose("+regenerate+") "+Thread.currentThread().getName()+", fin: "+this);
225 }
226 }
227
228 public synchronized void destroy() {
229 if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) {
230 Exception e1 = new Exception("GLWindow.destroy "+Thread.currentThread().getName()+", 1: "+this);
231 e1.printStackTrace();
232 }
233
a92906bc
SG
234 List newglw = (List) ((ArrayList) glwindows).clone();
235 newglw.remove(this);
236 glwindows=newglw;
237
a959c53b
KR
238 dispose(false);
239
240 Screen _screen = null;
241 Display _device = null;
242 if(null!=window) {
243 if(ownerOfDisplayAndScreen) {
244 _screen = getScreen();
245 if(null != _screen) {
246 _device = _screen.getDisplay();
247 }
248 }
249 window.destroy();
250 }
251
252 if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) {
253 System.out.println("GLWindow.destroy "+Thread.currentThread().getName()+", fin: "+this);
254 }
255
256 drawable = null;
257 context = null;
258
259 if(null != _screen) {
260 _screen.destroy();
261 }
262 if(null != _device) {
263 _device.destroy();
264 }
265 window = null;
266 }
267
268 public boolean getPerfLogEnabled() { return perfLog; }
269
270 public void enablePerfLog(boolean v) {
271 perfLog = v;
272 }
273
274 /**
275 * Sets the event handling mode.
276 *
277 * @see com.sun.javafx.newt.GLWindow#EVENT_HANDLER_GL_NONE
278 * @see com.sun.javafx.newt.GLWindow#EVENT_HANDLER_GL_CURRENT
279 */
280 public void setEventHandlerMode(int mode) {
281 eventHandlerMode = mode;
282 }
283
284 public int getEventHandlerMode() {
285 return eventHandlerMode;
286 }
a92906bc 287
a959c53b
KR
288 public void setVisible(boolean visible) {
289 window.setVisible(visible);
290 if (visible && context == null) {
291 NativeWindow nw;
292 if (window.getWrappedWindow() != null) {
293 nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration());
294 } else {
295 nw = window;
296 }
297 GLCapabilities glCaps = (GLCapabilities) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
298 factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
299 drawable = factory.createGLDrawable(nw);
300 drawable.setRealized(true);
301 if(getSurfaceHandle()==0) {
302 throw new GLException("SurfaceHandle==NULL after setRealize(true) "+this);
303 }
304 context = drawable.createContext(null);
305 sendReshape = true; // ensure a reshape event is send ..
306 }
307 }
308
309 public Screen getScreen() {
310 return window.getScreen();
311 }
312
313 public void setTitle(String title) {
314 window.setTitle(title);
315 }
316
317 public String getTitle() {
318 return window.getTitle();
319 }
320
321 public void setUndecorated(boolean value) {
322 window.setUndecorated(value);
323 }
324
325 public boolean isUndecorated() {
326 return window.isUndecorated();
327 }
328
329 public void setSize(int width, int height) {
330 window.setSize(width, height);
331 }
332
333 public void setPosition(int x, int y) {
334 window.setPosition(x, y);
335 }
336
7bed517f 337 public Insets getInsets() {
338 return window.getInsets();
339 }
340
a959c53b
KR
341 public boolean setFullscreen(boolean fullscreen) {
342 return window.setFullscreen(fullscreen);
343 }
344
345 public boolean isVisible() {
346 return window.isVisible();
347 }
348
349 public int getX() {
350 return window.getX();
351 }
352
353 public int getY() {
354 return window.getY();
355 }
356
357 public int getWidth() {
358 return window.getWidth();
359 }
360
361 public int getHeight() {
362 return window.getHeight();
363 }
364
365 public boolean isFullscreen() {
366 return window.isFullscreen();
367 }
368
bf584fba
SG
369 public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
370 window.addSurfaceUpdatedListener(l);
371 }
372 public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
373 window.removeSurfaceUpdatedListener(l);
374 }
375 public SurfaceUpdatedListener[] getSurfaceUpdatedListener() {
376 return window.getSurfaceUpdatedListener();
377 }
378 public void surfaceUpdated(Object updater, NativeWindow window0, long when) {
379 window.surfaceUpdated(updater, window, when);
380 }
381
a959c53b
KR
382 public void addMouseListener(MouseListener l) {
383 window.addMouseListener(l);
384 }
385
386 public void removeMouseListener(MouseListener l) {
387 window.removeMouseListener(l);
388 }
389
390 public MouseListener[] getMouseListeners() {
391 return window.getMouseListeners();
392 }
393
394 public void addKeyListener(KeyListener l) {
395 window.addKeyListener(l);
396 }
397
398 public void removeKeyListener(KeyListener l) {
399 window.removeKeyListener(l);
400 }
401
402 public KeyListener[] getKeyListeners() {
403 return window.getKeyListeners();
404 }
405
406 public void addWindowListener(WindowListener l) {
407 window.addWindowListener(l);
408 }
409
410 public void removeWindowListener(WindowListener l) {
411 window.removeWindowListener(l);
412 }
413
414 public WindowListener[] getWindowListeners() {
415 return window.getWindowListeners();
416 }
417
418 public String toString() {
bf584fba 419 return "NEWT-GLWindow[ \n\tDrawable: "+drawable+", \n\tWindow: "+window+", \n\tHelper: "+helper+", \n\tFactory: "+factory+"]";
a959c53b
KR
420 }
421
422 //----------------------------------------------------------------------
423 // OpenGL-related methods and state
424 //
425
a92906bc
SG
426 private static int eventHandlerMode = EVENT_HANDLER_GL_CURRENT;
427 private static boolean autoSwapBufferMode = true;
a959c53b
KR
428 private GLDrawableFactory factory;
429 private GLDrawable drawable;
430 private GLContext context;
431 private GLDrawableHelper helper = new GLDrawableHelper();
432 // To make reshape events be sent immediately before a display event
433 private boolean sendReshape=false;
434 private boolean sendDestroy=false;
435 private boolean perfLog = false;
436
437 public GLDrawableFactory getFactory() {
438 return factory;
439 }
440
441 public void setContext(GLContext newCtx) {
442 context = newCtx;
443 }
444
445 public GLContext getContext() {
446 return context;
447 }
448
449 public GL getGL() {
450 if (context == null) {
451 return null;
452 }
453 return context.getGL();
454 }
455
4e0a5af0 456 public GL setGL(GL gl) {
a959c53b
KR
457 if (context != null) {
458 context.setGL(gl);
4e0a5af0 459 return gl;
a959c53b 460 }
4e0a5af0 461 return null;
a959c53b
KR
462 }
463
464 public void addGLEventListener(GLEventListener listener) {
465 helper.addGLEventListener(listener);
466 }
467
468 public void removeGLEventListener(GLEventListener listener) {
469 helper.removeGLEventListener(listener);
470 }
471
a92906bc
SG
472 class DisplayPumpMessage implements Display.Action {
473 public void run(Display display) {
474 if( 0 == (eventHandlerMode & EVENT_HANDLER_GL_CURRENT) ) {
475 display.run();
476 } else {
477 helper.setAutoSwapBufferMode(false);
478 try {
479 helper.invokeGL(drawable, context, display, initAction);
480 } finally {
481 helper.setAutoSwapBufferMode(autoSwapBufferMode);
482 }
483 }
484 }
485 }
486 private DisplayPumpMessage displayPumpMessage = new DisplayPumpMessage();
487
488 static class DisplayPumpMessageStatic implements Display.Action {
489 public void run(Display display) {
490 display.run();
491 }
492 }
493 private static DisplayPumpMessageStatic displayPumpMessageStatic = new DisplayPumpMessageStatic();
494
495 /**
496 * @see #setRunPumpMessages
497 * @deprecated EXPERIMENTAL, semantic is about to be removed after further verification.
498 */
499 public static void runCurrentThreadPumpMessage() {
500 Exception safedE = null;
501
502 if( 0 != (eventHandlerMode & EVENT_HANDLER_GL_CURRENT) ) {
503 // for all: setup / init / makeCurrent
504 for(Iterator i = glwindows.iterator(); i.hasNext(); ) {
505 GLWindow glw = (GLWindow) i.next();
506 glw.helper.setAutoSwapBufferMode(false);
507 glw.helper.invokeGL(glw.drawable, glw.context, null, glw.initAction);
508 }
509 }
510
511 try {
512 Display.runCurrentThreadDisplaysAction(displayPumpMessageStatic);
513 } catch (Exception e) {
514 safedE=e;
515 }
516
517 if( 0 != (eventHandlerMode & EVENT_HANDLER_GL_CURRENT) ) {
518 // for all: reset
519 for(Iterator i = glwindows.iterator(); i.hasNext(); ) {
520 GLWindow glw = (GLWindow) i.next();
521 glw.helper.setAutoSwapBufferMode(autoSwapBufferMode);
522 }
523 }
524
525 if(null!=safedE) {
526 throw new GLException(safedE);
527 }
528 }
529
a959c53b 530 public void display() {
cf4c4037
SG
531 display(false);
532 }
533
534 public void display(boolean forceReshape) {
a959c53b 535 if(getSurfaceHandle()!=0) {
a92906bc
SG
536 if(runPumpMessages) {
537 displayPumpMessage.run(window.getScreen().getDisplay());
538 }
a959c53b
KR
539 if(window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED) {
540 dispose(true);
541 }
542 if (sendDestroy) {
543 destroy();
544 sendDestroy=false;
545 } else {
cf4c4037
SG
546 if(forceReshape) {
547 sendReshape = true;
548 }
a959c53b
KR
549 helper.invokeGL(drawable, context, displayAction, initAction);
550 }
551 }
552 }
553
554 private void sendDisposeEvent() {
555 if(disposeAction!=null && drawable!=null && context != null && window!=null && getSurfaceHandle()!=0) {
556 helper.invokeGL(drawable, context, disposeAction, null);
557 }
558 }
559
a92906bc 560 /** This implementation uses a static value */
a959c53b 561 public void setAutoSwapBufferMode(boolean onOrOff) {
a92906bc 562 autoSwapBufferMode = onOrOff;
a959c53b
KR
563 }
564
a92906bc 565 /** This implementation uses a static value */
a959c53b 566 public boolean getAutoSwapBufferMode() {
a92906bc 567 return autoSwapBufferMode;
a959c53b
KR
568 }
569
570 public void swapBuffers() {
571 if(getSurfaceHandle()!=0) {
572 if (context != null && context != GLContext.getCurrent()) {
573 // Assume we should try to make the context current before swapping the buffers
574 helper.invokeGL(drawable, context, swapBuffersAction, initAction);
575 } else {
576 drawable.swapBuffers();
577 }
578 }
579 }
580
581 class InitAction implements Runnable {
582 public void run() {
583 helper.init(GLWindow.this);
584 startTime = System.currentTimeMillis();
585 curTime = startTime;
586 if(perfLog) {
587 lastCheck = startTime;
588 totalFrames = 0; lastFrames = 0;
589 }
590 }
591 }
592 private InitAction initAction = new InitAction();
593
594 class DisposeAction implements Runnable {
595 public void run() {
596 helper.dispose(GLWindow.this);
597 }
598 }
599 private DisposeAction disposeAction = new DisposeAction();
600
601 class DisplayAction implements Runnable {
602 public void run() {
603 if (sendReshape) {
604 int width = getWidth();
605 int height = getHeight();
606 getGL().glViewport(0, 0, width, height);
607 helper.reshape(GLWindow.this, 0, 0, width, height);
608 sendReshape = false;
609 }
610
611 helper.display(GLWindow.this);
612
613 curTime = System.currentTimeMillis();
614 totalFrames++;
615
616 if(perfLog) {
617 long dt0, dt1;
618 lastFrames++;
619 dt0 = curTime-lastCheck;
620 if ( dt0 > 5000 ) {
621 dt1 = curTime-startTime;
622 System.out.println(dt0/1000 +"s: "+ lastFrames + "f, " + (lastFrames*1000)/dt0 + " fps, "+dt0/lastFrames+" ms/f; "+
623 "total: "+ dt1/1000+"s, "+(totalFrames*1000)/dt1 + " fps, "+dt1/totalFrames+" ms/f");
624 lastCheck=curTime;
625 lastFrames=0;
626 }
627 }
628 }
629 }
a92906bc 630 private DisplayAction displayAction = new DisplayAction();
a959c53b
KR
631
632 public long getStartTime() { return startTime; }
633 public long getCurrentTime() { return curTime; }
634 public long getDuration() { return curTime-startTime; }
635 public int getTotalFrames() { return totalFrames; }
636
637 private long startTime = 0;
638 private long curTime = 0;
639 private long lastCheck = 0;
640 private int totalFrames = 0, lastFrames = 0;
641 private boolean ownerOfDisplayAndScreen;
642
a959c53b
KR
643 class SwapBuffersAction implements Runnable {
644 public void run() {
645 drawable.swapBuffers();
646 }
647 }
a959c53b
KR
648 private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
649
650 //----------------------------------------------------------------------
651 // GLDrawable methods
652 //
653
654 public NativeWindow getNativeWindow() {
655 return null!=drawable ? drawable.getNativeWindow() : null;
656 }
657
658 public synchronized int lockSurface() throws NativeWindowException {
659 if(null!=drawable) return drawable.getNativeWindow().lockSurface();
660 return NativeWindow.LOCK_SURFACE_NOT_READY;
661 }
662
663 public synchronized void unlockSurface() {
664 if(null!=drawable) drawable.getNativeWindow().unlockSurface();
665 else throw new NativeWindowException("NEWT-GLWindow not locked");
666 }
667
668 public synchronized boolean isSurfaceLocked() {
669 if(null!=drawable) return drawable.getNativeWindow().isSurfaceLocked();
670 return false;
671 }
672
673 public synchronized Exception getLockedStack() {
674 if(null!=drawable) return drawable.getNativeWindow().getLockedStack();
675 return null;
676 }
677
8883fa88 678 public boolean surfaceSwap() {
679 if(null!=drawable) return drawable.getNativeWindow().surfaceSwap();
680 return super.surfaceSwap();
681 }
682
a959c53b
KR
683 public long getWindowHandle() {
684 if(null!=drawable) return drawable.getNativeWindow().getWindowHandle();
685 return super.getWindowHandle();
686 }
687
688 public long getSurfaceHandle() {
689 if(null!=drawable) return drawable.getNativeWindow().getSurfaceHandle();
690 return super.getSurfaceHandle();
691 }
692
693 //----------------------------------------------------------------------
694 // GLDrawable methods that are not really needed
695 //
696
697 public GLContext createContext(GLContext shareWith) {
698 return drawable.createContext(shareWith);
699 }
700
701 public void setRealized(boolean realized) {
702 }
703
704 public GLCapabilities getChosenGLCapabilities() {
705 if (drawable == null) {
706 throw new GLException("No drawable yet");
707 }
708
709 return drawable.getChosenGLCapabilities();
710 }
711
712 public GLProfile getGLProfile() {
713 if (drawable == null) {
714 throw new GLException("No drawable yet");
715 }
716
717 return drawable.getGLProfile();
718 }
719
720 //----------------------------------------------------------------------
721 // Internals only below this point
722 //
723
724 private void shouldNotCallThis() {
725 throw new NativeWindowException("Should not call this");
726 }
727}
http://JogAmp.org git info: FAQ, tutorial and man pages.