Newer
Older
AlgebraicDataflowArchitectureModel / GameEngine / src / main / java / org / example / Main.java
package org.example;
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;

import java.nio.*;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;

public class Main {

    // ウィンドウハンドル
    private long window;
    private final ColorController colorController = new ColorController();

    public void run() {
        System.out.println("Hello LWJGL " + Version.getVersion() + "!");

        init();
        loop();

        // ウィンドウのコールバックを解放し、ウィンドウを破棄
        glfwFreeCallbacks(window);
        glfwDestroyWindow(window);

        // GLFWを終了し、エラーコールバックを解放
        glfwTerminate();
        glfwSetErrorCallback(null).free();
    }

    private void init() {
        // エラーコールバックをセットアップします。デフォルトの実装はエラーメッセージをSystem.errに出力します。
        GLFWErrorCallback.createPrint(System.err).set();

        // GLFWを初期化します。これを行う前にほとんどのGLFW関数は動作しません。
        if ( !glfwInit() )
            throw new IllegalStateException("GLFWの初期化に失敗しました");

        // GLFWの設定
        glfwDefaultWindowHints(); // オプション、現在のウィンドウヒントはすでにデフォルト
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // ウィンドウ非表示
        glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); // ウィンドウサイズ変更を行わない

        // ウィンドウの作成
        window = glfwCreateWindow(800, 600, "Hello World!", NULL, NULL);
        if ( window == NULL )
            throw new RuntimeException("GLFWウィンドウの作成に失敗しました");

        // キーのコールバックを設定します。キーが押された、繰り返された、または放されたときに呼び出されます。
        glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
            if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
                glfwSetWindowShouldClose(window, true); // レンダリングループでこれを検出します
            if (action == GLFW_PRESS || action == GLFW_REPEAT) {
                colorController.handleInput(key); // キー入力に応じて色を変更
            }
        });

        // スレッドスタックを取得し、新しいフレームをプッシュします
        try ( MemoryStack stack = stackPush() ) {
            IntBuffer pWidth = stack.mallocInt(1); // int*
            IntBuffer pHeight = stack.mallocInt(1); // int*

            // glfwCreateWindowに渡されたウィンドウサイズを取得
            glfwGetWindowSize(window, pWidth, pHeight);

            // プライマリモニターの解像度を取得
            GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

            // ウィンドウを中央に配置
            glfwSetWindowPos(
                    window,
                    (vidmode.width() - pWidth.get(0)) / 2,
                    (vidmode.height() - pHeight.get(0)) / 2
            );
        } // スタックフレームは自動的にポップされます

        // OpenGLコンテキストを現在のスレッドに設定
        glfwMakeContextCurrent(window);
        // 垂直同期を有効化
        glfwSwapInterval(1);

        // ウィンドウを表示
        glfwShowWindow(window);
    }

    private void loop() {
        GL.createCapabilities();

        // レンダリングループ
        while (!glfwWindowShouldClose(window)) {
            // 現在の色でクリア
            glClearColor(colorController.getRed(), colorController.getGreen(), colorController.getBlue(), 0.0f);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // フレームバッファをクリア

            glfwSwapBuffers(window); // カラーバッファを交換

            glfwPollEvents(); // ウィンドウイベントをポーリング
        }

    }

    public static void main(String[] args) {
        new Main().run();
    }

}