RSS2.0

LWJGFont ver 1.1 をリリースしました

2014/2/25 にリリースした LWJGFont の更新版 ver1.1 をリリースしました。
LWJGFont は LWJGL 上で日本語文字列表示を簡単に実現するための、LWJGL の 3rd パーティライブラリです。

ver 1.0 では日本語文字列を表示するのに使いたいフォントのフォントファイルを手元に用意する必要がありましたが、ver 1.1 ではそれに加えて Java VM が認識しているシステムフォントも利用できるようになりました。とにもかくにもすぐに LWJGFont を使ってみたいという場合に OS にインストールされているフォントを使って日本語表示を実装できるようになりました。

LWJGFont_ver1.1.png
また ver 1.0 の Windows 環境で発生していたいくつかの不具合を修正し、安定性が向上しています。コマンドラインから実行する際に出力されるメッセージは実行環境にあわせて日英で切り替わるようになりした。
ひとまず先週の初期リリースで見逃してしまっていたバグについてはひと通り修正してありますので、すでに ver 1.0 をご利用頂いている方はぜひ最新版への乗り換えをお願いいたします。

なお、ver 1.1 へバージョンアップする際には再度 LWJGFont を実行し、フォントを jar ファイルに変換する必要があります。
加えて、net.chocolapod.lwjgfont.AbstractFont はクラス名が net.chocolapod.lwjgfont.LWJGFont に変更されているので注意してください。

システムフォントを使って日本語文字列を表示してみる

Windows 環境で MS P ゴシックを使って LWJGL から日本語文字列を表示してみたいと思います。

まず LWJGFont 公式ページから最新版の LWJGFont をダウンロードします。
次にコマンドプロンプトを起動し、LWJGFont をダウンロードしたフォルダに移動します。ここでは C:\Users\momokan\Downloads にダウンロードしたものとします。
> cd /d C:\Users\momokan\Downloads

LWJGFont に -l オプションを指定して実行し、システムにインストールされているフォントを確認します。利用できるシステムフォントは、ここで表示されるフォント一覧の中から指定する必要があります。
> java -jar lwjgfont-1.1.jar -l
Adobe Caslon Pro
Adobe Caslon Pro Bold
Adobe Fangsong Std R
Adobe Garamond Pro
Adobe Garamond Pro Bold
Adobe Heiti Std R
Adobe Kaiti Std R
Adobe Ming Std L
Adobe Myungjo Std M
Adobe Song Std L
Aharoni
Andalus
Angsana New
AngsanaUPC
Aparajita
Arabic Typesetting
Arial
...
Vrinda
Webdings
Wingdings
メイリオ
小塚ゴシック Pro B
小塚ゴシック Pro EL
小塚ゴシック Pro H
小塚ゴシック Pro L
小塚ゴシック Pro M
小塚ゴシック Pro R
小塚明朝 Pro B
小塚明朝 Pro EL
小塚明朝 Pro H
小塚明朝 Pro L
小塚明朝 Pro M
小塚明朝 Pro R
MS ゴシック
MS 明朝
MS Pゴシック
MS P明朝
私の環境ではシステムフォント一覧に『MS Pゴシック』と表示されたので、この名称をそのまま利用するフォントとして LWJGFont に指定することになります。

続いて LMJGFont でシステムフォントを LWJGL から呼び出すせる jar ファイルに変換します。ターミナルから以下のコマンドを実行してください。
>java -jar lwjgfont-1.1.jar -x

>java -jar lwjgfont-1.1.jar "MsPGothic@MS Pゴシック:24"
最初に -x オプションを指定して実行します。これは利用する文字ファイルをカレントディレクトリに展開する処理です。実行するとカレントディレクトリに characters というディレクトリが作られ、その中に LWJGFont から表示したい文字の一覧を書き出したテキストファイルが作成されます。デフォルトでは常用漢字までしか対象となっていないので、もし他に表示したい文字があれば、ここに書き加えてください。

