/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package xenon3d;
import java.awt.BufferCapabilities;
import java.awt.GraphicsConfigTemplate;
import java.awt.GraphicsConfiguration;
import java.awt.ImageCapabilities;
import java.awt.color.ColorSpace;
import java.awt.image.ColorModel;
import javax.media.opengl.GLCapabilities;
/**
* This class is used to obtain a valid GraphicsConfiguration that can be used
* by Xenon3D. A user should instantiate this template and and then set all
* non-default attributes as desired. The getBestConfiguration() method in the
* GraphicsDevice class is then called with this GraphicsConfigTemplate and the
* "best" GraphicsConfiguration is returned. The "best" GraphicsConfiguration
* means that this GraphicsConfiguration is supported and it meets or exceeds
* what was requested in the GraphicsConfigTemplate. Null is returned if no such
* "best" GraphicsConfiguration is found.
* @author Volker Everts
* @version 0.1 - 13.08.2011: Created
*/
public class GraphicsConfigTemplate3D extends GraphicsConfigTemplate {
// <editor-fold defaultstate="collapsed" desc=" Static Attributes ">
/** The latest "best" graphics configuration. */
static GraphicsConfiguration bestGC;
/** The latest "best" GLCapabilities. */
static GLCapabilities bestCaps;
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" Private Fields ">
/** The serial version UID. */
private static final long serialVersionUID = 20113107L;
/** The internal GLCapabilities object. */
private GLCapabilities caps;
/** The fullscreen flag. */
private boolean fullscreen;
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" Initialization ">
/**
* Creates a new GraphicsConfigTemplate3D with default parameters.
*/
public GraphicsConfigTemplate3D() {
caps = new GLCapabilities(Xenon3D.getProfile());
caps.setAccumAlphaBits(0);
caps.setAccumRedBits(0);
caps.setAccumGreenBits(0);
caps.setAccumBlueBits(0);
caps.setAlphaBits(0);
caps.setRedBits(8);
caps.setGreenBits(8);
caps.setBlueBits(8);
caps.setDepthBits(24);
caps.setDoubleBuffered(true);
caps.setHardwareAccelerated(true);
caps.setStencilBits(0);
caps.setStereo(false);
caps.setSampleBuffers(false);
caps.setNumSamples(2);
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" Public Properties ">
/**
* Sets the color buffer size requirement. The default is 32.
* @param size the required color buffer size, must be one of 16 or 32
*/
public void setColorSize(int size) {
if (size == 16) {
caps.setRedBits(5);
caps.setGreenBits(6);
caps.setBlueBits(5);
}
else if (size == 32) {
caps.setRedBits(8);
caps.setGreenBits(8);
caps.setBlueBits(8);
}
else throw new IllegalArgumentException();
}
/**
* Gets the color buffer size requirement.
* @return the required color buffer size, one of 16 or 32
*/
public int getColorSize() {
return caps.getRedBits() == 8 ? 32 : 16;
}
/**
* Sets the depth buffer size requirement. The default is 16.
* @param size the required depth buffer size, one of 16 or 24
*/
public void setDepthSize(int size) {
if (size == 16 || size == 24) caps.setDepthBits(size);
else throw new IllegalArgumentException();
}
/**
* Gets the depth buffer size requirement.
* @return the required depth buffer size
*/
public int getDepthBufferSize() {
return caps.getDepthBits();
}
/**
* Sets the double buffering requirement. The default is true.
* @param enable if true, double buffering is required
*/
public void setDoubleBuffer(boolean enable) {
caps.setDoubleBuffered(enable);
}
/**
* Gets the double buffering requirement.
* @return true, if double buffering is required
*/
public boolean isDoubleBuffer() {
return caps.getDoubleBuffered();
}
/**
* Sets the hardware acceleration requirement. The default is true.
* @param enable if true, hardware acceleation is required
*/
public void setHardwareAcceleration(boolean enable) {
caps.setHardwareAccelerated(enable);
}
/**
* Gets the hardware acceleration requirement.
* @return true, if hardware acceleration is required
*/
public boolean isHardwareAcceleration() {
return caps.getHardwareAccelerated();
}
/**
* Sets the stencil buffer requirement. The default is false.
* @param enable if true, a stencil buffer is required
*/
public void setStencilBuffer(boolean enable) {
caps.setStencilBits(enable ? 8 : 0);
}
/**
* Gets the stencil buffer requirement.
* @return true, if a stencil buffer is required
*/
public boolean isStencilBuffer() {
return caps.getStencilBits() != 0;
}
/**
* Sets the stereo requirement. The default is false.
* <p>
* NOTE: setting stereo to true is not yet supported
* @param enable if true, stereo rendering is required
*/
public void setStereo(boolean enable) {
// TODO: Stereo rendering
if (enable) throw new UnsupportedOperationException();
caps.setStereo(enable);
}
/**
* Gets the stereo requirement.
* @return true, if stereo rendering is required
*/
public boolean isStereo() {
return caps.getStereo();
}
/**
* Sets the scene antialiasing requirement. The default is false.
* @param enable if true, full scene antialiasing is required
*/
public void setSceneAntialiasing(boolean enable) {
caps.setSampleBuffers(enable);
}
/**
* Gets the scene antialiasing requirement.
* @return true, if full scene antialiasing is required
*/
public boolean isSceneAntialiasing() {
return caps.getSampleBuffers();
}
/**
* Sets the number of sample buffers allocated when full scene antialiasing
* is required. Default is 2. Allowed values are in the range 1 to 4.
* @param n the number of sample buffers
*/
public void setNumSamples(int n) {
if (n < 0 || n > 4) throw new IllegalArgumentException();
caps.setNumSamples(n);
}
/**
* Gets the number of sample buffers allocated when full scene antialiasing
* is required.
* @return the number of sample buffers
*/
public int getNumSamples() {
return caps.getNumSamples();
}
/**
* Gets the fullscreen requirement.
* @return true, if fullscreen exclusive mode is requested
*/
public boolean isFullScreen() {
return fullscreen;
}
/**
* Sets the fullscreen requirement. The default is false.
* @param enable if true, fullscreen will be enabled
*/
public void setFullScreen(boolean enable) {
fullscreen = enable;
}
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc=" Public Methods ">
/**
* Returns a boolean indicating whether or not the given GraphicsConfiguration
* can be used to create a drawing surface that can be rendered to.
* @param gc the graphics configuration under test
* @return true, if the specified graphics configuration is supported
*/
@Override
public boolean isGraphicsConfigSupported(GraphicsConfiguration gc) {
// Check for valid gc
if (gc == null) return false;
// Check color size
ColorModel cm = gc.getColorModel();
ColorSpace cs = cm.getColorSpace();
if (!cs.isCS_sRGB()) return false;
int[] rgb = cm.getComponentSize();
int red = rgb[0];
int green = rgb[1];
int blue = rgb[2];
int alpha = 0;
if (rgb.length > 3) alpha = rgb[3];
int colorSize = getColorSize();
if (colorSize == 16) {
if (red != 5) return false;
if (green != 6) return false;
if (blue != 5) return false;
}
else {
if (red != 8) return false;
if (green != 8) return false;
if (blue != 8) return false;
}
// Check double buffer
BufferCapabilities bc = gc.getBufferCapabilities();
if (caps.getDoubleBuffered() && !bc.isPageFlipping()) return false;
if (caps.getStereo() && !bc.isMultiBufferAvailable()) return false;
if (!fullscreen && bc.isFullScreenRequired()) return false;
// Check hardware acceleration
ImageCapabilities ic = bc.getBackBufferCapabilities();
if (caps.getHardwareAccelerated() && !ic.isAccelerated()) return false;
if (fullscreen && !gc.getDevice().isFullScreenSupported()) return false;
// Default: OK
return true;
}
/**
* Implement the abstract function of getBestConfiguration() of class
* GraphicsConfigTemplate. Usually this function is not directly called by
* the user. It is implicitly called by getBestConfiguration() in class
* GraphicsDevice. The method getBestConfiguration() in GraphicsDevice will
* return whatever this function returns. This function will return the
* "best" GraphicsConfiguration. The "best" GraphicsConfiguration means that
* this GraphicsConfiguration is supported and it meets or exceeds what was
* requested in the GraphicsConfigTemplate. If no such "best" configuration
* is found, null is returned.
* @param gc the array of GraphicsConfigurations to choose from
* @return the best GraphicsConfiguration
*/
@Override
public GraphicsConfiguration getBestConfiguration(GraphicsConfiguration[] gc) {
bestGC = null;
bestCaps = null;
if (gc == null || gc.length == 0) return null;
for (GraphicsConfiguration c : gc) {
if (isGraphicsConfigSupported(c)) {
bestGC = c;
bestCaps = caps;
break;
}
}
return bestGC;
}
// </editor-fold>
} // end class GraphicsConfigTemplate3D