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

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

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenGL

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

C++

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

Q&A

解決済

2回答

1890閲覧

ワイド文字が描画されません

hikarhikar

総合スコア18

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

OpenGL

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

C++

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

0グッド

0クリップ

投稿2020/05/12 03:38

編集2020/05/12 03:39

RPGゲームを作ろうと思い、現在ステータスウィンドウを作っているのですが
scanf_s()で取得した文字列が描画できません。

描画処理は[bool]で二つに分けています。
・名前入力画面(bool falseの場合)
・ステータス画面(bool trueの場合)


scanf_s()でchar型の文字列を取得

ワイド文字変換(ワイド配列buffer)

buffer渡す //(wchar_t buffer[NAME_MAX];)

set_Name(wchar_t* _format)
this->Name=_format; //(status::Name)

draw_status()


this->Name描画(描画されません)


main関数のscanf_sで得た文字列をワイド文字に変換して、
set_Name(wchar_t*_format)に渡す。
この[set_Name()]関数で描画した場合は正常に描画されました。

c

1void Human::set_Name(wchar_t* _format) { 2 this->Name = _format; 3 font_SetSize(20); 4 font_SetWidth(20); 5 font_GetColor(0x00, 0x00, 0x00); 6 int i = 0; 7 for (; (*this->Name != '\0') && (*this->Name != '\n'); this->Name++) { 8 font_SetPosition(90 + i * font_GetSize(), 40); 9 font_Draw(L"%c", *this->Name); 10 i++; 11 } 12}

名前を入力


上の描画処理を[draw_status()]関数で行うと(描画する場所が少しちらつき)描画がされません。
[draw_status()]関数では他に数字など色々描画してるのですが、set_Name()で取得した文字列だけ描画できなくなってしまいます。(描画場所に少しちらつきはあるのですが...)
ステータス描画


こちらのサイトで前回質問した時には[font]関数で間違えているところを指摘され、
指摘された箇所を全て治し正常に描画できたので、[font]関数が原因ではないと思うのですが...
色々試してみたのですががお手上げでした。

申し訳ありませんが、どこがいけないかご指摘いただければ幸いです。<(_ _)>

[main.cpp]

c

1nclude <stdio.h> 2#include <stdlib.h> 3#include <locale.h> 4 5#include "glm/glm.hpp" 6#include "glut.h" 7 8#include "rect.h" 9#include "font.h" 10#include "cube.h" 11#include "BONE.h" 12#include "obj.h" 13#include "status.h" 14#include "line.h" 15 16using namespace glm; 17vec2 windowSize = { 600,400 }; 18Rect rect0 = Rect(0, 0, 600, 400); 19Rect rect1 = Rect(0, 0, 600, 400); 20Rect rect2 = Rect(322, 112, 255, 200); 21Human human1; 22 23bool login = false; 24bool name = false; 25wchar_t buf[NAME_MAX]; 26void display(void) { 27 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 28 29 glMatrixMode(GL_PROJECTION); 30 glLoadIdentity(); 31 gluOrtho2D(0, windowSize.x, windowSize.y, TEXTURE_0); 32 33 glMatrixMode(GL_MODELVIEW); 34 glLoadIdentity(); 35 36 if (login != true) { 37 rect0.rect_Draw(0xff,0xff,0xff); 38 39 font_Begin(); 40 font_SetPosition(20, 0); 41 font_SetSize(20); 42 font_SetWidth(0); 43 font_GetColor(0x00, 0x00, 0x00); 44 font_Draw(L"名前を入力してください\n"); 45 font_End(); 46 47 line_SetPosition(20,60,230); 48 line_Draw(1.0); 49 if (name != false) { 50 size_t wLen = 0; 51 errno_t err = 0; 52 char numbur[NAME_MAX] = { 0 }; 53 wchar_t buffer[NAME_MAX]; 54 scanf_s("%s", numbur, NAME_MAX); 55 56 //文字列型変換 57 setlocale(LC_ALL, "japanese"); 58 err = mbstowcs_s(&wLen, buffer, NAME_MAX, numbur, _TRUNCATE); 59 60 font_Begin(); 61 font_SetPosition(20, 30); 62 font_SetSize(20); 63 font_SetWidth(0); 64 font_GetColor(0x00, 0x00, 0x00); 65 font_Draw(L"%s\n", buffer); 66 font_End(); 67 68 human1.set_Name(buffer); 69 70 login = true; 71 name = false; 72 } 73 glutSwapBuffers(); 74 return; 75 } 76 77 human1.worldClock(); 78 rect1.rect_Draw(TEXTURE_0); 79 human1.draw_status(); 80 81 rect2.rect_Draw(TEXTURE_1); 82 83 glutSwapBuffers(); 84 85} 86 87void idle(void) { 88 glutPostRedisplay(); 89} 90 91void reshape(int width, int height) { 92 printf("reshape: width:%d height:%d\n", width, height); 93 glViewport(0,0,width,height); 94 windowSize = vec2(width, height); 95} 96 97void mouse(int button, int state, int x, int y) { 98 if ((button == GLUT_LEFT_BUTTON) && (x > 0) && (x < 245) 99 && (y < 60) && (y > 30)) { 100 name = true; 101 } 102 printf("x:%d y:%d\n",x,y); 103} 104 105int main(int argc, char* argv[]) { 106 glutInit( 107 &argc, 108 argv); 109 glutInitDisplayMode(GL_DOUBLE); 110 glutInitWindowPosition(100,100); 111 glutInitWindowSize(windowSize.x,windowSize.y); 112 glutCreateWindow("Window"); 113 114 bmp_Load("ステータスウィンドウ.bmp", TEXTURE_0); 115 //bmp_Load("キャラクター0.bmp", TEXTURE_1); 116 117 glutDisplayFunc(display); 118 glutIdleFunc(idle); 119 glutReshapeFunc(reshape); 120 glutMouseFunc(mouse); 121 122 glutMainLoop(); 123 124 return 0; 125}