2 つめのコマンドは、実際にフォントを LWJGFont から利用するための jar を生成する処理になります。システムフォントを利用する場合、『<Java クラス名>@<システムフォント名>:<フォントのサイズ>』という書式で指定してください。
'@' より前の<Java クラス名>は、システムフォント名が ASCII 文字のみの場合は自動設定されるので、指定しなくてもかまいません。指定すると、LWJGFont でシステムフォントを利用するための Java クラスがその名前で作成されます。
引数にはいくつでもフォントを指定することができます。

成功すると、以下のようなログがコマンドプロンプトに出力されます。
myfont-1.0-SNAPSHOT.jar を作成しました。
myfont-1.0-SNAPSHOT.pom.xml を作成しました。

* 変換したフォントとクラスの対応表
    net.chocolapod.lwjgfont.myfont.MsPGothicH24Font <- MsPGothic@MS Pゴシック (Size: 24)

* Maven ローカルリポジトリへのインストール方法
    > mvn install:install-file -Dfile=myfont-1.0-SNAPSHOT.jar -DpomFile=myfont-1.0-SNAPSHOT.pom.xml -DgroupId=net.chocolapod.lwjgfont -DartifactId=myfont -Dversion=1.0-SNAPSHOT -Dpackaging=jar

* Maven プロジェクトでの利用方法 ( pom.xml への設定内容 )
    --------------------------------------------------------------------
    <dependency>
        <groupId>net.chocolapod.lwjgfont</groupId>
        <artifactId>myfont</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    --------------------------------------------------------------------

Thanks!
システムフォントの変換処理が完了すると myfont-1.0-SNAPSHOT.jar という jar ファイルが作成されます。この myfont-1.0-SNAPSHOT.jar を LWJGL でゲーム開発しているプロジェクトの classpath に追加することで、LWJGFont を使って日本語文字列を表示できるようになります。
myfont-1.0-SNAPSHOT.jar は一度作成しておけば、使用するフォントとフォントサイズを変えない限り、使いまわすことができます。

いっしょに作られる myfont-1.0-SNAPSHOT.pom.xml は、Maven からこの jar ファイルを依存性解決するための pom.xml ファイルになります。もし Maven を使って LWJGL ゲームを開発しているのであれば、Maven ローカルリポジトリへのインストール方法として表示されたコマンドを実行することで、myfont-1.0-SNAPSHOT.jar と myfont-1.0-SNAPSHOT.pom.xml をインストールすることができます。
> mvn install:install-file -Dfile=myfont-1.0-SNAPSHOT.jar -DpomFile=myfont-1.0-SNAPSHOT.pom.xml -DgroupId=net.chocolapod.lwjgfont -DartifactId=myfont -Dversion=1.0-SNAPSHOT -Dpackaging=jar
続いて LWJGFont を呼び出す Java プロジェクト側で、pom.xml に、Maven プロジェクトでの利用方法として表示された内容を追記してください。
    <dependency>
        <groupId>net.chocolapod.lwjgfont</groupId>
        <artifactId>myfont</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

LWJGL で日本語文字列を表示する

以下に、実際に LWJGL ゲーム開発プロジェクト側で、LWJGFont を利用する際のプログラムを記載します。LWJGL のメインループ部分の抜粋になります。
//	LWJGFont でフォントを読み込む
LWJGFont	font = new MsPGothicH24Font();
			
//	LWJGL のメインループ
while (!Display.isCloseRequested()) {
	//	スクリーンを初期化する
	GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

	//	LWJGFont で日本語文字列を表示する
	font.drawString("あと特攻もがっかりかもね...", 100, 100, 0);

	//	スクリーンを更新する
	Display.update();
}
基本的な流れとしては、
1. LWJGFont インスタンスを作成する
2. LWJGFont.drawString() を呼び出す
の 2 ステップになります。

