下面列出了java.awt.TexturePaint#getImage ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
protected Element createTexturePaint( TexturePaint paint, String imgId,
boolean highlight )
{
Element elem = dom.createElement( "pattern" ); //$NON-NLS-1$
if ( highlight )
elem.setAttribute( "id", getTextureId( paint ) + "h" ); //$NON-NLS-1$ //$NON-NLS-2$
else
elem.setAttribute( "id", getTextureId( paint ) ); //$NON-NLS-1$
BufferedImage img = paint.getImage( );
int width = img.getWidth( );
int height = img.getHeight( );
elem.setAttribute( "patternUnits", "userSpaceOnUse" ); //$NON-NLS-1$//$NON-NLS-2$
elem.setAttribute( "width", Integer.toString( width ) ); //$NON-NLS-1$
elem.setAttribute( "height", Integer.toString( height ) ); //$NON-NLS-1$
Element elemUse = dom.createElement( "use" ); //$NON-NLS-1$
elemUse.setAttribute( "x", "0" ); //$NON-NLS-1$//$NON-NLS-2$
elemUse.setAttribute( "y", "0" ); //$NON-NLS-1$//$NON-NLS-2$
elemUse.setAttribute( "xlink:href", "#" + imgId ); //$NON-NLS-1$//$NON-NLS-2$
elem.appendChild( elemUse );
return elem;
}
public TexturePaintSerializationWrapper(TexturePaint tp) {
ImageSerializationWrapper image = new ImageSerializationWrapper(
(RenderedImage) tp.getImage());
map.put(KEY_IMAGE, image);
Rectangle2DSerializationWrapper anchor = new Rectangle2DSerializationWrapper(
tp.getAnchorRect());
map.put(KEY_ANCHOR_RECT, anchor);
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated OGLPaints.Texture implementation. A TexturePaint is
* considered valid if the following conditions are met:
* - the texture image dimensions are power-of-two (or the
* GL_ARB_texture_non_power_of_two extension is present)
* - the texture image can be (or is already) cached in an OpenGL
* texture object
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// see if texture-non-pow2 extension is available
if (!dstData.isTexNonPow2Available()) {
int imgw = bi.getWidth();
int imgh = bi.getHeight();
// verify that the texture image dimensions are pow2
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into an
// OpenGL texture...
srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
OGLSurfaceData oglData = (OGLSurfaceData)srcData;
if (oglData.getType() != OGLSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated BufferedPaints.Texture implementation.
*
* A TexturePaint is considered valid if the following conditions
* are met:
* - the texture image dimensions are power-of-two
* - the texture image can be (or is already) cached in a D3D
* texture object
*/
@Override
public boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// verify that the texture image dimensions are pow2
D3DGraphicsDevice gd =
(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();
int imgw = bi.getWidth();
int imgh = bi.getHeight();
if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
// verify that the texture image is square if it has to be
if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into a
// D3D texture...
srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
D3DSurfaceData d3dData = (D3DSurfaceData)srcData;
if (d3dData.getType() != D3DSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated BufferedPaints.Texture implementation.
*
* A TexturePaint is considered valid if the following conditions
* are met:
* - the texture image dimensions are power-of-two
* - the texture image can be (or is already) cached in a D3D
* texture object
*/
@Override
public boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// verify that the texture image dimensions are pow2
D3DGraphicsDevice gd =
(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();
int imgw = bi.getWidth();
int imgh = bi.getHeight();
if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
// verify that the texture image is square if it has to be
if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into a
// D3D texture...
srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
D3DSurfaceData d3dData = (D3DSurfaceData)srcData;
if (d3dData.getType() != D3DSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated OGLPaints.Texture implementation. A TexturePaint is
* considered valid if the following conditions are met:
* - the texture image dimensions are power-of-two (or the
* GL_ARB_texture_non_power_of_two extension is present)
* - the texture image can be (or is already) cached in an OpenGL
* texture object
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// see if texture-non-pow2 extension is available
if (!dstData.isTexNonPow2Available()) {
int imgw = bi.getWidth();
int imgh = bi.getHeight();
// verify that the texture image dimensions are pow2
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into an
// OpenGL texture...
srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
OGLSurfaceData oglData = (OGLSurfaceData)srcData;
if (oglData.getType() != OGLSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated BufferedPaints.Texture implementation.
*
* A TexturePaint is considered valid if the following conditions
* are met:
* - the texture image dimensions are power-of-two
* - the texture image can be (or is already) cached in a D3D
* texture object
*/
@Override
public boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// verify that the texture image dimensions are pow2
D3DGraphicsDevice gd =
(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();
int imgw = bi.getWidth();
int imgh = bi.getHeight();
if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
// verify that the texture image is square if it has to be
if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into a
// D3D texture...
srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
D3DSurfaceData d3dData = (D3DSurfaceData)srcData;
if (d3dData.getType() != D3DSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated BufferedPaints.Texture implementation.
*
* A TexturePaint is considered valid if the following conditions
* are met:
* - the texture image dimensions are power-of-two
* - the texture image can be (or is already) cached in a D3D
* texture object
*/
@Override
public boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// verify that the texture image dimensions are pow2
D3DGraphicsDevice gd =
(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();
int imgw = bi.getWidth();
int imgh = bi.getHeight();
if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
// verify that the texture image is square if it has to be
if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into a
// D3D texture...
srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
D3DSurfaceData d3dData = (D3DSurfaceData)srcData;
if (d3dData.getType() != D3DSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* We use OpenGL's texture coordinate generator to automatically
* map the TexturePaint image to the geometry being rendered. The
* generator uses two separate plane equations that take the (x,y)
* location (in device space) of the fragment being rendered to
* calculate (u,v) texture coordinates for that fragment:
* u = Ax + By + Cz + Dw
* v = Ex + Fy + Gz + Hw
*
* Since we use a 2D orthographic projection, we can assume that z=0
* and w=1 for any fragment. So we need to calculate appropriate
* values for the plane equation constants (A,B,D) and (E,F,H) such
* that {u,v}=0 for the top-left of the TexturePaint's anchor
* rectangle and {u,v}=1 for the bottom-right of the anchor rectangle.
* We can easily make the texture image repeat for {u,v} values
* outside the range [0,1] by specifying the GL_REPEAT texture wrap
* mode.
*
* Calculating the plane equation constants is surprisingly simple.
* We can think of it as an inverse matrix operation that takes
* device space coordinates and transforms them into user space
* coordinates that correspond to a location relative to the anchor
* rectangle. First, we translate and scale the current user space
* transform by applying the anchor rectangle bounds. We then take
* the inverse of this affine transform. The rows of the resulting
* inverse matrix correlate nicely to the plane equation constants
* we were seeking.
*/
private static void setTexturePaint(RenderQueue rq,
SunGraphics2D sg2d,
TexturePaint paint,
boolean useMask)
{
BufferedImage bi = paint.getImage();
SurfaceData dstData = sg2d.surfaceData;
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
boolean filter =
(sg2d.interpolationType !=
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
// calculate plane equation constants
AffineTransform at = (AffineTransform)sg2d.transform.clone();
Rectangle2D anchor = paint.getAnchorRect();
at.translate(anchor.getX(), anchor.getY());
at.scale(anchor.getWidth(), anchor.getHeight());
double xp0, xp1, xp3, yp0, yp1, yp3;
try {
at.invert();
xp0 = at.getScaleX();
xp1 = at.getShearX();
xp3 = at.getTranslateX();
yp0 = at.getShearY();
yp1 = at.getScaleY();
yp3 = at.getTranslateY();
} catch (java.awt.geom.NoninvertibleTransformException e) {
xp0 = xp1 = xp3 = yp0 = yp1 = yp3 = 0.0;
}
// assert rq.lock.isHeldByCurrentThread();
rq.ensureCapacityAndAlignment(68, 12);
RenderBuffer buf = rq.getBuffer();
buf.putInt(SET_TEXTURE_PAINT);
buf.putInt(useMask ? 1 : 0);
buf.putInt(filter ? 1 : 0);
buf.putLong(srcData.getNativeOps());
buf.putDouble(xp0).putDouble(xp1).putDouble(xp3);
buf.putDouble(yp0).putDouble(yp1).putDouble(yp3);
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated OGLPaints.Texture implementation. A TexturePaint is
* considered valid if the following conditions are met:
* - the texture image dimensions are power-of-two (or the
* GL_ARB_texture_non_power_of_two extension is present)
* - the texture image can be (or is already) cached in an OpenGL
* texture object
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// see if texture-non-pow2 extension is available
if (!dstData.isTexNonPow2Available()) {
int imgw = bi.getWidth();
int imgh = bi.getHeight();
// verify that the texture image dimensions are pow2
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into an
// OpenGL texture...
srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
OGLSurfaceData oglData = (OGLSurfaceData)srcData;
if (oglData.getType() != OGLSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated BufferedPaints.Texture implementation.
*
* A TexturePaint is considered valid if the following conditions
* are met:
* - the texture image dimensions are power-of-two
* - the texture image can be (or is already) cached in a D3D
* texture object
*/
@Override
public boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// verify that the texture image dimensions are pow2
D3DGraphicsDevice gd =
(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();
int imgw = bi.getWidth();
int imgh = bi.getHeight();
if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
// verify that the texture image is square if it has to be
if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into a
// D3D texture...
srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
D3DSurfaceData d3dData = (D3DSurfaceData)srcData;
if (d3dData.getType() != D3DSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated OGLPaints.Texture implementation. A TexturePaint is
* considered valid if the following conditions are met:
* - the texture image dimensions are power-of-two (or the
* GL_ARB_texture_non_power_of_two extension is present)
* - the texture image can be (or is already) cached in an OpenGL
* texture object
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// see if texture-non-pow2 extension is available
if (!dstData.isTexNonPow2Available()) {
int imgw = bi.getWidth();
int imgh = bi.getHeight();
// verify that the texture image dimensions are pow2
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into an
// OpenGL texture...
srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
OGLSurfaceData oglData = (OGLSurfaceData)srcData;
if (oglData.getType() != OGLSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* We use OpenGL's texture coordinate generator to automatically
* map the TexturePaint image to the geometry being rendered. The
* generator uses two separate plane equations that take the (x,y)
* location (in device space) of the fragment being rendered to
* calculate (u,v) texture coordinates for that fragment:
* u = Ax + By + Cz + Dw
* v = Ex + Fy + Gz + Hw
*
* Since we use a 2D orthographic projection, we can assume that z=0
* and w=1 for any fragment. So we need to calculate appropriate
* values for the plane equation constants (A,B,D) and (E,F,H) such
* that {u,v}=0 for the top-left of the TexturePaint's anchor
* rectangle and {u,v}=1 for the bottom-right of the anchor rectangle.
* We can easily make the texture image repeat for {u,v} values
* outside the range [0,1] by specifying the GL_REPEAT texture wrap
* mode.
*
* Calculating the plane equation constants is surprisingly simple.
* We can think of it as an inverse matrix operation that takes
* device space coordinates and transforms them into user space
* coordinates that correspond to a location relative to the anchor
* rectangle. First, we translate and scale the current user space
* transform by applying the anchor rectangle bounds. We then take
* the inverse of this affine transform. The rows of the resulting
* inverse matrix correlate nicely to the plane equation constants
* we were seeking.
*/
private static void setTexturePaint(RenderQueue rq,
SunGraphics2D sg2d,
TexturePaint paint,
boolean useMask)
{
BufferedImage bi = paint.getImage();
SurfaceData dstData = sg2d.surfaceData;
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
boolean filter =
(sg2d.interpolationType !=
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
// calculate plane equation constants
AffineTransform at = (AffineTransform)sg2d.transform.clone();
Rectangle2D anchor = paint.getAnchorRect();
at.translate(anchor.getX(), anchor.getY());
at.scale(anchor.getWidth(), anchor.getHeight());
double xp0, xp1, xp3, yp0, yp1, yp3;
try {
at.invert();
xp0 = at.getScaleX();
xp1 = at.getShearX();
xp3 = at.getTranslateX();
yp0 = at.getShearY();
yp1 = at.getScaleY();
yp3 = at.getTranslateY();
} catch (java.awt.geom.NoninvertibleTransformException e) {
xp0 = xp1 = xp3 = yp0 = yp1 = yp3 = 0.0;
}
// assert rq.lock.isHeldByCurrentThread();
rq.ensureCapacityAndAlignment(68, 12);
RenderBuffer buf = rq.getBuffer();
buf.putInt(SET_TEXTURE_PAINT);
buf.putInt(useMask ? 1 : 0);
buf.putInt(filter ? 1 : 0);
buf.putLong(srcData.getNativeOps());
buf.putDouble(xp0).putDouble(xp1).putDouble(xp3);
buf.putDouble(yp0).putDouble(yp1).putDouble(yp3);
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated BufferedPaints.Texture implementation.
*
* A TexturePaint is considered valid if the following conditions
* are met:
* - the texture image dimensions are power-of-two
* - the texture image can be (or is already) cached in a D3D
* texture object
*/
@Override
public boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// verify that the texture image dimensions are pow2
D3DGraphicsDevice gd =
(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();
int imgw = bi.getWidth();
int imgh = bi.getHeight();
if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
// verify that the texture image is square if it has to be
if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into a
// D3D texture...
srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
D3DSurfaceData d3dData = (D3DSurfaceData)srcData;
if (d3dData.getType() != D3DSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated OGLPaints.Texture implementation. A TexturePaint is
* considered valid if the following conditions are met:
* - the texture image dimensions are power-of-two (or the
* GL_ARB_texture_non_power_of_two extension is present)
* - the texture image can be (or is already) cached in an OpenGL
* texture object
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// see if texture-non-pow2 extension is available
if (!dstData.isTexNonPow2Available()) {
int imgw = bi.getWidth();
int imgh = bi.getHeight();
// verify that the texture image dimensions are pow2
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into an
// OpenGL texture...
srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
OGLSurfaceData oglData = (OGLSurfaceData)srcData;
if (oglData.getType() != OGLSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated BufferedPaints.Texture implementation.
*
* A TexturePaint is considered valid if the following conditions
* are met:
* - the texture image dimensions are power-of-two
* - the texture image can be (or is already) cached in a D3D
* texture object
*/
@Override
public boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// verify that the texture image dimensions are pow2
D3DGraphicsDevice gd =
(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();
int imgw = bi.getWidth();
int imgh = bi.getHeight();
if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
// verify that the texture image is square if it has to be
if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into a
// D3D texture...
srcData =
dstData.getSourceSurfaceData(bi, sg2d.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
D3DSurfaceData d3dData = (D3DSurfaceData)srcData;
if (d3dData.getType() != D3DSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* We use OpenGL's texture coordinate generator to automatically
* map the TexturePaint image to the geometry being rendered. The
* generator uses two separate plane equations that take the (x,y)
* location (in device space) of the fragment being rendered to
* calculate (u,v) texture coordinates for that fragment:
* u = Ax + By + Cz + Dw
* v = Ex + Fy + Gz + Hw
*
* Since we use a 2D orthographic projection, we can assume that z=0
* and w=1 for any fragment. So we need to calculate appropriate
* values for the plane equation constants (A,B,D) and (E,F,H) such
* that {u,v}=0 for the top-left of the TexturePaint's anchor
* rectangle and {u,v}=1 for the bottom-right of the anchor rectangle.
* We can easily make the texture image repeat for {u,v} values
* outside the range [0,1] by specifying the GL_REPEAT texture wrap
* mode.
*
* Calculating the plane equation constants is surprisingly simple.
* We can think of it as an inverse matrix operation that takes
* device space coordinates and transforms them into user space
* coordinates that correspond to a location relative to the anchor
* rectangle. First, we translate and scale the current user space
* transform by applying the anchor rectangle bounds. We then take
* the inverse of this affine transform. The rows of the resulting
* inverse matrix correlate nicely to the plane equation constants
* we were seeking.
*/
private static void setTexturePaint(RenderQueue rq,
SunGraphics2D sg2d,
TexturePaint paint,
boolean useMask)
{
BufferedImage bi = paint.getImage();
SurfaceData dstData = sg2d.surfaceData;
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
boolean filter =
(sg2d.interpolationType !=
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
// calculate plane equation constants
AffineTransform at = (AffineTransform)sg2d.transform.clone();
Rectangle2D anchor = paint.getAnchorRect();
at.translate(anchor.getX(), anchor.getY());
at.scale(anchor.getWidth(), anchor.getHeight());
double xp0, xp1, xp3, yp0, yp1, yp3;
try {
at.invert();
xp0 = at.getScaleX();
xp1 = at.getShearX();
xp3 = at.getTranslateX();
yp0 = at.getShearY();
yp1 = at.getScaleY();
yp3 = at.getTranslateY();
} catch (java.awt.geom.NoninvertibleTransformException e) {
xp0 = xp1 = xp3 = yp0 = yp1 = yp3 = 0.0;
}
// assert rq.lock.isHeldByCurrentThread();
rq.ensureCapacityAndAlignment(68, 12);
RenderBuffer buf = rq.getBuffer();
buf.putInt(SET_TEXTURE_PAINT);
buf.putInt(useMask ? 1 : 0);
buf.putInt(filter ? 1 : 0);
buf.putLong(srcData.getNativeOps());
buf.putDouble(xp0).putDouble(xp1).putDouble(xp3);
buf.putDouble(yp0).putDouble(yp1).putDouble(yp3);
}
/**
* We use OpenGL's texture coordinate generator to automatically
* map the TexturePaint image to the geometry being rendered. The
* generator uses two separate plane equations that take the (x,y)
* location (in device space) of the fragment being rendered to
* calculate (u,v) texture coordinates for that fragment:
* u = Ax + By + Cz + Dw
* v = Ex + Fy + Gz + Hw
*
* Since we use a 2D orthographic projection, we can assume that z=0
* and w=1 for any fragment. So we need to calculate appropriate
* values for the plane equation constants (A,B,D) and (E,F,H) such
* that {u,v}=0 for the top-left of the TexturePaint's anchor
* rectangle and {u,v}=1 for the bottom-right of the anchor rectangle.
* We can easily make the texture image repeat for {u,v} values
* outside the range [0,1] by specifying the GL_REPEAT texture wrap
* mode.
*
* Calculating the plane equation constants is surprisingly simple.
* We can think of it as an inverse matrix operation that takes
* device space coordinates and transforms them into user space
* coordinates that correspond to a location relative to the anchor
* rectangle. First, we translate and scale the current user space
* transform by applying the anchor rectangle bounds. We then take
* the inverse of this affine transform. The rows of the resulting
* inverse matrix correlate nicely to the plane equation constants
* we were seeking.
*/
private static void setTexturePaint(RenderQueue rq,
SunGraphics2D sg2d,
TexturePaint paint,
boolean useMask)
{
BufferedImage bi = paint.getImage();
SurfaceData dstData = sg2d.surfaceData;
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
boolean filter =
(sg2d.interpolationType !=
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
// calculate plane equation constants
AffineTransform at = (AffineTransform)sg2d.transform.clone();
Rectangle2D anchor = paint.getAnchorRect();
at.translate(anchor.getX(), anchor.getY());
at.scale(anchor.getWidth(), anchor.getHeight());
double xp0, xp1, xp3, yp0, yp1, yp3;
try {
at.invert();
xp0 = at.getScaleX();
xp1 = at.getShearX();
xp3 = at.getTranslateX();
yp0 = at.getShearY();
yp1 = at.getScaleY();
yp3 = at.getTranslateY();
} catch (java.awt.geom.NoninvertibleTransformException e) {
xp0 = xp1 = xp3 = yp0 = yp1 = yp3 = 0.0;
}
// assert rq.lock.isHeldByCurrentThread();
rq.ensureCapacityAndAlignment(68, 12);
RenderBuffer buf = rq.getBuffer();
buf.putInt(SET_TEXTURE_PAINT);
buf.putInt(useMask ? 1 : 0);
buf.putInt(filter ? 1 : 0);
buf.putLong(srcData.getNativeOps());
buf.putDouble(xp0).putDouble(xp1).putDouble(xp3);
buf.putDouble(yp0).putDouble(yp1).putDouble(yp3);
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated OGLPaints.Texture implementation. A TexturePaint is
* considered valid if the following conditions are met:
* - the texture image dimensions are power-of-two (or the
* GL_ARB_texture_non_power_of_two extension is present)
* - the texture image can be (or is already) cached in an OpenGL
* texture object
*/
@Override
boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
OGLSurfaceData dstData = (OGLSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// see if texture-non-pow2 extension is available
if (!dstData.isTexNonPow2Available()) {
int imgw = bi.getWidth();
int imgh = bi.getHeight();
// verify that the texture image dimensions are pow2
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into an
// OpenGL texture...
srcData =
dstData.getSourceSurfaceData(bi,
SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof OGLSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
OGLSurfaceData oglData = (OGLSurfaceData)srcData;
if (oglData.getType() != OGLSurfaceData.TEXTURE) {
return false;
}
return true;
}
/**
* Returns true if the given TexturePaint instance can be used by the
* accelerated BufferedPaints.Texture implementation.
*
* A TexturePaint is considered valid if the following conditions
* are met:
* - the texture image dimensions are power-of-two
* - the texture image can be (or is already) cached in a D3D
* texture object
*/
@Override
public boolean isPaintValid(SunGraphics2D sg2d) {
TexturePaint paint = (TexturePaint)sg2d.paint;
D3DSurfaceData dstData = (D3DSurfaceData)sg2d.surfaceData;
BufferedImage bi = paint.getImage();
// verify that the texture image dimensions are pow2
D3DGraphicsDevice gd =
(D3DGraphicsDevice)dstData.getDeviceConfiguration().getDevice();
int imgw = bi.getWidth();
int imgh = bi.getHeight();
if (!gd.isCapPresent(CAPS_TEXNONPOW2)) {
if ((imgw & (imgw - 1)) != 0 || (imgh & (imgh - 1)) != 0) {
return false;
}
}
// verify that the texture image is square if it has to be
if (!gd.isCapPresent(CAPS_TEXNONSQUARE) && imgw != imgh)
{
return false;
}
SurfaceData srcData =
dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
// REMIND: this is a hack that attempts to cache the system
// memory image from the TexturePaint instance into a
// D3D texture...
srcData =
dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT,
CompositeType.SrcOver, null);
if (!(srcData instanceof D3DSurfaceData)) {
return false;
}
}
// verify that the source surface is actually a texture
D3DSurfaceData d3dData = (D3DSurfaceData)srcData;
if (d3dData.getType() != D3DSurfaceData.TEXTURE) {
return false;
}
return true;
}