package me.hammerle.snuviengine.api; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.IntBuffer; import javax.imageio.ImageIO; import org.lwjgl.BufferUtils; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL12.*; import static org.lwjgl.opengl.GL13.*; public class Texture { public class Animation { private final IntBuffer[] data; private final int[] widths; private final int[] heights; private final int offsetX; private final int offsetY; private int index = 0; private Animation(int offsetX, int offsetY, String... paths) { this.offsetX = offsetX; this.offsetY = offsetY; int l = paths.length; data = new IntBuffer[l]; widths = new int[l]; heights = new int[l]; for(int i = 0; i < l; i++) { BufferedImage image = readImage(paths[i], false); if(offsetX + image.getWidth() > width || offsetY + image.getHeight() > height) { System.out.println(String.format("animation image '%s'is out of range", paths[i])); return; } widths[i] = image.getWidth(); heights[i] = image.getHeight(); data[i] = createBufferFromImage(image); } } public void nextFrame() { glActiveTexture(GL_TEXTURE0); glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, widths[index], heights[index], GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data[index]); index = (index + 1) % data.length; } } private static BufferedImage readImage(String path, boolean internal) { try { if(internal) { return ImageIO.read(Texture.class.getClassLoader().getResource("me/hammerle/snuviengine/resources/" + path)); } return ImageIO.read(new File(path)); } catch(IOException | IllegalArgumentException ex) { System.out.println(String.format("cannot read texture file '%s': %s", path, ex.getMessage())); return new BufferedImage(0, 0, BufferedImage.TYPE_INT_ARGB); } } private static IntBuffer createBufferFromImage(BufferedImage image) { IntBuffer buffer = BufferUtils.createIntBuffer(image.getWidth() * image.getHeight()); for(int y = 0; y < image.getHeight(); y++) { for(int x = 0; x < image.getWidth(); x++) { int c = image.getRGB(x, y); buffer.put((c << 8) | ((c >> 24) & 0xFF)); } } buffer.flip(); return buffer; } private static int boundTexture = -1; private final int texture; private final int width; private final int height; protected Texture(String path, boolean internal) { BufferedImage image = readImage(path, internal); IntBuffer buffer = createBufferFromImage(image); width = image.getWidth(); height = image.getHeight(); glActiveTexture(GL_TEXTURE0); texture = glGenTextures(); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer); } public Texture(String path) { this(path, false); } public Animation addAnimation(int offsetX, int offsetY, String... paths) { return new Animation(offsetX, offsetY, paths); } public void bind() { if(boundTexture != texture) { boundTexture = texture; glBindTexture(GL_TEXTURE_2D, texture); } } }