Drawing a String of Characters using OpenGL.

 

Introduction

このページでは、OpenGLを使って、文字列を描画するプログラムを公開しています。フォントサイズと位置はOpenGLの変換行列でコントロールできます。なので、普通は、glScale (glScaled / glScalef)でフォントサイズを、glTranslate (glTranslated / glTranslatef)で描画位置をコントロールします。また、(汚い)フォントを内蔵(?)しているので、プラットフォーム依存のフォントを使う必要はありません。

OpenGLは強力なグラフィックスツールキットですが、文字列を書くのが得意でありません。文字列を描画するには、一般的には、WindowsならwglUseFontBitmap、X-WindowならglXUseXFont関数を使ったりしますが、どちらもプラットフォーム依存なので、移植性が無くなります。#ifdef, #else, #endifで互いのプラットフォームでコンパイルできるようにはできますが、違うプラットフォームに同じフォントがあるとは限らないのでやっぱり移植するとき困ります。さらに、上記の関数を使ったとしても、フォントの厳密な大きさや位置を指定できません。標準で十分な機能を持った文字列描画関数が無いという点は、OpenGLの大きな問題です。

YSFLIGHTに計器パネルを追加しようとしたとき、僕もこの問題に直面して、仕方ないので、数年前に作ったフォントを引っ張り出してきて、OpenGLから利用できるようにしました。(漢字は出ませんが)。この小さなコードは、多分似たような問題を持った人には有用なのではないかと思います。そこで、せっかくなので、ここで公開することにしました。使い方は、uglyfont.cppuglyfont.hをダウンロードして、文字列を描画したいプログラムの頭に #include "uglyfont.h" と追加してください。関数の使い方は下に書きます。なお、例題(sample.cpp)も参考にしてみてください。

著作権について

一応、uglyfont.cpp, uglyfont.h, sample.cppの著作権は放棄しません。が、商用、非商用、オープンソース、非オープンソースを問わず、このプログラムを利用していただいて結構です。また、使用許可を僕に問い合わせていただかなくてもそのまま利用していただいて結構です。が、このプログラムを利用した結果何が起きても僕は責任を負いませんので、利用いただく場合は自分の責任でご利用ください。

関数の使い方について

文字列描画関数の定義は次のとおりです。

void YsDrawUglyFont(const char str[],int centering,int useDisplayList=1);

const char str[] 文字列
int centering 1のとき、文字列をセンタリングします。0だと、左下角がローカル座標系の原点に来ます。
int useDisplayList 1のとき、OpenGLのディスプレイリストを使います。ディスプレイリスト1400番から1655番まで占有します。もしも、困る場合は、uglyfont.cppの中のconst int YsUglyFontBase=1400;というところを修正してください。glGenListsを使えばいいんでしょうけど、手抜きしました(^_^;)ディスプレイリストを使った方がCPUとグラフィックスハードウェア間のトランザクションが減ってパフォーマンスは向上するはずです。

フォントサイズは、glScale (glScalef or glScaled).でコントロールできます。スケーリングの指定が無いとき、フォントサイズは1.0x1.0x0.0になります。文字の左下角が(0,0,0)で、右上角が(1,1,0)です。(下の絵のような感じ)

なので、N文字書くとすると、文字列は(0,0,0)-(N,1,0).のバウンディングボックスに収まります。(wglとかglXとかを使ってるとこれができなくて往生した)

なお、例えば glScalef(0.5,0.5,0.5); とやってから描画すると下のような感じになります。

下のふたつの絵はcenteringの効果を比較しています。centeringに0を指定すると、次のように描画します。

 

これに対して、centeringが1だと、文字列が中心になるように描画するので、次のような結果になります。

また、2次元で描画したいときは、Projection matrix, Modelview matrixを正しくセットした上で(sample.cppも参照してください)、次のように記述します。

glPushMatrix();
glTranslatef(x,y,0);
glScalef(fontWid,-fontHei,1.0);
YsDrawUglyFont("ABCDEF",0);
glPopMatrix();

(x,y)は画面座標で、fontWidとfontHeiはフォントサイズです。なお、glScalef の第2パラメータにマイナスサインをつけていますが、これは、画面座標を(0,0)が画面の左上角で、Yの正の方向を画面下向きに設定した場合(多分それが普通だと思う)、文字の座標系と画面座標系のY軸方向が逆転してしまうためです。もしも、左下角が(0,0)で、Yの正の方向が画面上向きに設定した場合はマイナスサインは不要です。

  

Comments are welcome.  Send E-Mail to:

RETURN TO TOP PAGE

This page is link free, but please link to http://www.ysflight.com.  Please use one of following banners.