質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

0回答

356閲覧

openglでtextureatlasをつかったフォント表示

miiichat

総合スコア72

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/04/27 09:53

いつもありがとうございます!!お世話になります!
#####参考サイト
リンク1 / リンク2 / リンク3

#####したいこと
テクスチャアトラスをつくってフォント表示をしたい。
(リンク1のやりかたではフォント表示できました。)

#####わからないこと
・リンク3でglTexImage2D()をもう一度呼べばテクスチャのサイズ変更可能とありますが、
const GLvoid * dataは何を指定すればいいですか?

void glTexImage2D(Lenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * data); glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

・char16_t* の文字数の取得はどうやってしますか?

#####コード

#pragma once #include <ft2build.h> #include FT_FREETYPE_H #include <cstdlib> #include <iostream> #include <GL/glew.h> #include <GLFW/glfw3.h> #include <vector> #include <windows.h> #include <map> #include <string.h> class Font { struct character_info { float ax; // advance.x float ay; // advance.y float bw; // bitmap.width; float bh; // bitmap.rows; float bl; // bitmap_left; float bt; // bitmap_top; float tx; // x offset of glyph in texture coordinates } ; public: FT_Library library; FT_Face face; FT_GlyphSlot g; FT_GlyphSlot slot; GLuint tex; GLuint vao; GLuint vbo; BYTE *font_buff = NULL; //文字の最長の高さ int h = 0; //文字列の長さ int w = 0; std::map<char16_t, character_info> font_data; Font(const GLuint program) { Init(program); } int Init(const GLuint program) { if (FT_Init_FreeType(&library)) { std::cout << "Could not init freetype library\n"; return 1; } LOGFONT lf; ZeroMemory(&lf, sizeof(lf)); CHOOSEFONT cf; ZeroMemory(&cf, sizeof(cf)); cf.lStructSize = sizeof(cf); cf.Flags = 0; cf.lpLogFont = &lf; // とりあえず、適当なフォントを選ぶ。 if (!ChooseFont(&cf)) { return 1; } HFONT font_h = CreateFontIndirect(&lf); if (font_h == NULL) { std::fprintf(stderr, "%s(%d): failed to load font.\n", __FILE__, __LINE__); return 1; } HDC dc_h = GetDC(NULL); HGDIOBJ old_font_h = SelectObject(dc_h, font_h); DWORD cb = GetFontData(dc_h, 0x66637474, 0, NULL, 0); if (cb != 0 && cb != GDI_ERROR) { // これなら、TTC font_buff = new BYTE[cb]; GetFontData(dc_h, 0x66637474, 0, font_buff, cb); } else { // TTFとして読んでみる。 cb = GetFontData(dc_h, 0, 0, NULL, 0); if (cb == 0 || cb == GDI_ERROR) { std::fprintf(stderr, "%s(%d): failed to load font.\n", __FILE__, __LINE__); return 1; } font_buff = new BYTE[cb]; GetFontData(dc_h, 0, 0, font_buff, cb); } if (FT_New_Memory_Face(library, font_buff, cb, 0, &face) != 0) { std::fprintf(stderr, "%s(%d): failed to load font.\n", __FILE__, __LINE__); return 1; } DeleteObject(SelectObject(dc_h, old_font_h)); ReleaseDC(NULL, dc_h); g = face->glyph; FT_Set_Pixel_Sizes(face, 0, 48); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture(GL_TEXTURE0); glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); int uniform_tex = glGetUniformLocation(program, "tex"); glUniform1i(uniform_tex, 0); 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); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenBuffers(1, &vbo); int attribute_coord = glGetAttribLocation(program, "coord"); glEnableVertexAttribArray(attribute_coord); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(attribute_coord, 4, GL_FLOAT, GL_FALSE, 0, 0); } void render_text(const char16_t *text, float x, float y, float sx, float sy) { struct point { GLfloat x; GLfloat y; GLfloat s; GLfloat t; } coords[6 * 5]; //頂点数 int n = 0; for (const char16_t *p = text; *p != '\0'; ++p) { //初めての文字だったら if (font_data.end() == font_data.find(*p)) { if (FT_Load_Glyph(face, FT_Get_Char_Index(face, *p), FT_LOAD_RENDER)) continue; //文字の書き始め font_data[*p].tx = (float)w; w += g->bitmap.width; h = Int_max(h, g->bitmap.rows); font_data[*p].ax = g->advance.x >> 6; font_data[*p].ay = g->advance.y >> 6; font_data[*p].bw = g->bitmap.width; font_data[*p].bh = g->bitmap.rows; font_data[*p].bl = g->bitmap_left; font_data[*p].bt = g->bitmap_top; glBindTexture(GL_TEXTURE_2D, tex); glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, 0 ); glTexSubImage2D( GL_TEXTURE_2D, 0, font_data[*p].tx, 0, g->bitmap.width, g->bitmap.rows, GL_ALPHA, GL_UNSIGNED_BYTE, g->bitmap.buffer ); } //描画座標 float x2 = x + font_data[*p].bl * sx; float y2 = y + font_data[*p].bt * sy; float w = font_data[*p].bw * sx; float h = font_data[*p].bh * sy; x += font_data[*p].ax * sx; y += font_data[*p].ay * sy; if (!w || !h) continue; /* coords[n++] = { x2 , y2 , font_data[*p].tx / w , 0 }; coords[n++] = { x2 + w, y2 , font_data[*p].tx / w + font_data[*p].bw / w, 0 }; coords[n++] = { x2 , y2 - h , font_data[*p].tx / w , font_data[*p].bh / h }; coords[n++] = { x2 + w, y2 , font_data[*p].tx / w + font_data[*p].bw / w, 0 }; coords[n++] = { x2 , y2 - h , font_data[*p].tx / w , font_data[*p].bh / h }; coords[n++] = { x2 + w, y2 - h , font_data[*p].tx / w + font_data[*p].bw / w, font_data[*p].bh / h };*/ coords[n++] = { x2 , y2 , font_data[*p].tx / w , 0 }; coords[n++] = { x2 , y2 - h , font_data[*p].tx / w , font_data[*p].bh / h }; coords[n++] = { x2 + w, y2 , font_data[*p].tx / w + font_data[*p].bw / w, 0 }; coords[n++] = { x2 + w, y2 , font_data[*p].tx / w + font_data[*p].bw / w, 0 }; coords[n++] = { x2 , y2 - h , font_data[*p].tx / w , font_data[*p].bh / h }; coords[n++] = { x2 + w, y2 - h , font_data[*p].tx / w + font_data[*p].bw / w, font_data[*p].bh / h }; } glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof coords, coords, GL_DYNAMIC_DRAW); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, n); } void display(const GLuint program, GLFWwindow *const window) { glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT); GLfloat black[4] = { 0, 0, 0, 1 }; int uniform_color = glGetUniformLocation(program, "color"); glUniform4fv(uniform_color, 1, black); float sx = (2.0 / 640) * 0.5; float sy = (2.0 / 480) * 0.5; render_text(u"フォントの", -1 + 8 * sx, 1 - 50 * sy, sx, sy); render_text(u"openg", -1 + 8.5 * sx, 1 - 100.5 * sy, sx, sy); glfwSwapBuffers(window); glfwPollEvents(); } virtual ~Font() { glDeleteBuffers(1, &vao); glDeleteBuffers(1, &vbo); glDeleteBuffers(1, &tex); FT_Done_Face(face); delete[] font_buff; } static int Int_max(int x, int y) { if (x < y) { return y; } else { return x; } } static int Char16_Length(const char16_t *text) { size_t size = sizeof(text) / sizeof(text); size_t length = size; char16_t c = 0; for (int i = 0; i < size; ++i) { c = text[i]; if ((c > 0xD800) && (0xDC00 > c)) { --length; } } return length; } };

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問