123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- 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 TextureAtlas
- {
- private static final Texture NULL_TEXTURE = new Texture(0.0f, 0.0f, 0.0f, 0.0f);
-
- private static class Texture
- {
- private final float minX;
- private final float minY;
- private final float maxX;
- private final float maxY;
- private Texture(float minX, float minY, float maxX, float maxY)
- {
- this.minX = minX;
- this.minY = minY;
- this.maxX = maxX;
- this.maxY = maxY;
- }
- }
-
- private final int tileWidth;
- private final int tileHeight;
- private final int width;
- private final int height;
-
- private Texture[] textures;
- private int textureIndex = 0;
- private final int[][] data;
-
- private int texture = -1;
-
- private boolean generated = false;
-
- protected TextureAtlas(int tileWidth, int tileHeight, int width, int height)
- {
- this.tileWidth = tileWidth;
- this.tileHeight = tileHeight;
- this.width = width * tileWidth;
- this.height = height * tileHeight;
-
- textures = new Texture[width * height];
- for(int i = 0; i < textures.length; i++)
- {
- textures[i] = NULL_TEXTURE;
- }
-
- data = new int[this.width][this.height];
-
- for(int x = 0; x < this.width; x++)
- {
- for(int y = 0; y < this.height; y++)
- {
- data[x][y] = 0xFF0000FF;
- }
- }
- }
-
- protected void generateTexture()
- {
- if(generated)
- {
- throw new TextureException("the texture is already generated");
- }
- generated = true;
-
- texture = glGenTextures();
- glBindTexture(GL_TEXTURE_2D, texture);
- IntBuffer buffer = BufferUtils.createIntBuffer(width * height);
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- buffer.put(data[x][y]);
- }
- }
- buffer.flip();
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, buffer);
- }
- protected void bindTexture()
- {
- glActiveTexture(GL_TEXTURE0);
- 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);
- }
-
- private int convertColor(int c)
- {
- return (c << 8) | ((c >> 24) & 0xFF);
- }
-
- public int addTexture(String path)
- {
- if(generated)
- {
- throw new TextureException("cannot add a texture to an already generated texture atlas");
- }
- else if(textureIndex == textures.length)
- {
- throw new TextureException("the texture atlas is full");
- }
-
- BufferedImage image;
- try
- {
- image = ImageIO.read(new File(path));
- }
- catch(IOException | IllegalArgumentException ex)
- {
- throw new TextureException("cannot add texture '" + path + "'");
- }
-
- if(image.getWidth() != tileWidth || image.getHeight() != tileHeight)
- {
- throw new TextureException("size of '" + path + "' is " + image.getWidth() + "x" + image.getHeight() + ", expected is " + tileWidth + "x" + tileHeight);
- }
- int x = (textureIndex % width) * tileWidth;
- int y = (textureIndex / height) * tileHeight;
- textures[textureIndex] = new Texture(((float) x) / width, ((float) y) / height, ((float) (x + tileWidth)) / width, ((float) (y + tileHeight)) / height);
- textureIndex++;
- for(int ix = 0; ix < image.getWidth(); ix++)
- {
- for(int iy = 0; iy < image.getHeight(); iy++)
- {
- data[ix + x][iy + y] = convertColor(image.getRGB(ix, image.getHeight() - iy - 1));
- }
- }
- return textureIndex - 1;
- }
-
- protected float getTextureMinX(int index, boolean hFlip)
- {
- if(hFlip)
- {
- return textures[index].maxX;
- }
- return textures[index].minX;
- }
-
- protected float getTextureMaxX(int index, boolean hFlip)
- {
- if(hFlip)
- {
- return textures[index].minX;
- }
- return textures[index].maxX;
- }
-
- protected float getTextureMinY(int index, boolean vFlip)
- {
- if(vFlip)
- {
- return textures[index].maxY;
- }
- return textures[index].minY;
- }
-
- protected float getTextureMaxY(int index, boolean vFlip)
- {
- if(vFlip)
- {
- return textures[index].minY;
- }
- return textures[index].maxY;
- }
- }
|