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(); } }