package org.example; import org.lwjgl.*; import org.lwjgl.glfw.*; import org.lwjgl.opengl.*; import org.lwjgl.system.*; import java.nio.*; import java.util.ArrayList; import java.util.List; 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 List<IGameComponent> iGameComponents = new ArrayList<>(); public static void main(String[] args) { new Main().run(); } public void run() { System.out.println("Hello LWJGL " + Version.getVersion() + "!"); init(); loop(); glfwFreeCallbacks(window);// ウィンドウのコールバックを解放し、ウィンドウを破棄 glfwDestroyWindow(window); glfwTerminate(); // GLFWを終了し、エラーコールバックを解放 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); // レンダリングループでこれを検出します }); // スレッドスタックを取得し、新しいフレームをプッシュします 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 ); } // スタックフレームは自動的にポップされます glfwMakeContextCurrent(window); // OpenGLコンテキストを現在のスレッドに設定 glfwSwapInterval(1); // 垂直同期を有効化 glfwShowWindow(window); // ウィンドウを表示 //--------------------------------------------------------------- KeyInput.init(window); iGameComponents.add(new ColorController()); //GameComponentのinit処理 for (IGameComponent gameComponents : iGameComponents) { gameComponents.init(); } //--------------------------------------------------------------- } private void loop() { GL.createCapabilities(); while (!glfwWindowShouldClose(window)) { //--------------------------------------------------------------- // 毎フレームのキー状態を更新 KeyInput.updateKeyStates(); //GameComponentのupdate処理 for (IGameComponent gameComponents : iGameComponents) { gameComponents.update(); } //--------------------------------------------------------------- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // フレームバッファをクリア glfwSwapBuffers(window); // カラーバッファを交換 glfwPollEvents(); // ウィンドウイベントをポーリング } } }