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

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 Integer id = null; //OpenGLのテクスチャID
    private int width; // 読み込んだ画像の幅
    private int height; // 読み込んだ画像の高さ
    private ByteBuffer pixels;

    public Texture() {
    }

    public void setTextureData(int width, int height, ByteBuffer buffer) {
        this.width = width;
        this.height = height;
        this.pixels = buffer;
    }

    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)を作成
            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();

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

    public void init() {
        // 新しいテクスチャ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);
    }

    public Integer getId() {
        return id;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

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