Newer
Older
AlgebraicDataflowArchitectureModel / GameEngine / src / main / java / gameEngine / entites / gameComponents / Texture.java
package gameEngine.entites.gameComponents;

import org.lwjgl.BufferUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;

import static org.lwjgl.opengl.GL11.*;

public class Texture {

    /*
    指定された画像ファイルを読み込み、そのピクセルデータをOpenGLにアップロードして
    テクスチャとして利用できるようにする
     */

    private int id; //OpenGLのテクスチャID
    private int width; // 読み込んだ画像の幅
    private int height; // 読み込んだ画像の高さ

    public Texture(String path) {
        BufferedImage bi;
        try {
            //ImageIO.read(new File(path)): 画像ファイルを読み込み、BufferedImageオブジェクトを作成
            //BufferedImageはJava標準ライブラリのクラス
            bi = ImageIO.read(new File(path));
            width = bi.getWidth();
            height = bi.getHeight();

            //画像のピクセルデータをRGB形式で取得
            //pixelsRawは整数配列で、各ピクセルの色データが格納される
            int[] pixelsRaw = bi.getRGB(0, 0, width, height, null, 0, width);

            //BufferUtils.createByteBuffer(width * height * 4): OpenGLに送信するためのバッファ(ByteBuffer)を作成
            ByteBuffer pixels = BufferUtils.createByteBuffer(width * height * 4);

            // 各ピクセルを取り出し、色成分(R, G, B, A)を抽出してByteBufferに格納
            // (pixel >> 16) & 0xFF: ピクセルデータの上位16ビットを右にシフトし、赤色成分を抽出。
            // 同様に緑(8ビット右シフト)、青(そのまま)、アルファ(24ビット右シフト)も抽出
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    int pixel = pixelsRaw[y * width + x];
                    pixels.put((byte) ((pixel >> 16) & 0xFF)); // Red
                    pixels.put((byte) ((pixel >> 8) & 0xFF));  // Green
                    pixels.put((byte) (pixel & 0xFF));         // Blue
                    pixels.put((byte) ((pixel >> 24) & 0xFF)); // Alpha
                }
            }
            // ByteBufferを読み込み可能な状態に
            pixels.flip();

            // 新しいテクスチャIDを生成
            id = glGenTextures();

            // 生成したテクスチャIDを現在のテクスチャとしてバインド
            // 以降のテクスチャ関連の操作はこのテクスチャに対して行われる
            glBindTexture(GL_TEXTURE_2D, id);

            // テクスチャデータをOpenGLに送信
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

            //テクスチャのフィルタリング方法を設定
            //ニアレストフィルタリング:拡大縮小時のぼやけがなくなる
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

            // テクスチャのバインディングを解除
            glBindTexture(GL_TEXTURE_2D, 0);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public int getId() {
        return id;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public void delete() {
        //テクスチャを削除し、OpenGLからリソースを解放します。
        glDeleteTextures(id);
    }
}