2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FreeTypeをOpenGLで使うときに困ったこと

Posted at

GLEW、GLM、FreeTypeなどを使って、画面上に日本語を表示させる処理を作っているときに、自分が詰まったことを、記録しておきます。
なお、僕は主に以下のサイトを参考にしながら処理を作成しました。

そもそも英文字が表示されない

"abc"みたいな簡単な英文字が画面に表示されない場合、とりあえず以下のことができているか、チェックしてみてください。

  • glTexImage2D 関数でformatとinternalformatを GL_RED にしたか?
  • vertex Shaderで、gl_Positionに view projectionもtransfrom matrixなどをかけずに、そのまま頂点座標をわたしたとき、描画されるか?
    (描画される場合、view projectionやtransform matrixが間違っている。Uniformを指定する前に、glUseProgram呼び出してる?
    描画されない場合、Vertex Arrayなどのほかのところが間違っている。)

2個目のやつで言っていたのは、以下のようなvetex shaderでとりあえず文字列が描画されるか調べてみよ、ということ。

Vertex.vert
#version 330 core

layout(location = 0) in vec2 inPosition;
layout(location = 1) in vec2 inTexCoord;

out vec2 fragTexCoord;

void main()
{
	vec4 pos = vec4(inPosition, 0.0, 1.0);
	gl_Position = pos;
	fragTexCoord = inTexCoord;
}

日本語が思ったように表示されない(文字化けする)場合

以下のことを試してみてください。

  • true typeのフォントが本当に日本語対応しているか?(SDL TTFで日本語表示できたからと言って、Free Typeでも同じようにやろうと思ったら、日本語が表示できませんでした。なぜかわからない!!)
    僕はArial Unicode MSでうまく表示できました。
    記事執筆現在では、以下のサイトでダウンロードできます。

  • FT_Select_Charmap(mFontFace, ft_encoding_unicode); をコード中に記述してみたか?
  • ソースコードのエンコーディングがutf-8か?
  • FT_Get_Char_Indexに渡す文字はchar16_tか?

日本語文字列を読み込むイメージとしては以下のような感じです。

	struct TexChar {
		GLuint texID;
		glm::ivec2 Size;
		glm::ivec2 Bearing;
		unsigned int Advance;
	};
	std::vector<TexChar> mJapanTexVec;
///////////////////////////////////////////

const char16_t str[] = u"あいうえお"; // 小文字のuを忘れない!!!
for (int i = 0; str[i] != '\0'; i++) {
			if (FT_Load_Glyph(mFontFace, FT_Get_Char_Index(mFontFace, str[i]), FT_LOAD_RENDER)) {
				std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
				exit(-1);
			}
			GLuint tex;
			glGenTextures(1, &tex);
			glActiveTexture(GL_TEXTURE);
			glBindTexture(GL_TEXTURE_2D, tex);
			glPixelStorei(GL_UNPACK_ALIGNMENT, 1);


			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            // ↓↓↓ GL_REDにする ↓↓↓
			glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, mFontFace->glyph->bitmap.width, mFontFace->glyph->bitmap.rows,
				0, GL_RED, GL_UNSIGNED_BYTE, mFontFace->glyph->bitmap.buffer); 
			mFontWidth = mFontFace->glyph->bitmap.width;
			mFontHeight = mFontFace->glyph->bitmap.rows;

			TexChar	 tc = {
				tex,
				glm::ivec2(mFontFace->glyph->bitmap.width, mFontFace->glyph->bitmap.rows),
				glm::ivec2(mFontFace->glyph->bitmap_left, mFontFace->glyph->bitmap_top),
				mFontFace->glyph->advance.x
			};

			glGenerateMipmap(GL_TEXTURE_2D);
			glBindTexture(tex, 0);		// unbind

			mJapanTexVec.push_back(tc);
		}

文字列を描画する処理は、https://learnopengl.com/In-Practice/Text-Rendering のとおりに作成しました。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?