package gui;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glColor4f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glTexCoord2f;
import static org.lwjgl.opengl.GL11.glVertex2f;
public class Icon {
int toggle;
boolean tex;
private int height;
private int width;
private int texID;
private ByteBuffer data;
private IntBuffer dataInt;
/**
* Load the specified texture and bind it into OpenGL
*
* @param filename Filename to load
* @throws IOException If there are errors loading image
*/
public Icon(String filename) throws IOException {
// BufferedImage img = ImageIO.read(new File(filename));
BufferedImage img = ImageIO.read(ClassLoader.getSystemResourceAsStream(filename));
width = img.getWidth();
height = img.getHeight();
data = BufferUtils.createByteBuffer(height * width * 4);
// Some wierd flip-flop that gets it oriented right (I think.... >.>)
for (int x = height - 1; x > -1; x--) {
for (int y = 0; y < width; y++) {
int rgba = img.getRGB(y, x);
byte b = (byte) (rgba >> 0 & 0xFF);
byte g = (byte) (rgba >> 8 & 0xFF);
byte r = (byte) (rgba >> 16 & 0xFF);
byte a = (byte) (rgba >> 24 & 0xFF);
data.put(r);
data.put(g);
data.put(b);
data.put(a);
}
}
data.rewind();
texID = bindToTexture();
data = null;
}
public Icon(int[] pixels, int width, int height) {
// BufferedImage img = ImageIO.read(new File(filename));
this.width = width;
this.height = height;
dataInt = ByteBuffer.allocateDirect(pixels.length * 4).asIntBuffer();
dataInt.put(pixels);
dataInt.flip();
texID = bindToTexture();
dataInt = null;
}
/**
* Calls glBindTexture(GL_TEXTURE_2D, textureID)
*/
public void glBindTexture() {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texID);
}
/**
* Get the height of this texture in pixels
*
* @return Height of this texture in pixels
*/
public int getHeight() {
return height;
}
/**
* Get the width of this texture in pixels
*
* @return Widht of this texture in pixels
*/
public int getWidth() {
return width;
}
/**
* Get the OpenGL texture ID used by this texture
*
* @return OpenGL texture ID
*/
public int getTexID() {
return texID;
}
/**
* Returns an int color of the 4 provided colors (they should be in the
* range 0-255)
*
* @param r Red component of color
* @param g Green component of color
* @param b Blue component of color
* @param a Alpha component of color
* @return Integer version of color provided
*/
public int intColor(short r, short g, short b, short a) {
int out = 0;
out |= (a & 0x00FF) << 0;
out |= (b & 0x00FF) << 8;
out |= (g & 0x00FF) << 16;
out |= (r & 0x00FF) << 24;
return out;
}
/**
* Render this texture at a 1:1 ratio
*
* @param startX X position to render at
* @param startY Y position to render at
* @param texX X position to start at of texture in pixels
* @param texY Y position to start at of texture in pixels
* @param width Width to render
* @param height Height to render
*/
public void render(float startX, float startY, float texX, float texY, float width, float height) {
this.render(startX, startY, texX, texY, width, height, 0);
}
/**
* Render this texture at a 1:1 ratio with rotation
*
* @param startX X position to render at
* @param startY Y position to render at
* @param texX X position to start at of texture in pixels
* @param texY Y position to start at of texture in pixels
* @param width Width to render
* @param height Height to render
* @param rot Angle to render at
*/
public void render(float startX, float startY, float texX, float texY, float width, float height, float rot) {
float one = 1.0F / (float) getWidth();
// texY = 1024 - texY;
texY = getHeight() - height - texY;
float w = width;
float h = height;
GL11.glBindTexture(GL_TEXTURE_2D, texID);
GL11.glPushMatrix();
GL11.glTranslatef(startX, startY, 0);
GL11.glRotatef(rot, 0, 0, 1);
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1);
glTexCoord2f(texX * one, texY * one);
glVertex2f(0, 0);
glTexCoord2f(texX * one + w * one, texY * one);
glVertex2f(w, 0);
glTexCoord2f(texX * one + w * one, texY * one + h * one);
glVertex2f(w, h);
glTexCoord2f(texX * one, texY * one + h * one);
glVertex2f(0, h);
glEnd();
GL11.glPopMatrix();
}
/**
* Render this texture at a 1:1 ratio, centered at the position given
*
* @param startX X position to render at
* @param startY Y position to render at
* @param texX X position to start at of texture in pixels
* @param texY Y position to start at of texture in pixels
* @param width Width to render
* @param height Height to render
* @param rot Angle to render at
*/
public void renderCentered(float startX, float startY, float texX, float texY, float width, float height, float rot) {
float one = 1.0F / (float) getWidth();
// texY = 1024 - texY;
texY = getHeight() - height - texY;
float w = width;
float h = height;
GL11.glBindTexture(GL_TEXTURE_2D, texID);
GL11.glPushMatrix();
GL11.glTranslatef(startX, startY, 0);
GL11.glRotatef(rot, 0, 0, 1);
glBegin(GL_QUADS);
// glColor4f(1, 1, 1, 1);
glTexCoord2f(texX * one, texY * one);
glVertex2f(-w / 2, -h / 2);
glTexCoord2f(texX * one + w * one, texY * one);
glVertex2f(w / 2, -h / 2);
glTexCoord2f(texX * one + w * one, texY * one + h * one);
glVertex2f(w / 2, h / 2);
glTexCoord2f(texX * one, texY * one + h * one);
glVertex2f(-w / 2, h / 2);
glEnd();
GL11.glPopMatrix();
}
public void update(int[] pixels, int xOff, int yOff, int width, int height) {
if (pixels.length != width * height) {
throw new IllegalArgumentException("Array was of wrong length for this texture!");
}
if (xOff + width > this.width || yOff + height > this.height) {
throw new IllegalArgumentException("Cannot update texture: would go out of bounds.");
}
dataInt = ByteBuffer.allocateDirect(pixels.length * 4).asIntBuffer();
dataInt.put(pixels);
dataInt.flip();
updateData(texID, xOff, yOff, width, height);
dataInt = null;
}
/**
* Binds this texture to a new OpenGL texture
*
* @return The new OpenGL texture ID
*/
private int bindToTexture() {
int tex = GL11.glGenTextures();
bindData(tex);
return tex;
}
private void bindData(int tex) {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, tex);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); // Linear Filtering
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); // Linear Filtering
if (data != null) {
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, data);
} else if (dataInt != null) {
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, dataInt);
}
}
private void updateData(int tex, int xOff, int yOff, int width, int height) {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, tex);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST); // Linear Filtering
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST); // Linear Filtering
if (data != null) {
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, xOff, yOff, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, data);
} else if (dataInt != null) {
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, xOff, yOff, width, height, GL11.GL_RGBA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, dataInt);
}
}
}