[status.h]

c

1 2#define BUF_MAX 64 3#define NAME_MAX 64 4 5class status { 6public: 7 int level = 0; 8 int nextLevel = 0; 9 int hp = 0; 10 int mp = 0; 11 int power = 0; 12 int defense = 0; 13 int speed = 0; 14 int jobCount = 0; 15 int gender = 0; 16 int intelligence = 0; 17 18 wchar_t* Name; 19}; 20 21class Human :public status { 22private: 23 int hour[2] = { 0 }; 24 int minute[2] = { 0 }; 25 int second[2] = { 0 }; 26public: 27 Human(); 28 void set_Name(wchar_t* format); 29 void set_Job(); 30 31 void worldClock(); 32 void draw_status(); 33};

[status.cpp]

c

1#include <stdio.h> 2 3#include "status.h" 4#include "font.h" 5 6Human::Human() { 7 for (int i = 0; i < 2; i++) { 8 this->second[i] = 0; 9 this->minute[i] = 0; 10 this->hour[i] = 0; 11 } 12 13 this->nextLevel = 60; 14 this->level = 1; 15 this->hp = 10; 16 this->mp = 10; 17 this->power = 3; 18 this->defense = 3; 19 this->speed = 2; 20 this->jobCount = 5; 21 this->intelligence = 25; 22} 23 24void Human::set_Name(wchar_t* _format) { 25 this->Name = _format; 26 /*font_SetSize(20); 27 font_SetWidth(FONT_DEFAULT_HEIGHT); 28 font_GetColor(0x00, 0x00, 0x00); 29 int i = 0; 30 for (; (*this->Name != '\0') && (*this->Name != '\n'); this->Name++) { 31 font_SetPosition(90 + i * font_GetSize()*1.5, 40); 32 font_Draw(L"%c", *this->Name); 33 i++; 34 }*/ 35} 36 37void Human::worldClock() { 38 static int time = 0; 39 if (time == 60) { 40 this->second[1]++; 41 time = 0; 42 if (this->second[1] == 10) { 43 this->second[1] = 0; 44 this->second[0]++; 45 if (this->second[0] == 6) { 46 this->second[0] = 0; 47 this->minute[1]++; 48 if (this->minute[1] == 10) { 49 this->minute[1] = 0; 50 this->minute[0]++; 51 if (this->minute[0] == 6) { 52 this->minute[0] = 0; 53 this->hour[1]++; 54 if (this->hour[1] == 10) { 55 this->hour[1] = 0; 56 this->hour[0]++; 57 } 58 } 59 } 60 } 61 } 62 } 63 64 time++; 65} 66 67void Human::draw_status() { 68 font_Begin(); 69 70 font_SetPosition(100, 122); 71 font_SetSize(35); 72 font_SetWidth(25); 73 font_GetColor(0x00, 0x00, 0x00); 74 font_Draw(L"%d%d:%d%d:%d%d", 75 this->hour[0], this->hour[1], 76 this->minute[0], this->minute[1], 77 this->second[0], this->second[1]); 78 79 font_SetSize(20); 80 font_SetWidth(20); 81 font_GetColor(0x00, 0x00, 0x00); 82 int i = 0; 83 for (; (*this->Name != '\0') && (*this->Name != '\n'); this->Name++) { 84 font_SetPosition(90 + i * font_GetSize(), 40); 85 font_Draw(L"%c", *this->Name); 86 i++; 87 } 88 89 font_SetPosition(432, 20); 90 font_SetSize(35); 91 font_SetWidth(25); 92 font_GetColor(0x00, 0x00, 0x00); 93 font_Draw(L"%d\n", this->level); 94 95 font_SetPosition(432, 55); 96 font_SetSize(15); 97 font_SetWidth(20); 98 font_GetColor(0x00, 0x00, 0x00); 99 font_Draw(L"%d\n", this->nextLevel); 100 101 font_SetPosition(100, 320); 102 font_SetSize(15); 103 font_SetWidth(20); 104 font_GetColor(0x00, 0x00, 0x00); 105 font_Draw(L"%d\n", this->power); 106 107 font_SetPosition(100, 355); 108 font_SetSize(15); 109 font_SetWidth(20); 110 font_GetColor(0x00, 0x00, 0x00); 111 font_Draw(L"%d\n", this->speed); 112 113 font_SetPosition(300, 320); 114 font_SetSize(15); 115 font_SetWidth(20); 116 font_GetColor(0x00, 0x00, 0x00); 117 font_Draw(L"%d\n", this->defense); 118 119 font_SetPosition(300, 355); 120 font_SetSize(15); 121 font_SetWidth(20); 122 font_GetColor(0x00, 0x00, 0x00); 123 font_Draw(L"%d\n", this->intelligence); 124 125 font_SetPosition(460, 320); 126 font_SetSize(15); 127 font_SetWidth(20); 128 font_GetColor(0x00, 0x00, 0x00); 129 font_Draw(L"%d\n", this->mp); 130 131 font_SetPosition(460, 355); 132 font_SetSize(15); 133 font_SetWidth(20); 134 font_GetColor(0x00, 0x00, 0x00); 135 font_Draw(L"%d\n", this->hp); 136 137 font_End(); 138}

