OpenGLでウィンドウハンドルの取得

このQ&Aのポイント
  • glut関数で作成したウィンドウのハンドルを取得し、文字を表示する方法について説明します。
  • TextOutやDrawTextを使用して文字を表示しようとしたところ、背景色しか表示されない問題が発生しています。
  • おそらくDrawTextの戻り値が18であることから、成功していると考えられますが、なぜ文字が表示されないのかお教えください。
回答を見る
  • ベストアンサー

OpenGLでウィンドウハンドルの取得

コンソールアプリで作ることが前提です。 glut関数で作成したウィンドウのハンドルを取得し、その画面上に文字を表示しようとTextOutやDrawTextやらを使ってみたんですが、背景色しか表示されません。DrawTextの戻り値が18だったので成功していると思うのですが。どこがおかしいのかご指摘をお願いします。 #include<stdio.h> #include<windows.h> #include<GL/glut.h> HWND hwnd; void display(){ glClearColor(0.5,0.5,0.5,1); glClear(GL_COLOR_BUFFER_BIT); hwnd=GetActiveWindow(); PAINTSTRUCT ps; HDC hdc; RECT rect; LPCSTR str = TEXT("あああ"); GetClientRect(hwnd, &rect); hdc = BeginPaint(hwnd, &ps); SetRect( &rect, 10, 10, 100, 100); TextOut(hdc, 10, 10, str, lstrlen(str));    DrawText(hdc, TEXT("あああ"), -1, &rect,DT_CENTER); EndPaint(hwnd, &ps); glFlush(); } int main(int argc,char **argv){ glutInit(&argc,argv); glutInitWindowSize(640,480); glutCreateWindow("aaa"); glutDisplayFunc(display); glutMainLoop(); return(0); }

  • sanato
  • お礼率72% (170/236)

質問者が選んだベストアンサー

  • ベストアンサー
  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.1

DirectXやOpenGLが扱ってるサーフェイスとWindows GDIが管理しているサーフェイスはまったく別のものだと 思ってください。 通常はウインドウの上にOpenGLのサーフェイスが作られているだけで、ウインドウ上に何を描画しようとも 上書きされてしまいます。 どうしてもDrawTextの結果をOpenGLで使いたいなら、 CreateBitmapやCreateDC等のAPIを使い、メモリー上のデバイスコンテキストを作成し そこにDrawTextを実行。 それをBitmapに変換する等してから、テクスチャとして流し込む等することは可能だと思います。 ちなみにDirectX9にはIDirect3DSurface9::GetDCというものが用意されているようですが アルファが設定されていると上手く動作しないようです。 OpenGLでそれに該当するものがあるかどうかは分かりません。 ただ単に文字列描画をしたいだけなら「OpenGL 文字列描画」で検索した方が早いと思います。 BeginPaint、EndPaint はコンソールアプリケーションでは使えません。 MSDNからの引用ですが「アプリケーションがこの関数(BeginPaint)を呼び出せるのは、WM_PAINT メッセージに応答するときだけです。」 となっています。

sanato
質問者

お礼

詳しい説明ありがとうございました。 つまりglFlash()で上書きされるということでしょうか。 いろいろ試行錯誤した結果、TextOut関数をglFlush()の後に記述するとなぜか文字列を表示することができました。しかしもっと複雑なプログラムで試したらダメでした。 やはり別の方法を考えようと思います。

