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.GL30.*; public class Texture { public class Animation { private IntBuffer[] data; private int[] wi; private int[] he; 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]; wi = new int[l]; he = new int[l]; for(int i = 0; i < l; i++) { BufferedImage image; try { image = ImageIO.read(new File(paths[i])); } catch(IOException | IllegalArgumentException ex) { throw new TextureException("cannot read texture file '" + paths[i] + "'"); } if(offsetX + image.getWidth() > w || offsetY + image.getHeight() > h) { System.out.println(offsetX + " " + image.getWidth() + " " + w + " " + offsetY + " " + image.getHeight() + " " + h); throw new TextureException("animation image '" + paths[i] + "'is out of range"); } wi[i] = image.getWidth(); he[i] = image.getHeight(); IntBuffer buffer = BufferUtils.createIntBuffer(wi[i] * he[i]); for(int y = 0; y < he[i]; y++) { for(int x = 0; x < wi[i]; x++) { int c = image.getRGB(x, y); buffer.put((c << 8) | ((c >> 24) & 0xFF)); } } buffer.flip(); data[i] = buffer; } } public void nextFrame() { GLHelper.glBindTexture(texture); glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, wi[index], he[index], GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data[index]); index = (index + 1) % data.length; } } private int texture = -1; private final String path; private final int w; private final int h; private IntBuffer buffer; public Texture(String path) { this.path = path; BufferedImage image; try { image = ImageIO.read(new File(path)); } catch(IOException | IllegalArgumentException ex) { throw new TextureException("cannot read texture file '" + path + "'"); } w = image.getWidth(); h = image.getHeight(); buffer = BufferUtils.createIntBuffer(w * h); for(int y = 0; y < h; y++) { for(int x = 0; x < w; x++) { int c = image.getRGB(x, y); buffer.put((c << 8) | ((c >> 24) & 0xFF)); } } buffer.flip(); Shader.addTask(() -> loadTexture()); } public Animation addAnimation(int offsetX, int offsetY, String... paths) { return new Animation(offsetX, offsetY, paths); } private void loadTexture() { if(texture != -1) { throw new TextureException("a texture is already loaded"); } texture = glGenTextures(); GLHelper.glBindTexture(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, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer); buffer = null; glGenerateMipmap(GL_TEXTURE_2D); } public void bindTexture() { if(texture == -1) { throw new TextureException("cannot load non loaded texture"); } GLHelper.glBindTexture(texture); } }