生成する LWJGFont インスタンスは変換したシステムフォントによって異なります。どのフォントでどの LWJGFont クラスのインスタンスを生成すればいいかは、jar への変換処理でメッセージに出力されます。
* 変換したフォントとクラスの対応表
    net.chocolapod.lwjgfont.myfont.MsPGothicH24Font <- MsPGothic@MS Pゴシック (Size: 24)
上記の場合、MS Pゴシックは net.chocolapod.lwjgfont.myfont.MsPGothicH24Font クラスに変換されたことになりますので、そのインスタンスを作成してください。

日本語文字列を表示するには drawString() メソッドを呼び出してください。第一引数が表示したい日本語文字列、第二~第三引数が表示先の座標 (X, Y, Z) になります。
LWJGFont クラスには他にもいくつかの文字列表示に関するメソッドが用意されています。詳細は以下のリンクを参照してください。
LWJGFont 公式ページ
LWJGFont ver 1.0 を公開しました 内の LWJGFont チートシート

LWJGFont ver 1.1 開発裏話

ver 1.0 は特に Windows 環境での不具合が多く発生してしまい、リリースからわずか 1 週間でのアップデートとなってしまいました。LWJGFont は Maven Central Repository で公開していることもあって、一度リリースしてしまうと、不具合を修正してアーカイブを差し替えるということができません。特に Windows でゲーム開発している利用者の皆様、申し訳ありませんでした。テストの強化はオープンソースプロジェクトとしては特に重要な課題だなと実感しています。

ver 1.1 の開発でもう 1 つポイントだったのが、LWJGFont で作成した jar の Maven 依存性解決についてです。
ver 1.0 で作成した jar は、LWJGFont 呼び出し側のゲーム開発プロジェクトで、作成した jar に加えて LWJGFont も pom.xml の dependencies タグに指定しなければなりませんでした。ver 1.1 ではこれを改善し、LWJGFont で作成した jar だけ dependencies タグに書き加えればいいようになっています。LWJGFont 自体は自動で依存性解決してくれるようになり、設定の手間が若干向上しました。

ひとまずこれで LWJGFont 開発はひと段落かな、といったところです。
もしご意見ご要望バグ報告などありましたら、このブログでも、Github でもかまいませんので、お気軽にお寄せください。
皆様の LWJGL でのゲーム開発が少しでも効率的になればと祈っております!
  LWJGFont 開発  コメント (9) 2014/03/02 11:38:52


公開範囲:
2014/10/24 20:08:35   ゲストさん 公開範囲: すべて, 承認済み
Slick2Dで表示させようとすると文字が反転してしまいました。

Slick2Dを使って文字を正しく表示することは可能でしょうか?
2014/10/24 21:48:28   momokan 公開範囲: すべて, 承認済み
ご利用ありがとうございます!

おそれいります、LWJGFont.drawString(dstX, dstY, dstZ) の第三引数に、0 以外の Z 座標を指定してますでしょうか?
ver 1.1 では内部で Z 座標の符号が反転する(* -1 されて認識される)というバグがあり、この影響かもしれません。
もしそうなら、例えば LWJGFont.drawString(100, 100, 100 * -1) というような呼び出し方をひとまず試していただけますか。

そうでないなら、文字が反転する現象が発生するコードを見せて頂けると嬉しいです。

お手数ですがよろしくお願いします。
2014/10/25 01:50:00   ゲストさん 公開範囲: すべて, 承認済み
コメント返信ありがとうございますm(__)m

Z座標を 100 * -1 という呼び出しにしたところ、画面に表示されなくなりました。

おそらくSlick2Dは、3Dに対応していないためZ座標が認識されないのだと思います。

以下、Slick2Dでのコードです。
----------------------------------------------------------------------------
public class MainClass extends BasicGame{
    public static void main(String[] args) throws SlickException{
       AppGameContainer app = new AppGameContainer(new MainClass());
        app.setTargetFrameRate(60);
        app.setDisplayMode(640,480,false);
        app.start();
    }
    public MainClass(){ super("タイトル"); }

        //フォントの読み込み
    LWJGFont font =  new Migu1pRegularH20Font();

