GraphicsConfiguration getBestConfiguration(GraphicsConfigTemplate3D gct,
GraphicsConfiguration[] gc) {
if (VERBOSE) System.err.println("JoglPipeline.getBestConfiguration()");
// Create a GLCapabilities based on the GraphicsConfigTemplate3D
final GLCapabilities caps = new GLCapabilities(profile);
caps.setDoubleBuffered(gct.getDoubleBuffer() != GraphicsConfigTemplate.UNNECESSARY);
caps.setStereo(gct.getStereo() != GraphicsConfigTemplate.UNNECESSARY);
// Scene antialiasing only if double buffering
if (gct.getSceneAntialiasing() != GraphicsConfigTemplate.UNNECESSARY &&
gct.getDoubleBuffer() != GraphicsConfigTemplate.UNNECESSARY) {
caps.setSampleBuffers(true);
caps.setNumSamples(2);
} else {
caps.setSampleBuffers(false);
caps.setNumSamples(0);
}
caps.setDepthBits(gct.getDepthSize());
caps.setStencilBits(gct.getStencilSize());
caps.setRedBits(Math.max(5, gct.getRedSize()));
caps.setGreenBits(Math.max(5, gct.getGreenSize()));
caps.setBlueBits(Math.max(5, gct.getBlueSize()));
// Issue 399: Request alpha buffer if transparentOffScreen is set
if (VirtualUniverse.mc.transparentOffScreen) {
caps.setAlphaBits(1);
}
// Add PREFERRED capabilities in order of least to highest priority and we will try disabling them
ArrayList<DisabledCaps> capsToDisable = new ArrayList<DisabledCaps>();
if (gct.getStereo() == GraphicsConfigTemplate.PREFERRED) {
capsToDisable.add(DisabledCaps.STEREO);
}
if (gct.getSceneAntialiasing() == GraphicsConfigTemplate.PREFERRED) {
capsToDisable.add(DisabledCaps.AA);
}
// if AA is required, so is double buffering.
if (gct.getSceneAntialiasing() != GraphicsConfigTemplate.REQUIRED &&
gct.getDoubleBuffer() == GraphicsConfigTemplate.PREFERRED) {
capsToDisable.add(DisabledCaps.DOUBLE_BUFFER);
}
// Pick an arbitrary graphics device.
GraphicsDevice device = gc[0].getDevice();
AbstractGraphicsScreen screen = (device != null) ? AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT) :
AWTGraphicsScreen.createDefault();
// Create a Frame and dummy GLCanvas to perform eager pixel format selection
// Note that we loop in similar fashion to the NativePipeline's
// native code in the situation where we need to disable certain
// capabilities which aren't required
boolean tryAgain = true;
CapabilitiesCapturer capturer = null;
AWTGraphicsConfiguration awtConfig = null;
while (tryAgain) {
Frame f = new Frame(device.getDefaultConfiguration());
f.setUndecorated(true);
f.setLayout(new BorderLayout());
capturer = new CapabilitiesCapturer();
try {
awtConfig = createAwtGraphicsConfiguration(caps, capturer, screen);
QueryCanvas canvas = new QueryCanvas(awtConfig, capturer);
f.add(canvas, BorderLayout.CENTER);
f.setSize(MIN_FRAME_SIZE, MIN_FRAME_SIZE);
f.setVisible(true);
canvas.doQuery();
if (DEBUG_CONFIG) {
System.err.println("Waiting for CapabilitiesCapturer");
}
// Try to wait for result without blocking EDT
if (!EventQueue.isDispatchThread()) {
synchronized(capturer) {
if (!capturer.done()) {
try {
capturer.wait(WAIT_TIME);
} catch (InterruptedException e) {
}
}
}
}
disposeOnEDT(f);
tryAgain = false;
} catch (GLException e) {
// Failure to select a pixel format; try switching off one
// of the only-preferred capabilities
if (capsToDisable.size() == 0) {
tryAgain = false;
} else {
switch (capsToDisable.remove(0)) {
case STEREO:
caps.setStereo(false);
break;
case AA:
caps.setSampleBuffers(false);
break;
case DOUBLE_BUFFER:
caps.setDoubleBuffered(false);
break;
}
awtConfig = null;
}
}
}
int chosenIndex = capturer.getChosenIndex();
GLCapabilities chosenCaps = null;
if (chosenIndex < 0) {
if (DEBUG_CONFIG) {
System.err.println("CapabilitiesCapturer returned invalid index");
}
// It's possible some platforms or implementations might not