[font.cpp]

c

1#include <Windows.h> 2 3#include "glm/glm.hpp" 4#include "glut.h" 5 6#include "font.h" 7 8int x, y = 0; 9int width = 0; 10int size = FONT_DEFAULT_HEIGHT; 11float color[3] = { 0xff,0xff,0xff }; 12 13void font_Begin() { 14 glPushMatrix(); 15 glPushAttrib(GL_ALL_ATTRIB_BITS); 16 17 glMatrixMode(GL_PROJECTION); 18 glLoadIdentity(); 19 20 GLint viewport[4]; 21 glGetIntegerv(GL_VIEWPORT, viewport); 22 gluOrtho2D(0,viewport[2], viewport[3],0); 23 24 glMatrixMode(GL_MODELVIEW); 25 glLoadIdentity(); 26 27 glDisable(GL_DEPTH_TEST); 28 glDisable(GL_LIGHTING); 29 glDisable(GL_TEXTURE_2D); 30} 31 32void font_End() { 33 glPopAttrib(); 34 glPopMatrix(); 35} 36 37void font_SetPosition(int _x, int _y) { 38 x = _x + 5; 39 y = _y + 20; 40} 41 42void font_SetSize(int _size) { 43 size = _size; 44} 45 46void font_SetWidth(int _width) { 47 width = _width; 48} 49 50int font_GetSize() { 51 return size; 52} 53 54void font_GetColor(float _red, float _green, float _blue) { 55 color[0] = _red; 56 color[1] = _green; 57 color[2] = _blue; 58} 59 60void font_Draw(const wchar_t* format, ...) { 61 va_list argList; 62 63 if (format == nullptr)return; 64 65 wchar_t buf[256]; 66 va_start(argList, format); 67 vswprintf_s(buf, format, argList); 68 va_end(argList); 69 70 int length = wcslen(buf); 71 int list = glGenLists(length); 72 73 wchar_t fontType[] = { L"MS 明朝" }; 74 HFONT Ofont = CreateFontW( 75 size, 76 width, 77 0, 78 0, 79 FW_REGULAR, 80 FALSE, 81 FALSE, 82 FALSE, 83 SHIFTJIS_CHARSET, 84 OUT_DEFAULT_PRECIS, 85 CLIP_DEFAULT_PRECIS, 86 DEFAULT_QUALITY, 87 FIXED_PITCH | FF_MODERN, 88 fontType); 89 90 HDC Odc = wglGetCurrentDC(); 91 SelectObject(Odc, Ofont); 92 93 wchar_t* font = buf; 94 int i = 0; 95 for (; (*font != '\0') && (*font != '\n'); font++) { 96 wglUseFontBitmapsW( 97 Odc, 98 *font, 99 1, 100 list + i 101 ); 102 i++; 103 } 104 glColor3f(color[0], color[1], color[2]); 105 glPushMatrix(); 106 { 107 glRasterPos2i(x, y); 108 for (int i = 0; i < length; i++) { 109 glCallList(list + i); 110 } 111 } 112 glPopMatrix(); 113 114 SelectObject(Odc, GetStockObject(SYSTEM_FONT)); 115 DeleteObject(Ofont); 116 if (*font == '\n' && *(font + 1) != '\0') { 117 glDeleteLists(list, length); 118 119 font_SetPosition(0, y + font_GetSize()-15); 120 font_Draw(L"%s",++font); 121 } 122}

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

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

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

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

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