関連するQ&A

  • openGLについて

    最近プログラムを学んでいる初心者の者です。 私は床井研究室の”GLUTによる「手抜き」OpenGL入門”というサイトを使い学んでいるのですが、最初の段階でつまずいてしまいました。 最初のウィンドウを開く段階で #include <GL/glut.h> void display(void) { } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; } とすると書いてあるのですが、 最初の#includeのところがペーストしてもエラーが出ます。 あと他のサイトを見ると#includeが複数書かれているようです。 何か解決する方法はありますでしょうか。 ちなみに 私が使っているのはwindows7です。 どうかお願いします。

  • BCCDeveloperでのOpenGLのコンパイルについて

    環境は BorlandC++Compiler Version 5.5 Developer Version1.2.21 GLUT Version 3.7 OS WindowsXP PC NEC LL730/7 です。 GLUTをインストールし、次のプログラムをコンパイルしたのですが、コンパイルエラーは出なかったのですが、実行時に 「プロシージャ エントリ ポイント _glutCreateWindow@4がダイナミック リンク ライブラリ GLUT32.DLL から見つかりませんでした。」 と言うエラーメッセージが出ました。 原因がわかる方がいれば教えてください。 #include <GL/glut.h> void display(void) { } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutMainLoop(); return 0; }

  • OpenGLで登録したコールバック関数の引数

    OpenGLで画面を描画をする際に, 以下のソースのように,glutDisplayFuncに関数を登録しています. main関数で,定義した定数や,そのポインタを display_funcに渡したいと思うのですが, どのような方法があるのでしょうか? 現在,私は,グローバル変数を定義して,それをmain関数とdisplay関数で いじっています. ソースコードの整理,関数化のため,できれば,ポインタや引数を渡したいです. どうぞよろしくお願いします. --------------------------------------------- #include <GL/glut.h> void display_func(void) { 描画内容を記述 } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutCreateWindow(argv[0]); glutDisplayFunc(display_func); glutMainLoop(); return 0; } ---------------------------------------------

  • OpenGLについて質問があります。

    底から見上げているように立方体がみえるように実行したいんですけどここからどうしていいかわからなくてわかる方いたら教えてください。お願いします。 #include <GL/glut.h> GLdouble vertex[][3] = { { 0.0, 0.0, 0.0 }, /* A */ { 1.0, 0.0, 0.0 }, /* B */ { 1.0, 1.0, 0.0 }, /* C */ { 0.0, 1.0, 0.0 }, /* D */ { 0.0, 0.0, 1.0 }, /* E */ { 1.0, 0.0, 1.0 }, /* F */ { 1.0, 1.0, 1.0 }, /* G */ { 0.0, 1.0, 1.0 } /* H */ }; int edge[][2] = { { 0, 1 }, /* ア (A-B) */ { 1, 2 }, /* イ (B-C) */ { 2, 3 }, /* ウ (C-D) */ { 3, 0 }, /* エ (D-A) */ { 4, 5 }, /* オ (E-F) */ { 5, 6 }, /* カ (F-G) */ { 6, 7 }, /* キ (G-H) */ { 7, 4 }, /* ク (H-E) */ { 0, 4 }, /* ケ (A-E) */ { 1, 5 }, /* コ (B-F) */ { 2, 6 }, /* サ (C-G) */ { 3, 7 } /* シ (D-H) */ }; void display(void) { int i; glClear(GL_COLOR_BUFFER_BIT); /* 図形の描画 */ glColor3d(0.0, 0.0, 0.0); glBegin(GL_LINES); for (i = 0; i < 12; ++i) { glVertex3dv(vertex[edge[i][0]]); glVertex3dv(vertex[edge[i][1]]); } glEnd(); glFlush(); } void resize(int w, int h) { glViewport(0, 0, w, h); glLoadIdentity(); // glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0, 2.0); gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0); //glTranslated(0.0, 0.0, -5.0); gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } void init(void) { glClearColor(1.0, 1.0, 1.0, 1.0); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutDisplayFunc(display); glutReshapeFunc(resize); init(); glutMainLoop(); return 0; }

  • Windows8+OpenGLで未処理の例外エラー

    Windows8 Pro のマシンで OpenGL を使うため、glut をインストールし、 簡単なサンプルをコンパイルして実行したところ、 「ユーザーコールバック中に未処理の例外エラーが発生しました」 というエラーを吐いて止まってしまいました。 統合環境は Visual C++2010 Express を利用しています。 サンプルプログラムは、以下の通りです。 #include <GL/glut.h> void display(void) { glClearColor(1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glFlush(); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutInitWindowSize(640,480); glutCreateWindow(”window”); glutDisplayFunc(display); glutMainLoop(); return 0; } glut は様々なサイトで紹介されている方法通りに、 公式ページにて必要なファイル (32bit版) をダウンロードし、 glut.h を C:\Program Files (x86)\Microsoft Visual Stdio 10.0\VC\include\GL\ に、 glut32.lib を C:\Progma Files (x86)\Microsoft Visual Stdio 10.0\VC\lib\ に glut32.dll を C:\Windows\SysWOW64\ にコピーしました。 glut の代わりに freeglut も試してみたのですが、同様のエラーで止まってしまいました。 使用しているマシンは Surface Pro で ディスプレイアダプターは、 Intel(R) HD Graphics 4000 です。 ネットでいろいろ調べて Windows8 にインストールしている事例もちらほら見かけたので、 Windows8 でも動くとは思うんですが、どうにもうまくいきません。 dll が Windows8 に対応していないのか、Surface だから駄目なのか、検討がつきません。 原因をご存知の方がいましたら、どうか詳しく教えていただけないでしょうか? よろしくお願いします。

  • TextOut( ) を BeginPaint( ) と GetDC( )

    LRESULT CALLBACK の case WM_PAINT: で、 hdc = BeginPaint(hWnd, &ps); TextOut(hdc,0,0,str,strlen(str)); EndPaint(hWnd, &ps); ↑問題無し。↓文字がちらつく。 hdc = GetDC(hWnd); TextOut(hdc,0,0,str,strlen(str)); ReleaseDC(hWnd,hdc); ちらつきの原因は、高速で TextOut( ) が繰り返されるから だと思いました。 どうして TextOut( ) が繰り返されるんですか? 上の方法の場合は、 ReleaseDC(hWnd,hdc); は書かなくてもいいですか?

  • OpenGLの惑星プログラム

    /* p4-MovingPlanet.c * Animation for a solar system ( see p3-planet.c ) using by glutTimerFunc(). */ #include <stdlib.h> #include <GL/glut.h> #include <math.h> int year = 0, day = 0; int samplingTime = 50; void myKeyboard(unsigned char key, int x, int y) { if ( key == 27) exit (0); } void myDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3d(1.0, 1.0, 1.0); glPushMatrix(); glutWireSphere(1.0, 20, 16); // sun glRotated((double)year, 0.0, 1.0, 0.0); glTranslated(3.0, 0.0, 0.0); glRotated((double)day, 0.0, 1.0, 0.0); glutWireSphere(0.2, 10, 8); // planet glPopMatrix(); glutSwapBuffers(); } void myInit(char *progname) { int width = 500, height = 500; glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(width, height); glutInitWindowPosition(0, 0); glutCreateWindow(progname); glClearColor(0.0, 0.0, 0.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(90.0, (double)width / (double)height, 0.1, 20.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } void myTimer(int value) { if (value==1) { glutTimerFunc(samplingTime,myTimer,1); year = (year+1) % 360; day = (day+5) % 360; glutPostRedisplay(); } } int main(int argc, char** argv) { glutInit(&argc, argv); myInit(argv[0]); glutKeyboardFunc(myKeyboard); glutTimerFunc(samplingTime, myTimer, 1); glutDisplayFunc(myDisplay); glutMainLoop(); return 0; } このプログラムを改良して太陽系(水星~天王星)のプログラムを作成したいです。何を加えればいいんですか?教えてください><よろしくお願いします!!!

  • TextOut( ) が動かない

    LRESULT CALLBACK WndProc( HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ PAINTSTRUCT ps; HDC hdc; switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  break; エスケープキーで文字表示をやりたいけど TextOut( ) が動作していないみたいでした。 switch(msg){ case WM_KEYDOWN:  if( wParam == VK_ESCAPE ){   hdc = BeginPaint(hWnd, &ps);   TextOut(hdc,0,0,str,strlen(str));   EndPaint(hWnd, &ps);  }  break; case WM_PAINT:  hdc = BeginPaint(hWnd, &ps);  TextOut(hdc,0,0,str,strlen(str));  EndPaint(hWnd, &ps);  break; とすると、常に文字が表示されたから、やっぱり case WM_KEYDOWN: の中の TextOut( ) が 動作していないんだと思いました。 TextOut( ) は case WM_PAINT: からのつながりが ある場合でないと実行されないんですか? ソースのおかしいところがあったら教えてください。

  • プログラミングのopenglで困っています.

    OpenGlの超初心者です. openglで,円を一つ作ってあるsampleプログラムを拾ってきたのですが, 円をもう一つ,別の座標で作りたいのですが,以下のプログラムをどのように編集すればいいですか? 誰か助けてください. ========================================== #include <GLUT/glut.h> #include "glut.h" #include <math.h> //--初期化処理------------------------------------------------------------------ void myinit(void){ glClearColor(1.0f, 1.0f, 1.0f, 1.0f);//背景色の設定(R,G,B,ALPHA) 0.0-1.0の範囲で } //--描画内容-------------------------------------------------------------------- void display(void){ float x1,y1,x2,y2; float th1,th2; float th1_rad, th2_rad; float hankei = 0.1; glClear(GL_COLOR_BUFFER_BIT);//画面全体を背景色で塗りつぶす glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //単位行列を行列スタックに読み込む glColor3f(0.0f, 0.0f, 0.0f);//頂点カラーの指定( R, G, B すべてが1.0fなら白) for (th1 = 0.0; th1 <= 360.0; th1 = th1 + 10.0){ th2 = th1 + 10.0; th1_rad = th1 / 180.0 * 3.1415926; // 「度」を「ラジアン」に直す th2_rad = th2 / 180.0 * 3.1415926; x1 = hankei * cos(th1_rad); y1 = hankei * sin(th1_rad); x2 = hankei * cos(th2_rad); y2 = hankei * sin(th2_rad); glBegin(GL_LINES);//glBegin(GL_LINES)とglEnd()の間に glVertex2f( x1, y1 ); //描画したい直線の頂点を並べる glVertex2f( x2, y2 ); glEnd(); //ここまでで,ひとつのオブジェクトの宣言がおわる } glFlush();//OpenGLで実際に描画を行う } //--再描画---------------------------------------------------------------------- void myReshape(GLsizei w, GLsizei h){ glViewport(0,0,w,h); //ウィンドウ全体をビューポートにする glMatrixMode(GL_PROJECTION); glLoadIdentity();//単位行列を行列スタックに読み込む glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f); } //--メイン関数------------------------------------------------------------------ int main(int argc, char **argv){ glutInitWindowPosition(100, 100); //(図形が描画される)ウィンドウ位置の設定 glutInitWindowSize(600, 600); //(図形が描画される)ウィンドウサイズの設定 glutInit(&argc, argv);//環境の初期化 glutInitDisplayMode(GLUT_RGBA|GLUT_SINGLE); //表示モードの設定 glutCreateWindow("kadai"); //ウィンドウを開く glutDisplayFunc(display); //図形表示関数の指定 myinit(); glutReshapeFunc(myReshape); //座標軸・ビューポート設定関数の指定 glutMainLoop();//無限ループ return 0; } ==========================================

  • SDKでウィンドウの中央に文字列を表示させる方法

    ウィンドウの中央に文字列sを表示させる方法を教えて下さい。 /********************************** WM_PAINTで TCHAR s[80]; HDC hDC; PAINTSTRUCT ps; RECT rc; GetClientRect(hWnd, &rc); hDC = BeginPaint(hWnd, &ps); TextOut(hDC, rc.right / 2, rc.bottom / 2, tcDayTime, lstrlen(s)); EndPaint(hWnd, &ps); return FALSE; ***********************************/ GetClientRect(hWnd, &rc);でウィンドウのサイズを取得し、 TextOutの第2、第3引数で ウィンドウ幅/2、ウィンドウ高さ/2 としていますが、これだと中央から表示されてしまいます。 できれば、ウィンドウのサイズを変更してもウィンドウの中央に表示させたいです。 #VC ++ 6.0 & Win98 & SDK で作成してます。

専門家に質問してみよう