OpenGLで日本語描画

opengl-japanesedraw.png

日本語を書く

  • FTGLを使う方法…FTGL+FreeTypeでは商用でも使用されている例がある
  • SDL-ttfを使う方法…非力な環境だと遅いらしいよ。
  • GLFW…新しく生まれ変わったGLFW3ではUTF-8をサポートしている。ってことは、日本語が書けるってことだ!!

GDIを使う

通常の GDI 関数を使って OpenGL が描画した領域の上から文字を描画するという方法だ。 (Windows における) ウィンドウ座標と (OpenGL における) 正規化座標の間で適切な変換を施すという若干の手間はあるが、 Win32 API に慣れていれば実に簡単に日本語が表示できる。
http://gltest.blog.shinobi.jp/Entry/11/
遅いらしい。

wglUseFontBitmapsW 

ソースコード

#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#include <GL/freeglut.h>
#include <stdio.h>
 
#define WIDTH 320
#define HEIGHT 240
 
class GLFONT
{
public:
 HFONT Hfont;
 HDC Hdc;
 GLFONT(wchar_t *fontname, int size);
 void DrawStringW(int x,int y,wchar_t *format, ...);
};
//コンストラクタ フォント作成
GLFONT::GLFONT(wchar_t *fontname, int size)
{
 Hfont = CreateFontW(
        size,      //フォント高さ
        0,       //文字幅
        0,       //テキストの角度
        0,       //ベースラインとx軸との角度
        FW_REGULAR,     //フォントの太さ
        FALSE,      //イタリック体
        FALSE,      //アンダーライン
        FALSE,      //打ち消し線
        SHIFTJIS_CHARSET,   //文字セット
        OUT_DEFAULT_PRECIS,   //出力精度
        CLIP_DEFAULT_PRECIS,  //クリッピング精度
        ANTIALIASED_QUALITY,  //出力品質
        FIXED_PITCH | FF_MODERN, //ピッチとファミリー
        fontname);     //書体名
 
 Hdc = wglGetCurrentDC();
 SelectObject(Hdc, Hfont);
}
//ワイド文字列の描画
void GLFONT::DrawStringW(int x,int y,wchar_t *format, ...)
{
 wchar_t buf[256];
 va_list ap;
 int Length=0;
 int list=0;
 
 //ポインタがNULLの場合は終了
 if ( format == NULL )
  return;
 
 //文字列変換
 va_start(ap, format);
 vswprintf_s(buf, format, ap);
 va_end(ap);
 
 Length = wcslen(buf);
 list = glGenLists(Length);
 for( int i=0; i<Length; i++ ){
  wglUseFontBitmapsW(Hdc, buf[i], 1, list + (DWORD)i);
 }
 
 glDisable(GL_LIGHTING);
 glRasterPos2i(x, y);
 //ディスプレイリストで描画
 for( int i=0; i<Length; i++ )
 {
  glCallList(list + i);
 }
 glEnable(GL_LIGHTING);
 //ディスプレイリスト破棄
 glDeleteLists(list, Length);
 list = 0;
 Length = 0;
}
 
GLFONT *font;
 
void display(void)
{
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
 font->DrawStringW(10,120,L"こんにちわ OpenGLの世界!!");
 glutSwapBuffers();
}
void idle(void)
{
 glutPostRedisplay();
}
void Init(){
 glClearColor(1.0, 1.0, 1.0, 1.0);
 glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);
 font = new GLFONT(L"MS明朝", 24);
}
int main(int argc, char *argv[])
{
 glutInitWindowPosition(100, 100);
 glutInitWindowSize(WIDTH, HEIGHT);
 glutInit(&argc, argv);
 glutCreateWindow("文字列を描画");
 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
 glutDisplayFunc(display);
 glutIdleFunc(idle);
 Init();
 glutMainLoop();
 return 0;
}

freetype ftgl

サポートサイト Wikidot.com freetypeftgl