Texture.java 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. import static org.lwjgl.opengl.GL20.*;
  12. import static org.lwjgl.opengl.GL30.*;
  13. import static org.lwjgl.opengl.GL33.*;
  14. public class Texture
  15. {
  16. public class Animation
  17. {
  18. private IntBuffer[] data;
  19. private int[] wi;
  20. private int[] he;
  21. private final int offsetX;
  22. private final int offsetY;
  23. private int index = 0;
  24. private Animation(int offsetX, int offsetY, String... paths)
  25. {
  26. this.offsetX = offsetX;
  27. this.offsetY = offsetY;
  28. int l = paths.length;
  29. data = new IntBuffer[l];
  30. wi = new int[l];
  31. he = new int[l];
  32. for(int i = 0; i < l; i++)
  33. {
  34. BufferedImage image;
  35. try
  36. {
  37. image = ImageIO.read(new File(paths[i]));
  38. }
  39. catch(IOException | IllegalArgumentException ex)
  40. {
  41. throw new TextureException("cannot read texture file '" + paths[i] + "'");
  42. }
  43. if(offsetX + image.getWidth() > w || offsetY + image.getHeight() > h)
  44. {
  45. System.out.println(offsetX + " " + image.getWidth() + " " + w + " " + offsetY + " " + image.getHeight() + " " + h);
  46. throw new TextureException("animation image '" + paths[i] + "'is out of range");
  47. }
  48. wi[i] = image.getWidth();
  49. he[i] = image.getHeight();
  50. IntBuffer buffer = BufferUtils.createIntBuffer(wi[i] * he[i]);
  51. for(int y = 0; y < he[i]; y++)
  52. {
  53. for(int x = 0; x < wi[i]; x++)
  54. {
  55. int c = image.getRGB(x, y);
  56. buffer.put((c << 8) | ((c >> 24) & 0xFF));
  57. }
  58. }
  59. buffer.flip();
  60. data[i] = buffer;
  61. }
  62. }
  63. public void nextFrame()
  64. {
  65. glActiveTexture(GL_TEXTURE0 + textureUnit);
  66. glTexSubImage2D(GL_TEXTURE_2D, 0, offsetX, offsetY, wi[index], he[index], GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, data[index]);
  67. index = (index + 1) % data.length;
  68. }
  69. }
  70. private int texture = -1;
  71. private final String path;
  72. private final int w;
  73. private final int h;
  74. private IntBuffer buffer;
  75. private static int textureUnits = 1;
  76. private int textureUnit = -1;
  77. private static int boundSampler = -1;
  78. private int sampler = -1;
  79. private int sampLoc = -1;
  80. public Texture(String path, boolean internal)
  81. {
  82. this.path = path;
  83. BufferedImage image;
  84. try
  85. {
  86. if(internal)
  87. {
  88. image = ImageIO.read(Texture.class.getClassLoader().getResource("me/hammerle/snuviengine/resources/" + path));
  89. }
  90. else
  91. {
  92. image = ImageIO.read(new File(path));
  93. }
  94. }
  95. catch(IOException | IllegalArgumentException ex)
  96. {
  97. throw new TextureException("cannot read texture file '" + path + "'");
  98. }
  99. w = image.getWidth();
  100. h = image.getHeight();
  101. buffer = BufferUtils.createIntBuffer(w * h);
  102. for(int y = 0; y < h; y++)
  103. {
  104. for(int x = 0; x < w; x++)
  105. {
  106. int c = image.getRGB(x, y);
  107. buffer.put((c << 8) | ((c >> 24) & 0xFF));
  108. }
  109. }
  110. buffer.flip();
  111. Shader.addTask(() -> loadTexture());
  112. }
  113. public Texture(String path)
  114. {
  115. this(path, false);
  116. }
  117. public Animation addAnimation(int offsetX, int offsetY, String... paths)
  118. {
  119. return new Animation(offsetX, offsetY, paths);
  120. }
  121. private void loadTexture()
  122. {
  123. if(texture != -1)
  124. {
  125. throw new TextureException("a texture is already loaded");
  126. }
  127. sampler = glGenSamplers();
  128. sampLoc = glGetUniformLocation(Shader.getProgram(), "samp");
  129. glUniform1i(sampLoc, sampler);
  130. textureUnit = textureUnits;
  131. textureUnits++;
  132. glBindSampler(GL_TEXTURE0 + textureUnit, sampler);
  133. glActiveTexture(GL_TEXTURE0 + textureUnit);
  134. texture = glGenTextures();
  135. glBindTexture(GL_TEXTURE_2D, texture);
  136. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  137. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  138. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  139. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  140. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
  141. buffer = null;
  142. glGenerateMipmap(GL_TEXTURE_2D);
  143. }
  144. public void bind()
  145. {
  146. if(texture == -1)
  147. {
  148. throw new TextureException("cannot load non loaded texture");
  149. }
  150. if(boundSampler != sampler)
  151. {
  152. boundSampler = sampler;
  153. glUniform1i(sampLoc, sampler);
  154. }
  155. }
  156. }