javax.media.nativewindow.Capabilities Maven / Gradle / Ivy
/*
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistribution of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistribution in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Neither the name of Sun Microsystems, Inc. or the names of
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
* ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
* DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed or intended for use
* in the design, construction, operation or maintenance of any nuclear
* facility.
*
* Sun gratefully acknowledges that this software was originally authored
* and developed by Kenneth Bradley Russell and Christopher John Kline.
*/
package javax.media.nativewindow;
/** Specifies a set of capabilities that a window's rendering context
must support, such as color depth per channel. It currently
contains the minimal number of routines which allow configuration
on all supported window systems. */
public class Capabilities implements CapabilitiesImmutable, Cloneable {
protected final static String na_str = "----" ;
private int redBits = 8;
private int greenBits = 8;
private int blueBits = 8;
private int alphaBits = 0;
// Support for transparent windows containing OpenGL content
private boolean backgroundOpaque = true;
private int transparentValueRed = 0;
private int transparentValueGreen = 0;
private int transparentValueBlue = 0;
private int transparentValueAlpha = 0;
// Switch for on- or offscreen
private boolean onscreen = true;
// offscreen bitmap mode
private boolean isBitmap = false;
/** Creates a Capabilities object. All attributes are in a default
state.
*/
public Capabilities() {}
@Override
public Object cloneMutable() {
return clone();
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new NativeWindowException(e);
}
}
/**
* Copies all {@link Capabilities} values
* from source
into this instance.
* @return this instance
*/
public Capabilities copyFrom(CapabilitiesImmutable other) {
redBits = other.getRedBits();
greenBits = other.getGreenBits();
blueBits = other.getBlueBits();
alphaBits = other.getAlphaBits();
backgroundOpaque = other.isBackgroundOpaque();
onscreen = other.isOnscreen();
isBitmap = other.isBitmap();
transparentValueRed = other.getTransparentRedValue();
transparentValueGreen = other.getTransparentGreenValue();
transparentValueBlue = other.getTransparentBlueValue();
transparentValueAlpha = other.getTransparentAlphaValue();
return this;
}
@Override
public int hashCode() {
// 31 * x == (x << 5) - x
int hash = 31 + this.redBits;
hash = ((hash << 5) - hash) + ( this.onscreen ? 1 : 0 );
hash = ((hash << 5) - hash) + ( this.isBitmap ? 1 : 0 );
hash = ((hash << 5) - hash) + this.greenBits;
hash = ((hash << 5) - hash) + this.blueBits;
hash = ((hash << 5) - hash) + this.alphaBits;
hash = ((hash << 5) - hash) + ( this.backgroundOpaque ? 1 : 0 );
hash = ((hash << 5) - hash) + this.transparentValueRed;
hash = ((hash << 5) - hash) + this.transparentValueGreen;
hash = ((hash << 5) - hash) + this.transparentValueBlue;
hash = ((hash << 5) - hash) + this.transparentValueAlpha;
return hash;
}
@Override
public boolean equals(Object obj) {
if(this == obj) { return true; }
if(!(obj instanceof CapabilitiesImmutable)) {
return false;
}
CapabilitiesImmutable other = (CapabilitiesImmutable)obj;
boolean res = other.getRedBits()==redBits &&
other.getGreenBits()==greenBits &&
other.getBlueBits()==blueBits &&
other.getAlphaBits()==alphaBits &&
other.isBackgroundOpaque()==backgroundOpaque &&
other.isOnscreen()==onscreen &&
other.isBitmap()==isBitmap;
if(res && !backgroundOpaque) {
res = other.getTransparentRedValue()==transparentValueRed &&
other.getTransparentGreenValue()==transparentValueGreen &&
other.getTransparentBlueValue()==transparentValueBlue &&
other.getTransparentAlphaValue()==transparentValueAlpha;
}
return res;
}
/**
* Comparing RGBA values only
**/
@Override
public int compareTo(final CapabilitiesImmutable caps) {
/**
if ( ! ( o instanceof CapabilitiesImmutable ) ) {
Class> c = (null != o) ? o.getClass() : null ;
throw new ClassCastException("Not a CapabilitiesImmutable object, but " + c);
}
final CapabilitiesImmutable caps = (CapabilitiesImmutable) o; */
final int rgba = redBits * greenBits * blueBits * ( alphaBits + 1 );
final int xrgba = caps.getRedBits() * caps.getGreenBits() * caps.getBlueBits() * ( caps.getAlphaBits() + 1 );
if(rgba > xrgba) {
return 1;
} else if(rgba < xrgba) {
return -1;
}
return 0; // they are equal: RGBA
}
@Override
public int getVisualID(VIDType type) throws NativeWindowException {
switch(type) {
case INTRINSIC:
case NATIVE:
return VisualIDHolder.VID_UNDEFINED;
default:
throw new NativeWindowException("Invalid type <"+type+">");
}
}
@Override
public final int getRedBits() {
return redBits;
}
/** Sets the number of bits requested for the color buffer's red
component. On some systems only the color depth, which is the
sum of the red, green, and blue bits, is considered. */
public void setRedBits(int redBits) {
this.redBits = redBits;
}
@Override
public final int getGreenBits() {
return greenBits;
}
/** Sets the number of bits requested for the color buffer's green
component. On some systems only the color depth, which is the
sum of the red, green, and blue bits, is considered. */
public void setGreenBits(int greenBits) {
this.greenBits = greenBits;
}
@Override
public final int getBlueBits() {
return blueBits;
}
/** Sets the number of bits requested for the color buffer's blue
component. On some systems only the color depth, which is the
sum of the red, green, and blue bits, is considered. */
public void setBlueBits(int blueBits) {
this.blueBits = blueBits;
}
@Override
public final int getAlphaBits() {
return alphaBits;
}
/**
* Sets the number of bits requested for the color buffer's alpha
* component. On some systems only the color depth, which is the
* sum of the red, green, and blue bits, is considered.
*
* Note: If alpha bits are zero
, they are set to one
* by {@link #setBackgroundOpaque(boolean)} and it's OpenGL specialization GLCapabilities::setSampleBuffers(boolean)
.
* Ensure to call this method after the above to ensure a zero
value.
* The above automated settings takes into account, that the user calls this method to request alpha bits,
* not to reflect a current state. Nevertheless if this is the case - call it at last.
*
*/
public void setAlphaBits(int alphaBits) {
this.alphaBits = alphaBits;
}
/**
* Sets whether the surface shall be opaque or translucent.
*
* Platform implementations may need an alpha component in the surface (eg. Windows),
* or expect pre-multiplied alpha values (eg. X11/XRender).
* To unify the experience, this method also invokes {@link #setAlphaBits(int) setAlphaBits(1)}
* if {@link #getAlphaBits()} == 0.
* Please note that in case alpha is required on the platform the
* clear color shall have an alpha lower than 1.0 to allow anything shining through.
*
*
* Mind that translucency may cause a performance penalty
* due to the composite work required by the window manager.
*
*/
public void setBackgroundOpaque(boolean opaque) {
backgroundOpaque = opaque;
if(!opaque && getAlphaBits()==0) {
setAlphaBits(1);
}
}
@Override
public final boolean isBackgroundOpaque() {
return backgroundOpaque;
}
/**
* Sets whether the surface shall be on- or offscreen.
*
* Defaults to true.
*
*
* If requesting an offscreen surface without further selection of it's mode,
* e.g. FBO, Pbuffer or {@link #setBitmap(boolean) bitmap},
* the implementation will choose the best available offscreen mode.
*
* @param onscreen
*/
public void setOnscreen(boolean onscreen) {
this.onscreen=onscreen;
}
@Override
public final boolean isOnscreen() {
return onscreen;
}
/**
* Requesting offscreen bitmap mode.
*
* If enabled this method also invokes {@link #setOnscreen(int) setOnscreen(false)}.
*
*
* Defaults to false.
*
*
* Requesting offscreen bitmap mode disables the offscreen auto selection.
*
*/
public void setBitmap(boolean enable) {
if(enable) {
setOnscreen(false);
}
isBitmap = enable;
}
@Override
public boolean isBitmap() {
return isBitmap;
}
@Override
public final int getTransparentRedValue() { return transparentValueRed; }
@Override
public final int getTransparentGreenValue() { return transparentValueGreen; }
@Override
public final int getTransparentBlueValue() { return transparentValueBlue; }
@Override
public final int getTransparentAlphaValue() { return transparentValueAlpha; }
/** Sets the transparent red value for the frame buffer configuration,
ranging from 0 to the maximum frame buffer value for red.
This value is ignored if {@link #isBackgroundOpaque()} equals true.
It defaults to half of the frambuffer value for red.
A value of -1 is interpreted as any value. */
public void setTransparentRedValue(int transValueRed) { transparentValueRed=transValueRed; }
/** Sets the transparent green value for the frame buffer configuration,
ranging from 0 to the maximum frame buffer value for green.
This value is ignored if {@link #isBackgroundOpaque()} equals true.
It defaults to half of the frambuffer value for green.
A value of -1 is interpreted as any value. */
public void setTransparentGreenValue(int transValueGreen) { transparentValueGreen=transValueGreen; }
/** Sets the transparent blue value for the frame buffer configuration,
ranging from 0 to the maximum frame buffer value for blue.
This value is ignored if {@link #isBackgroundOpaque()} equals true.
It defaults to half of the frambuffer value for blue.
A value of -1 is interpreted as any value. */
public void setTransparentBlueValue(int transValueBlue) { transparentValueBlue=transValueBlue; }
/** Sets the transparent alpha value for the frame buffer configuration,
ranging from 0 to the maximum frame buffer value for alpha.
This value is ignored if {@link #isBackgroundOpaque()} equals true.
It defaults to half of the frambuffer value for alpha.
A value of -1 is interpreted as any value. */
public void setTransparentAlphaValue(int transValueAlpha) { transparentValueAlpha=transValueAlpha; }
@Override
public StringBuilder toString(StringBuilder sink) {
return toString(sink, true);
}
/** Returns a textual representation of this Capabilities
object. */
@Override
public String toString() {
StringBuilder msg = new StringBuilder();
msg.append("Caps[");
toString(msg);
msg.append("]");
return msg.toString();
}
/** Return a textual representation of this object's on/off screen state. Use the given StringBuilder [optional]. */
protected StringBuilder onoffScreenToString(StringBuilder sink) {
if(null == sink) {
sink = new StringBuilder();
}
if(onscreen) {
sink.append("on-scr");
} else {
sink.append("offscr[");
}
if(isBitmap) {
sink.append("bitmap");
} else if(onscreen) {
sink.append("."); // no additional off-screen modes besides on-screen
} else {
sink.append("auto-cfg"); // auto-config off-screen mode
}
sink.append("]");
return sink;
}
/** Element separator */
protected static final String ESEP = "/";
/** Component separator */
protected static final String CSEP = ", ";
protected StringBuilder toString(StringBuilder sink, boolean withOnOffScreen) {
if(null == sink) {
sink = new StringBuilder();
}
sink.append("rgba ").append(redBits).append(ESEP).append(greenBits).append(ESEP).append(blueBits).append(ESEP).append(alphaBits);
if(backgroundOpaque) {
sink.append(", opaque");
} else {
sink.append(", trans-rgba 0x").append(toHexString(transparentValueRed)).append(ESEP).append(toHexString(transparentValueGreen)).append(ESEP).append(toHexString(transparentValueBlue)).append(ESEP).append(toHexString(transparentValueAlpha));
}
if(withOnOffScreen) {
sink.append(CSEP);
onoffScreenToString(sink);
}
return sink;
}
protected final String toHexString(int val) { return Integer.toHexString(val); }
}