main.io.github.seba244c.icespire.graphics.Texture Maven / Gradle / Ivy
package io.github.seba244c.icespire.graphics;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import org.lwjgl.system.MemoryStack;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL30.glGenerateMipmap;
import static org.lwjgl.stb.STBImage.stbi_load;
import static org.lwjgl.stb.STBImage.stbi_failure_reason;
import static org.lwjgl.stb.STBImage.stbi_image_free;
import static org.lwjgl.stb.STBImage.stbi_load_from_memory;
/**
* A texture is a image can be applied to an material. Requires an image.
* @author Sebsa
* @since 1.0.2
*/
public class Texture {
private final int id;
private final int width;
private final int height;
public ByteBuffer imageBuffer;
public Texture(String fileName) throws Exception {
// Load Texture file
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer channels = stack.mallocInt(1);
imageBuffer = stbi_load(fileName, w, h, channels, 4);
if (imageBuffer == null) {
throw new IOException("Image file [" + fileName + "] not loaded: " + stbi_failure_reason());
}
width = w.get();
height = h.get();
}
this.id = createTexture(imageBuffer);
stbi_image_free(imageBuffer);
}
public Texture(ByteBuffer imageBuffer) throws Exception {
ByteBuffer buf;
// Load Texture file
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer channels = stack.mallocInt(1);
buf = stbi_load_from_memory(imageBuffer, w, h, channels, 4);
if (buf == null) {
throw new IOException("Image file not loaded: " + stbi_failure_reason());
}
width = w.get();
height = h.get();
}
this.id = createTexture(buf);
stbi_image_free(buf);
}
private int createTexture(ByteBuffer buf) {
// Create a new OpenGL texture
int textureId = glGenTextures();
// Bind the texture
glBindTexture(GL_TEXTURE_2D, textureId);
// Tell OpenGL how to unpack the RGBA bytes. Each component is 1 byte size
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Upload the texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, buf);
// Generate Mip Map
glGenerateMipmap(GL_TEXTURE_2D);
return textureId;
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public void bind() {
glBindTexture(GL_TEXTURE_2D, id);
}
public int getId() {
return id;
}
public void cleanup() {
glDeleteTextures(id);
}
}