import entities.WindowConfig;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
public class Main {
private long variableYieldTime, lastTime;
// ウィンドウハンドル
private long hWnd;
//
private JumpGame jumpGame = new JumpGame();
// フルスクリーン
public boolean fullScreen;
//---------------------------------------------------------------
//---------------------------------------------------------------
// エントリーポイント
public static void main(String[] args) {
new Main().run(false);
}
//---------------------------------------------------------------
// メイン関数
public void run(boolean fullScreen) {
// フルスクリーンの真偽値を貰う
this.fullScreen = fullScreen;
// 色々初期化
initWindow();
initRender();
jumpGame.init();
// メインループ
while (!glfwWindowShouldClose(hWnd)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // バッファのクリア
jumpGame.update();
glfwSwapBuffers(hWnd); // バッファのスワップ
glfwPollEvents(); // 入力とかイベントの取得
}
// 終了処理
delete(); // デストラクタ
glfwFreeCallbacks(hWnd); // ウィンドウコールバックの解放
glfwDestroyWindow(hWnd); // ウィンドウの破棄
glfwTerminate(); // GLFWの破棄
glfwSetErrorCallback(null).free(); // エラーコールバックの解放
}
//---------------------------------------------------------------
//---------------------------------------------------------------
// ウィンドウの初期化
private void initWindow() {
GLFWErrorCallback.createPrint(System.err).set(); // エラーコールバックの設定
// GLFWの初期化
if (!glfwInit())
throw new IllegalStateException("Unable to initialize GLFW");
// ウィンドウの設定
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
// ウィンドウの作成
hWnd = glfwCreateWindow(WindowConfig.WIDTH, WindowConfig.HEIGHT, WindowConfig.TITLE_NAME, fullScreen ? glfwGetPrimaryMonitor() : NULL, NULL);
if (hWnd == NULL)
throw new RuntimeException("Failed to create the window.");
// ウィンドウをタゲにするのか?
glfwMakeContextCurrent(hWnd);
// v-syncの適応
glfwSwapInterval(1);
// ウィンドウの表示
glfwShowWindow(hWnd);
}
//---------------------------------------------------------------
// 描画プロセス初期化
private void initRender() {
GL.createCapabilities();
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // 背景色設定
// OpenGLの初期化
glEnable(GL_TEXTURE_2D); // 二次元テクスチャの有効化
glEnable(GL_BLEND); // アルファブレンディングの有効化
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // ブレンドモードの設定
}
//---------------------------------------------------------------
// デストラクタ
public void delete() {
jumpGame.delete();
}
//---------------------------------------------------------------
//
private void sync(int fps) {
if (fps <= 0) return;
long sleepTime = 1000000000 / fps; // nanoseconds to sleep this frame
// yieldTime + remainder micro & nano seconds if smaller than sleepTime
long yieldTime = Math.min(sleepTime, variableYieldTime + sleepTime % (1000*1000));
long overSleep = 0; // time the sync goes over by
try {
while (true) {
long t = System.nanoTime() - lastTime;
if (t < sleepTime - yieldTime) {
Thread.sleep(1);
}else if (t < sleepTime) {
// burn the last few CPU cycles to ensure accuracy
Thread.yield();
}else {
overSleep = t - sleepTime;
break; // exit while loop
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lastTime = System.nanoTime() - Math.min(overSleep, sleepTime);
// auto tune the time sync should yield
if (overSleep > variableYieldTime) {
// increase by 200 microseconds (1/5 a ms)
variableYieldTime = Math.min(variableYieldTime + 200*1000, sleepTime);
}
else if (overSleep < variableYieldTime - 200*1000) {
// decrease by 2 microseconds
variableYieldTime = Math.max(variableYieldTime - 2*1000, 0);
}
}
}
//---------------------------------------------------------------
}