/* * Copyright (c) 2003-onwards Shaven Puppy Ltd * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions 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 'Shaven Puppy' nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.shavenpuppy.jglib.sprites; import org.lwjgl.opengl.OpenGLException; import org.w3c.dom.Element; import com.shavenpuppy.jglib.Resource; import com.shavenpuppy.jglib.Resources; import com.shavenpuppy.jglib.opengl.GLBaseTexture; import com.shavenpuppy.jglib.util.XMLUtil; /** * An SpriteImage is just a quad inside a texture. * Because a SpriteImage no public constructor taking a name as an argument it cannot * be mapped and created directly in the resources XML file. */ public class SpriteImage extends Resource implements Appearance { private static final long serialVersionUID = 1L; /** The imagebank, if any */ private transient ImageBank imageBank; /** The image bank name */ private String imageBankName; /** The texture */ private transient GLBaseTexture texture; /** The rendering style */ private transient Style style; /** The name of the rendering style */ private String styleName; /** The pixel coordinates of the image and its hotspot */ private int x, y, w, h, hotspotx, hotspoty; /** Offset */ private boolean offset = true; /** The quad's texture coordinates */ private float tx0, tx1, ty0, ty1; /** * C'tor */ protected SpriteImage() { } /** * Constructor for SpriteImage. */ SpriteImage(String name, String imageBankName, String styleName) { this(name); this.imageBankName = imageBankName; this.styleName = styleName; } /** * Constructor with known quad dimensions in pixels */ SpriteImage(String name, String imageBankName, String styleName, int x, int y, int w, int h, int hotspotx, int hotspoty, boolean offset) { this(name, imageBankName, styleName); this.x = x; this.y = y; this.w = w; this.h = h; this.hotspotx = hotspotx; this.hotspoty = hotspoty; this.offset = offset; } /** * Constructor with known quad dimensions in pixels and existing GL texture and styles */ public SpriteImage(GLBaseTexture texture, Style style, int x, int y, int w, int h, int hotspotx, int hotspoty, boolean offset) { this.texture = texture; this.style = style; this.x = x; this.y = y; this.w = w; this.h = h; this.hotspotx = hotspotx; this.hotspoty = hotspoty; this.offset = offset; } /** * Public constructor for simply making the image from a whole texture */ public SpriteImage(String texture, String styleName, int hotspotx, int hotspoty) { this(texture + "-image"); this.texture = Resources.get(texture); this.style = (Style) Resources.get(styleName); this.hotspotx = hotspotx; this.hotspoty = hotspoty; this.w = this.texture.getWidth(); this.h = this.texture.getHeight(); tx1 = 1.0f; ty1 = 1.0f; } /** * Public constructor for simply making a spriteimage without a texture */ public SpriteImage(String styleName, int width, int height, int hotspotx, int hotspoty) { this(styleName+"-"+width+"x"+height); this.styleName = styleName; this.hotspotx = hotspotx; this.hotspoty = hotspoty; this.w = width; this.h = height; } /** * Ensure registration of the image with our little map, and get us an index number too */ private SpriteImage(String name) { super(name); } /** * Load from an XML element */ @Override public void load(Element element, Resource.Loader loader) throws Exception { x = Integer.parseInt(element.getAttribute("x")); y = Integer.parseInt(element.getAttribute("y")); w = Integer.parseInt(element.getAttribute("w")); h = Integer.parseInt(element.getAttribute("h")); hotspotx = Integer.parseInt(element.getAttribute("hx")); hotspoty = Integer.parseInt(element.getAttribute("hy")); styleName = element.getAttribute("style"); offset = XMLUtil.getBoolean(element, "offset", true); } /** * Calculate the texture coordinates of the quad */ private void calculateTextureCoordinates() { double tw = texture.getWidth(); double th = texture.getHeight(); // Offset: the default for linear styled textures if (offset) { tx0 = (float) ((x + 0.5f) / tw); tx1 = (float) ((x + w - 0.5f) / tw); ty0 = (float) ((y + 0.5f) / th); ty1 = (float) ((y + h - 0.5f) / th); } else { // Not offset: for linear styled textures tx0 = (float) (x / tw); tx1 = (float) ((x + w) / tw); ty0 = (float) (y / th); ty1 = (float) ((y + h) / th); } } /* (non-Javadoc) * @see ALResource#doCreate() */ @Override protected void doCreate() { if (texture == null) { if (imageBankName != null) { imageBank = (ImageBank) Resources.get(imageBankName); if (imageBank == null) { throw new OpenGLException("Imagebank " + imageBankName + " does not exist"); } texture = imageBank.texture; if (texture == null) { throw new OpenGLException("Imagebank " + imageBankName +" has no texture"); } } } if (style == null) { if (styleName == null || "".equals(styleName)) { styleName = imageBank.getDefaultStyleName(); } style = (Style) Resources.get(styleName); } if (texture != null) { calculateTextureCoordinates(); } } @Override public void archive() { imageBankName = null; styleName = null; } /* (non-Javadoc) * @see ALResource#doDestroy() */ @Override protected void doDestroy() { imageBank = null; texture = null; } /** * Accessor */ public final int getWidth() { return w; } /** * Accessor */ public final int getHeight() { return h; } /** * Gets the tx0. * @return Returns a float */ public final float getTx0() { return tx0; } /** * Gets the tx1. * @return Returns a float */ public final float getTx1() { return tx1; } /** * Gets the ty0. * @return Returns a float */ public final float getTy0() { return ty0; } /** * Gets the ty1. * @return Returns a float */ public final float getTy1() { return ty1; } /** * Gets the hotspotx. * @return Returns a int */ public final int getHotspotX() { return hotspotx; } /** * Gets the hotspoty. * @return Returns a int */ public final int getHotspotY() { return hotspoty; } /** * Gets the texture. * @return Returns a GLTexture */ public final GLBaseTexture getTexture() { return texture; } /** * Returns the style. * @return Style */ public Style getStyle() { return style; } @Override public boolean toSprite(Sprite target) { target.setImage(this); return false; } /** * @return the x */ public int getX() { return x; } /** * @return the y */ public int getY() { return y; } }