Texture.java 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. package me.hammerle.snuviengine.api;
  2. import java.awt.image.BufferedImage;
  3. import java.io.File;
  4. import java.io.IOException;
  5. import java.nio.IntBuffer;
  6. import javax.imageio.ImageIO;
  7. import org.lwjgl.BufferUtils;
  8. import static org.lwjgl.opengl.GL11.*;
  9. import static org.lwjgl.opengl.GL12.*;
  10. import static org.lwjgl.opengl.GL13.*;
  11. public class Texture {
  12. public class Animation {
  13. private final IntBuffer[] data;
  14. private final int[] widths;
  15. private final int[] heights;
  16. private final int offsetX;
  17. private final int offsetY;
  18. private int index = 0;
  19. private Animation(int offsetX, int offsetY, String... paths) {
  20. this.offsetX = offsetX;
  21. this.offsetY = offsetY;
  22. int l = paths.length;
  23. data = new IntBuffer[l];
  24. widths = new int[l];
  25. heights = new int[l];
  26. for(int i = 0; i < l; i++) {
  27. BufferedImage image = readImage(paths[i], false);
  28. if(offsetX + image.getWidth() > width || offsetY + image.getHeight() > height) {
  29. System.out.println(String.format("animation image '%s'is out of range", paths[i]));
  30. return;
  31. }
  32. widths[i] = image.getWidth();
  33. heights[i] = image.getHeight();
  34. data[i] = createBufferFromImage(image);
  35. }
  36. }
  37. public void nextFrame() {
  38. glActiveTexture(GL_TEXTURE0);
  39. glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, widths[index], heights[index], GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data[index]);
  40. index = (index + 1) % data.length;
  41. }
  42. }
  43. private static BufferedImage readImage(String path, boolean internal) {
  44. try {
  45. if(internal) {
  46. return ImageIO.read(Texture.class.getClassLoader().getResource("me/hammerle/snuviengine/resources/" + path));
  47. }
  48. return ImageIO.read(new File(path));
  49. } catch(IOException | IllegalArgumentException ex) {
  50. System.out.println(String.format("cannot read texture file '%s': %s", path, ex.getMessage()));
  51. return new BufferedImage(0, 0, BufferedImage.TYPE_INT_ARGB);
  52. }
  53. }
  54. private static IntBuffer createBufferFromImage(BufferedImage image) {
  55. IntBuffer buffer = BufferUtils.createIntBuffer(image.getWidth() * image.getHeight());
  56. for(int y = 0; y < image.getHeight(); y++) {
  57. for(int x = 0; x < image.getWidth(); x++) {
  58. int c = image.getRGB(x, y);
  59. buffer.put((c << 8) | ((c >> 24) & 0xFF));
  60. }
  61. }
  62. buffer.flip();
  63. return buffer;
  64. }
  65. private static int boundTexture = -1;
  66. private final int texture;
  67. private final int width;
  68. private final int height;
  69. protected Texture(String path, boolean internal) {
  70. BufferedImage image = readImage(path, internal);
  71. IntBuffer buffer = createBufferFromImage(image);
  72. width = image.getWidth();
  73. height = image.getHeight();
  74. glActiveTexture(GL_TEXTURE0);
  75. texture = glGenTextures();
  76. glBindTexture(GL_TEXTURE_2D, texture);
  77. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  78. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  79. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  80. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  81. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
  82. }
  83. public Texture(String path) {
  84. this(path, false);
  85. }
  86. public Animation addAnimation(int offsetX, int offsetY, String... paths) {
  87. return new Animation(offsetX, offsetY, paths);
  88. }
  89. public void bind() {
  90. if(boundTexture != texture) {
  91. boundTexture = texture;
  92. glBindTexture(GL_TEXTURE_2D, texture);
  93. }
  94. }
  95. }