package org.andengine.opengl.texture.atlas; import java.util.ArrayList; import org.andengine.opengl.texture.ITextureStateListener; import org.andengine.opengl.texture.PixelFormat; import org.andengine.opengl.texture.Texture; import org.andengine.opengl.texture.TextureManager; import org.andengine.opengl.texture.TextureOptions; import org.andengine.opengl.texture.atlas.source.ITextureAtlasSource; /** * (c) 2010 Nicolas Gramlich * (c) 2011 Zynga Inc. * * @author Nicolas Gramlich * @since 14:22:55 - 14.07.2011 */ public abstract class TextureAtlas<T extends ITextureAtlasSource> extends Texture implements ITextureAtlas<T> { // =========================================================== // Constants // =========================================================== // =========================================================== // Fields // =========================================================== protected final int mWidth; protected final int mHeight; protected final ArrayList<T> mTextureAtlasSources = new ArrayList<T>(); // =========================================================== // Constructors // =========================================================== public TextureAtlas(final TextureManager pTextureManager, final int pWidth, final int pHeight, final PixelFormat pPixelFormat, final TextureOptions pTextureOptions, final ITextureAtlasStateListener<T> pTextureAtlasStateListener) { super(pTextureManager, pPixelFormat, pTextureOptions, pTextureAtlasStateListener); this.mWidth = pWidth; this.mHeight = pHeight; } // =========================================================== // Getter & Setter // =========================================================== @Override public int getWidth() { return this.mWidth; } @Override public int getHeight() { return this.mHeight; } @Deprecated @Override public boolean hasTextureStateListener() { return super.hasTextureStateListener(); } @Override public boolean hasTextureAtlasStateListener() { return super.hasTextureStateListener(); } /** * @see {@link ITextureAtlas#setTextureStateListener(ITextureAtlasStateListener)} */ @Deprecated @Override public ITextureAtlasStateListener<T> getTextureStateListener() { return this.getTextureAtlasStateListener(); } @SuppressWarnings("unchecked") @Override public ITextureAtlasStateListener<T> getTextureAtlasStateListener() { return (ITextureAtlasStateListener<T>) super.getTextureStateListener(); } /** * @see {@link ITextureAtlas#setTextureStateListener(ITextureAtlasStateListener)} */ @Deprecated @Override public void setTextureStateListener(final ITextureStateListener pTextureStateListener) { super.setTextureStateListener(pTextureStateListener); } @Override public void setTextureAtlasStateListener(final ITextureAtlasStateListener<T> pTextureAtlasStateListener) { super.setTextureStateListener(pTextureAtlasStateListener); } // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== @Override public void addTextureAtlasSource(final T pTextureAtlasSource, final int pTextureX, final int pTextureY) throws IllegalArgumentException { this.checkTextureAtlasSourcePosition(pTextureAtlasSource, pTextureX, pTextureY); pTextureAtlasSource.setTextureX(pTextureX); pTextureAtlasSource.setTextureY(pTextureY); this.mTextureAtlasSources.add(pTextureAtlasSource); this.mUpdateOnHardwareNeeded = true; } @Override public void addTextureAtlasSource(final T pTextureAtlasSource, final int pTextureX, final int pTextureY, final int pTextureAtlasSourcePadding) throws IllegalArgumentException { this.addTextureAtlasSource(pTextureAtlasSource, pTextureX, pTextureY); if(pTextureAtlasSourcePadding > 0) { /* Left padding. */ if(pTextureX >= pTextureAtlasSourcePadding) { this.addEmptyTextureAtlasSource(pTextureX - pTextureAtlasSourcePadding, pTextureY, pTextureAtlasSourcePadding, pTextureAtlasSource.getTextureHeight()); } /* Top padding. */ if(pTextureY >= pTextureAtlasSourcePadding) { this.addEmptyTextureAtlasSource(pTextureX, pTextureY - pTextureAtlasSourcePadding, pTextureAtlasSource.getTextureWidth(), pTextureAtlasSourcePadding); } /* Right padding. */ if(pTextureX + pTextureAtlasSource.getTextureWidth() - 1 + pTextureAtlasSourcePadding <= this.getWidth()) { this.addEmptyTextureAtlasSource(pTextureX + pTextureAtlasSource.getTextureWidth(), pTextureY, pTextureAtlasSourcePadding, pTextureAtlasSource.getTextureHeight()); } /* Bottom padding. */ if(pTextureY + pTextureAtlasSource.getTextureHeight() - 1 + pTextureAtlasSourcePadding <= this.getHeight()) { this.addEmptyTextureAtlasSource(pTextureX, pTextureY + pTextureAtlasSource.getTextureHeight(), pTextureAtlasSource.getTextureWidth(), pTextureAtlasSourcePadding); } } } @Override public void removeTextureAtlasSource(final T pTextureAtlasSource, final int pTextureX, final int pTextureY) { final ArrayList<T> textureSources = this.mTextureAtlasSources; for(int i = textureSources.size() - 1; i >= 0; i--) { final T textureSource = textureSources.get(i); if(textureSource == pTextureAtlasSource && textureSource.getTextureX() == pTextureX && textureSource.getTextureY() == pTextureY) { textureSources.remove(i); this.mUpdateOnHardwareNeeded = true; return; } } } @Override public void clearTextureAtlasSources() { this.mTextureAtlasSources.clear(); this.mUpdateOnHardwareNeeded = true; } // =========================================================== // Methods // =========================================================== private void checkTextureAtlasSourcePosition(final T pTextureAtlasSource, final int pTextureX, final int pTextureY) throws IllegalArgumentException { if(pTextureX < 0) { throw new IllegalArgumentException("Illegal negative pTextureX supplied: '" + pTextureX + "'"); } else if(pTextureY < 0) { throw new IllegalArgumentException("Illegal negative pTextureY supplied: '" + pTextureY + "'"); } else if(pTextureX + pTextureAtlasSource.getTextureWidth() > this.getWidth() || pTextureY + pTextureAtlasSource.getTextureHeight() > this.getHeight()) { throw new IllegalArgumentException("Supplied pTextureAtlasSource must not exceed bounds of Texture."); } } // =========================================================== // Inner and Anonymous Classes // =========================================================== }