1 /*
2  * Copyright (c) 2003 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  * You acknowledge that this software is not designed or intended for use
33  * in the design, construction, operation or maintenance of any nuclear
34  * facility.
35  *
36  * Sun gratefully acknowledges that this software was originally authored
37  * and developed by Kenneth Bradley Russell and Christopher John Kline.
38  */
39 
40 package javax.media.opengl;
41 
42 import java.security.*;
43 import com.sun.opengl.impl.*;
44 
45 /** <P> Provides a virtual machine- and operating system-independent
46     mechanism for creating {@link GLDrawable}s. </P>
47 
48     <P> The {@link javax.media.opengl.GLCapabilities} objects passed
49     in to the various factory methods are used as a hint for the
50     properties of the returned drawable. The default capabilities
51     selection algorithm (equivalent to passing in a null {@link
52     GLCapabilitiesChooser}) is described in {@link
53     DefaultGLCapabilitiesChooser}. Sophisticated applications needing
54     to change the selection algorithm may pass in their own {@link
55     GLCapabilitiesChooser} which can select from the available pixel
56     formats. The GLCapabilitiesChooser mechanism may not be supported
57     by all implementations or on all platforms, in which case any
58     passed GLCapabilitiesChooser will be ignored. </P>
59 
60     <P> Because of the multithreaded nature of the Java platform's
61     window system toolkit, it is typically not possible to immediately
62     reject a given {@link GLCapabilities} as being unsupportable by
63     either returning <code>null</code> from the creation routines or
64     raising a {@link GLException}. The semantics of the rejection
65     process are (unfortunately) left unspecified for now. The current
66     implementation will cause a {@link GLException} to be raised
67     during the first repaint of the {@link GLCanvas} or {@link
68     GLJPanel} if the capabilities can not be met. Pbuffers are always
69     created immediately and their creation will fail with a {@link
70     GLException} if errors occur. </P>
71 
72     <P> The concrete GLDrawableFactory subclass instantiated by {@link
73     #getFactory getFactory} can be changed by setting the system
74     property <code>opengl.factory.class.name</code> to the
75     fully-qualified name of the desired class. </P>
76 */
77 
78 public abstract class GLDrawableFactory {
79   private static GLDrawableFactory factory;
80 
GLDrawableFactory()81   protected GLDrawableFactory() {}
82 
83   /** Returns the sole GLDrawableFactory instance. */
getFactory()84   public static GLDrawableFactory getFactory() {
85     if (factory == null) {
86       try {
87         String factoryClassName =
88           (String) AccessController.doPrivileged(new PrivilegedAction() {
89               public Object run() {
90                 return System.getProperty("opengl.factory.class.name");
91               }
92             });
93         String osName = System.getProperty("os.name");
94         String osNameLowerCase = osName.toLowerCase();
95         Class factoryClass = null;
96 
97         // Because there are some complications with generating all
98         // platforms' Java glue code on all platforms (among them that we
99         // would have to include jawt.h and jawt_md.h in the jogl
100         // sources, which we currently don't have to do) we break the only
101         // static dependencies with platform-specific code here using reflection.
102 
103         if (factoryClassName != null) {
104           factoryClass = Class.forName(factoryClassName);
105         } else if (osNameLowerCase.startsWith("wind")) {
106           factoryClass = Class.forName("com.sun.opengl.impl.windows.WindowsGLDrawableFactory");
107         } else if (osNameLowerCase.startsWith("mac os x")) {
108           factoryClass = Class.forName("com.sun.opengl.impl.macosx.MacOSXGLDrawableFactory");
109         } else {
110           // Assume Linux, Solaris, etc. Should probably test for these explicitly.
111           factoryClass = Class.forName("com.sun.opengl.impl.x11.X11GLDrawableFactory");
112         }
113 
114         if (factoryClass == null) {
115           throw new GLException("OS " + osName + " not yet supported");
116         }
117 
118         factory = (GLDrawableFactory) factoryClass.newInstance();
119       } catch (Exception e) {
120         throw new GLException(e);
121       }
122     }
123 
124     return factory;
125   }
126 
127   /**
128    * <P> Selects a graphics configuration on the specified graphics
129    * device compatible with the supplied GLCapabilities. This method
130    * is intended to be used by applications which do not use the
131    * supplied GLCanvas class but instead wrap their own Canvas or
132    * other window toolkit-specific object with a GLDrawable. Some
133    * platforms (specifically X11) require the graphics configuration
134    * to be specified when the window toolkit object is created. This
135    * method may return null on platforms on which the OpenGL pixel
136    * format selection process is performed later. </P>
137    *
138    * <P> The concrete data type of the passed graphics device and
139    * returned graphics configuration must be specified in the
140    * documentation binding this particular API to the underlying
141    * window toolkit. The Reference Implementation accepts {@link
142    * AWTGraphicsDevice AWTGraphicsDevice} objects and returns {@link
143    * AWTGraphicsConfiguration AWTGraphicsConfiguration} objects. </P>
144    *
145    * @see java.awt.Canvas#Canvas(java.awt.GraphicsConfiguration)
146    *
147    * @throws IllegalArgumentException if the data type of the passed
148    *         AbstractGraphicsDevice is not supported by this
149    *         GLDrawableFactory.
150    * @throws GLException if any window system-specific errors caused
151    *         the selection of the graphics configuration to fail.
152    */
153   public abstract AbstractGraphicsConfiguration
chooseGraphicsConfiguration(GLCapabilities capabilities, GLCapabilitiesChooser chooser, AbstractGraphicsDevice device)154     chooseGraphicsConfiguration(GLCapabilities capabilities,
155                                 GLCapabilitiesChooser chooser,
156                                 AbstractGraphicsDevice device)
157     throws IllegalArgumentException, GLException;
158 
159   /**
160    * Returns a GLDrawable that wraps a platform-specific window system
161    * object, such as an AWT or LCDUI Canvas. On platforms which
162    * support it, selects a pixel format compatible with the supplied
163    * GLCapabilities, or if the passed GLCapabilities object is null,
164    * uses a default set of capabilities. On these platforms, uses
165    * either the supplied GLCapabilitiesChooser object, or if the
166    * passed GLCapabilitiesChooser object is null, uses a
167    * DefaultGLCapabilitiesChooser instance.
168    *
169    * @throws IllegalArgumentException if the passed target is either
170    *         null or its data type is not supported by this GLDrawableFactory.
171    * @throws GLException if any window system-specific errors caused
172    *         the creation of the GLDrawable to fail.
173    */
getGLDrawable(Object target, GLCapabilities capabilities, GLCapabilitiesChooser chooser)174   public abstract GLDrawable getGLDrawable(Object target,
175                                            GLCapabilities capabilities,
176                                            GLCapabilitiesChooser chooser)
177     throws IllegalArgumentException, GLException;
178 
179   //----------------------------------------------------------------------
180   // Methods to create high-level objects
181 
182   /**
183    * Returns true if it is possible to create a GLPbuffer. Some older
184    * graphics cards do not have this capability.
185    */
canCreateGLPbuffer()186   public abstract boolean canCreateGLPbuffer();
187 
188   /**
189    * Creates a GLPbuffer with the given capabilites and dimensions. <P>
190    *
191    * See the note in the overview documentation on
192    * <a href="../../../overview-summary.html#SHARING">context sharing</a>.
193    *
194    * @throws GLException if any window system-specific errors caused
195    *         the creation of the GLPbuffer to fail.
196    */
createGLPbuffer(GLCapabilities capabilities, GLCapabilitiesChooser chooser, int initialWidth, int initialHeight, GLContext shareWith)197   public abstract GLPbuffer createGLPbuffer(GLCapabilities capabilities,
198                                             GLCapabilitiesChooser chooser,
199                                             int initialWidth,
200                                             int initialHeight,
201                                             GLContext shareWith)
202     throws GLException;
203 
204   //----------------------------------------------------------------------
205   // Methods for interacting with third-party OpenGL libraries
206 
207   /**
208    * <P> Creates a GLContext object representing an existing OpenGL
209    * context in an external (third-party) OpenGL-based library. This
210    * GLContext object may be used to draw into this preexisting
211    * context using its {@link GL} and {@link
212    * javax.media.opengl.glu.GLU} objects. New contexts created through
213    * {@link GLDrawable}s may share textures and display lists with
214    * this external context. </P>
215    *
216    * <P> The underlying OpenGL context must be current on the current
217    * thread at the time this method is called. The user is responsible
218    * for the maintenance of the underlying OpenGL context; calls to
219    * <code>makeCurrent</code> and <code>release</code> on the returned
220    * GLContext object have no effect. If the underlying OpenGL context
221    * is destroyed, the <code>destroy</code> method should be called on
222    * the <code>GLContext</code>. A new <code>GLContext</code> object
223    * should be created for each newly-created underlying OpenGL
224    * context.
225    *
226    * @throws GLException if any window system-specific errors caused
227    *         the creation of the external GLContext to fail.
228    */
createExternalGLContext()229   public abstract GLContext createExternalGLContext()
230     throws GLException;
231 
232   /**
233    * Returns true if it is possible to create an external GLDrawable
234    * object via {@link #createExternalGLDrawable}.
235    */
canCreateExternalGLDrawable()236   public abstract boolean canCreateExternalGLDrawable();
237 
238   /**
239    * <P> Creates a {@link GLDrawable} object representing an existing
240    * OpenGL drawable in an external (third-party) OpenGL-based
241    * library. This GLDrawable object may be used to create new,
242    * fully-functional {@link GLContext}s on the OpenGL drawable. This
243    * is useful when interoperating with a third-party OpenGL-based
244    * library and it is essential to not perturb the state of the
245    * library's existing context, even to the point of not sharing
246    * textures or display lists with that context. </P>
247    *
248    * <P> An underlying OpenGL context must be current on the desired
249    * drawable and the current thread at the time this method is
250    * called. The user is responsible for the maintenance of the
251    * underlying drawable. If one or more contexts are created on the
252    * drawable using {@link GLDrawable#createContext}, and the drawable
253    * is deleted by the third-party library, the user is responsible
254    * for calling {@link GLContext#destroy} on these contexts. </P>
255    *
256    * <P> Calls to <code>setSize</code>, <code>getWidth</code> and
257    * <code>getHeight</code> are illegal on the returned GLDrawable. If
258    * these operations are required by the user, they must be performed
259    * by the third-party library. </P>
260    *
261    * <P> It is legal to create both an external GLContext and
262    * GLDrawable representing the same third-party OpenGL entities.
263    * This can be used, for example, to query current state information
264    * using the external GLContext and then create and set up new
265    * GLContexts using the external GLDrawable. </P>
266    *
267    * <P> This functionality may not be available on all platforms and
268    * {@link #canCreateExternalGLDrawable} should be called first to
269    * see if it is present. For example, on X11 platforms, this API
270    * requires the presence of GLX 1.3 or later.
271    *
272    * @throws GLException if any window system-specific errors caused
273    *         the creation of the external GLDrawable to fail.
274    */
createExternalGLDrawable()275   public abstract GLDrawable createExternalGLDrawable()
276     throws GLException;
277 }
278