guest

回答2

0

ベストアンサー

set_Nameでbufferのポインタを記憶させていますが、bufferはローカル宣言した変数のため、変数の有効なスコープを抜けた時点で無効になり、無効になった領域のポインタを保持することになります。
文字列は std::wstring 等で保持した方がよいでしょう。

投稿2020/05/12 07:37

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

episteme

2020/05/12 07:45

あ、ホントだ... ココがいちばん怪しいスね。
hikarhikar

2020/05/12 07:52

radianさんご返答ありがとうございます。<(_ _)> なるほどです! display()→sit_Name()→抜ける→draw_status()ということですね! radianさんがおっしゃったことを参考に処理を直していきたいとおもいます。
guest

0

font_Drawの中からfont_Draw呼んでますけど、これで正しいんですよね?

投稿2020/05/12 04:05

episteme

総合スコア16612

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

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

hikarhikar

2020/05/12 04:18

epistemeさんご返答ありがとうございます。<(_ _)> [font.cpp]のfont_Drawからfont_Drawをよんでるということでしょうか? 文字列に改行コードが入っていた場合にfont_Drawを再帰的に呼んでいるので大丈夫だと思います。 前質問した際に下のように、直すようご指摘していただきました。 if (*font == '\n' && *(font + 1) != '\0') { glDeleteLists(list, length); font_SetPosition(0, y + font_GetSize()-15); font_Draw(L"%s", ++font); }
episteme

2020/05/12 04:47

ホント? CreateFontやらなんやらを何度も何度も呼ぶことになりますよ? それがチラつきの原因だったりしませんかね?
hikarhikar

2020/05/12 06:57

上の処理(先に返答した)をglDeleteLists(list,length)だけに変えてみたのですが、結果は変わりませんでした。(◞‸◟) epistemeさんがおっしゃった「createFontを何度も何度も呼ぶことになる」は、DeleteObject()関数で開放しているのですが、他に何かした方がいいのでしょうか?
episteme

2020/05/12 07:01

いや、一文字ごとにCreateFont/DeleteObjectせにゃいかんのですか?
hikarhikar

2020/05/12 07:15

int length = wcslen(buf); int list = glGenLists(length); 文字の長さを取得し、文字の長さだけディスプレイを作成。 CreateFont()でフォント作成 文字列を描画(文字の長さぶん) フォントを元に戻す。 deleteObject()でフォントを解放 glDeleteLists()で文字の長さぶん、ディスプレイを解放 という感じなのですが... 新たにfont_Load()関数みたいのを作成し、その中でCreateFontWでフォントを作成、保持し、 フォントを使用する時になったら、保持しているフォントを使用し、フォントをデフォルトに戻す。 実質CreateFontWは一度main関数で呼ばれるだけ。 みたいな感じでしょうか?
episteme

2020/05/12 07:35

みたいな感じです。ひとつあれば十分なものをいくつも用意する必要ないんだから。
hikarhikar

2020/05/12 07:53

epistemeさん何から何までありがとうございました。<(_ _)> epistemeさんがおっしゃっとことを参考にコードを直していきたいと思います。 本当にありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問