    //描画処理
    public void render(GameContainer arg0, Graphics g) throws     
                         SlickException {
        try {
            font.drawString("はろー", 100, 100, 0);
            
        } catch (IOException e) { e.printStackTrace(); }
    }

    //初期処理
    public void init(GameContainer arg0) throws SlickException {}

    //更新処理
    public void update(GameContainer arg0, int arg1) throws 
                          SlickException {}
}
----------------------------------------------------------------------------
2014/10/25 12:03:17   momokan 公開範囲: すべて, 承認済み
返信ありがとうございます!

Z 座標反転の件、おっしゃる通り Slick2D では関係なかったですね。
わざわざ試していただきありがとうございました。

いただいたサンプルコードで手元で再現することができました。
少し手間がかかりますが、回避する方法もありましたので、
修正版のサンプルコードを最後に記載いたします。
追加した drawStringWithLWJGFont() にて LWJGFont で正しく文字列表示できます。

この現象は、Slick2D と LWJGFont でデフォルトの原点座標の位置が違うことが原因でした。
Slick2D では画面左上が原点となるため、Y 座標が大きいほど画面の下の方に表示されますが、LWJGFont では画面左下を原点として想定しているため、その逆となります。
LWJGFont は文字列表示において、内部で文字列の上端と下端の座標を指定しますが、
原点が左下にあることを想定して 下端の Y 座標 < 上端の Y 座標 となっているため、
Slick2D の座標系では文字列の上下の座標が逆転する結果となっていました。

OpenGL では描画時の原点は随時変更できますので、
LWJGFont を使う時だけ画面を Y 軸方向に 180 度回転させることで、
正常に文字列を表示することができるかと思います。
※Slick2D の座標系は org.newdawn.slick.opengl.renderer.ImmediateModeOGLRenderer.enterOrtho(int, int) にて設定されますが、座標系指定に関するパラメーターは存在しないため、Slick2D の初期設定処理を変更することはできませんでした。

とはいえ、毎回そのような手順を行うのも利便性が悪いので、
次のバージョンの LWJGFont では、もう少し対策を考えたいと思います。
私としても座標系については考慮が抜けていました。
このようなフィードバックをいただけてとてもありがたかったです。
ありがとうございました。

サンプルコードについて不明点などありましたらご連絡ください。


******* 以下修正版サンプルコードになります *******

import java.io.IOException;

import net.chocolapod.lwjgfont.LWJGFont;
import net.chocolapod.lwjgfont.example_demo.Migu1pRegularH45Font;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.opengl.renderer.Renderer;

public class MainClass extends BasicGame{
    //フォントの読み込み
    private LWJGFont    font = new Migu1pRegularH45Font();
    
    public MainClass(){
        super("タイトル");
    }

    //描画処理
    public void render(GameContainer arg0, Graphics g) throws SlickException {
        try {
            drawStringWithLWJGFont(g, "はろー", 100, 100);
            // font.drawString("はろー", 100, 100, 0);
        } catch (IOException e) { e.printStackTrace(); }
    }

    /**
     *  Slick2D ではデフォルトで画面左上が原点となるが、
     *  LWJGFont ver1.1 ではデフォルトで画面左下が原点となるよう glOrtho が呼ばれる。
     *  なので、LWJGFont で文字列表示する際には X 軸を中心に 180 度回転させた上で表示を行う。
     */
    public void drawStringWithLWJGFont(Graphics g, String text, int x, int y) throws IOException {
        // 移動・回転を行うため、行列スタックに現在の行列を退避させる
        g.pushTransform();

        // 原点(回転の中心点)を文字列の表示位置に移動する
        Renderer.get().glTranslatef(x, y + (font.getLineHeight() / 2), 0);
        // 原点を通る X 軸を中心に 180 度回転させ、Y 座標の方向を逆転させる
        Renderer.get().glRotatef(180, 1, 0, 0);
        
        // 原点に LWJGFont で文字列を表示する
        font.drawString(text, 0, 0, 0);
        
        // 行列スタックからもとの行列を取り出し、移動・回転前の状態に戻す
        g.popTransform();
    }

    //初期処理
    public void init(GameContainer arg0) throws SlickException {}

    //更新処理
    public void update(GameContainer arg0, int arg1) throws SlickException {}
    
    public static void main(String[] args) throws SlickException{
        AppGameContainer app = new AppGameContainer(new MainClass());
        app.setTargetFrameRate(60);
        app.setDisplayMode(640,480,false);
        app.start();
    }
}
2014/10/25 22:07:51   ゲストさん 公開範囲: すべて, 承認済み
返信遅れて申し訳ありませんm(__)m

サンプルコード実行した結果、正常に実行されました。
文字が反転して表示された原因は、Slick2DとLWJGLで座標の開始点が異なることで発生していたのですか・・・
Slick2Dでの動作を保証しているわけでないにも関わらず、動作が正常に至らなかった説明と
その対処法まで書いていただいて非常に助かりました。

LWJGFontを用いると、一からフォントセットを読み込む場合よりも圧倒的に起動速度が速いので助かります。
丁寧な解説と素晴らしいライブラリを開発していただきありがとうございます!
2014/10/26 07:45:18   momokan 公開範囲: すべて, 承認済み
無事に文字列表示できたとのこと、よかったです!

> LWJGFontを用いると、一からフォントセットを読み込む場合よりも圧倒的に起動速度が速いので助かります。

LWJGFont 設計時に Slick2D の drawString() よりも速く動作させることを意識していましたが、と言いつつ実際に Slick2D と性能検証したことはありませんでした…。
LWJGFont は準備するのが面倒なので分が悪いですが、動作については狙い通りに速度差が出ていたようでひと安心でした。

次のバージョンの LWJGFont では、初期読み込み時の速度を向上させる改良を加えていますので、リリースの折りにはぜひぜひ試していただけたらと思います!
2015/03/30 18:02:19   ゲストさん 公開範囲: すべて, 承認済み
java -jar lwjgfont-1.1.jar "MsPGothic@MS Pゴシック:24"を実行したところ
cmdでこのような表示が出たのですがどうすればちゃんと動くでしょうか、

Exception in thread "main" net.chocolapod.lwjgfont.exception.LwjgFontException:
SytemJavaCompiler が見つかりません。JDK に含まれる java コマンドで実行してください。
at net.chocolapod.lwjgfont.packager.SourceCompiler.compile(SourceCompiler.java:70)
at net.chocolapod.lwjgfont.packager.LwjgFontFactory.makePackage(LwjgFontFactory.java:122)
at net.chocolapod.lwjgfont.cli.Main.main(Main.java:67)

<環境>
Windows8.1
java version "1.8.0_31"
Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
Java HotSpot(TM) Client VM (build 25.31-b07, mixed mode, sharing)
2015/04/05 16:14:51   momokan 公開範囲: すべて, 承認済み
ご利用ありがとうございます!

実行している java コマンドが Java SE Runtime Environment (JRE) に付属のものとのことですが、開発用の Java SE Development Kit (JDK) に付属の java コマンドを使っていただけますか。

JRE は Java プログラムの実行用、JDK は Java プログラムの開発用なので、ゲーム開発をするなら JDK を用意されていることかと思います。
JDK / JRE が両方インストールされているなら、JRE が優先されているのだと思うので、代わりに JDK へパスを通してみてください。
2019/06/07 16:36:55   ゲストさん 公開範囲: すべて, 承認済み
lwjgl3でも動作しますか?
あとご存でしたら教えてくださいGoogle Noto fontも問題ないでしょうか?

https://www.google.com/get/noto/
プロフィール HN: ももかん
ゲーム作ったり雑談書いたり・・・していた時期が私にもありました。
カレンダー
<<2024, 11>>
272829303112
3456789
10111213141516
17181920212223
24252627282930