OpenGL glut 文字の描画

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Toshita
記事: 23
登録日時: 9年前

OpenGL glut 文字の描画

#1

投稿記事 by Toshita » 9年前

お世話になっております.
現在Linux OpenGL & Glut で簡単なゲームを作っています.
そこでScoreなどを文字で描画したいのですが,どうすればいいのでしょうか?

Glutで英語で表記させようとしてるのですが、なかなかできません.
下記のコードのどの部分で文字を書き込むコードを埋めればいいのでしょうか?

下記のコードを追加して

コード:

void printString(float x, float y, char* str, int length){
	float z = -1.0f;
	glRasterPos3f(x, y, z);
	
	for (int i = 0; i < length; i++){
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]);
	}
}
displayの中に

コード:

printString(0, 0, "HogeHoge", 8);
を書き入れようとしてます.

ただ、どこにいれてもなかなか表示ができず・・・。
お願いします.


書き入れたいコード

コード:

/* Include */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <GL/glut.h>
#include <fenv.h>
#include <iostream>
#include "Leap.h"
#include "unistd.h"

/*
Leap座標
-100 < x < 100 -> -3.5 < x < 3.5
 250 < y < 300 ->    0 < y < 4

x = ((x + 100) / 29) - 3.5
y = ((y - 250) / 12.5)

*/
/* フィールド生成用 */
#define W 10			/* フィールドの幅 */
#define	D 10			/* フィールドの長さ */
#define G (-9.8)		/* 重力加速度 */
#define V 25.0			/* 球の初速度 */
#define QX 0.0			/* 球の初期位置 x座標 */
#define QY 1.5			/* 球の初期位置 y座標 */
#define QZ (10.0)		/* 球の初期位置 z座標 */
#define QM 100          	/* 球の数 */
#define KEY_ESCAPE 27		/*  */
#define DEFAULT_WIDTH 800	/* ウィンドウの幅 */
#define DEFAULT_HEIGHT 600	/* ウィンドウの高さ */
#define TSTEP 0.01		/* フレームごとの時間 */

using namespace Leap;
using namespace std;
int shoot_flag=0;
typedef struct{
	double py;
	double pz;
}qmake;

double shootx,shooty;
int number;//球の番号
int window;
int screen_width = DEFAULT_WIDTH;
int screen_height = DEFAULT_HEIGHT;
int flag = 0;
Controller controller;
Screen screen;

int score=0;

/* フラグ一覧 */
int sw_flag = 0;
int cir_flag = 0;
int key_flag = 0;
int scr_flag = 0;
double fing[4]={0,0,0,0};

void idle(void){
        glutPostRedisplay();
}

/************* LeapMotion ***************/

class SampleListener : public Listener {
        public:
                virtual void onInit(const Controller&);
                virtual void onConnect(const Controller&);
                virtual void onDisconnect(const Controller&);
                virtual void onExit(const Controller&);
                virtual void onFrame(const Controller&);
                //virtual void onFocusGained(const Controller&);
		//virtual void onFocusLost(const Controller&);
};

void SampleListener::onInit(const Controller& controller) {
	std::cout << "Initialized" << std::endl;
}

void SampleListener::onConnect(const Controller& controller) {
	std::cout << "Connected" << std::endl;
	/* 使用するジェスチャーをセットする */
  	controller.enableGesture(Gesture::TYPE_CIRCLE);
  	controller.enableGesture(Gesture::TYPE_KEY_TAP);
  	controller.enableGesture(Gesture::TYPE_SCREEN_TAP);
  	controller.enableGesture(Gesture::TYPE_SWIPE);
}

void SampleListener::onDisconnect(const Controller& controller) {
	std::cout << "Disconnected" << std::endl;
}

void SampleListener::onExit(const Controller& controller) {
	std::cout << "Exited" << std::endl;
}

void SampleListener::onFrame(const Controller& controller) {
	//ここに処理を書く
	Frame frame = controller.frame();// 最新のFrameを取得する
  	HandList handList = frame.hands();// 全ての手の情報を取得する
  	FingerList allFingerList = frame.fingers();// 全ての指の情報を取得する
  	GestureList gesturesInFrame = frame.gestures();// 全てのジェスチャーの情報を取得する
  	int i, j;
	
  	//それぞれの個数を表示する
  	printf("hands:%d, fingers:%2d, gestures:%d\n",
          	handList.count(), allFingerList.count(), gesturesInFrame.count());

  	//手と指の処理
  	for(i = 0; i < handList.count(); i++){
    		Hand hand = handList[i];
    		Vector handCenter = hand.palmPosition();
    		FingerList fingerList = hand.fingers();// handの指の情報を取得する
    
    		//個別の手の情報を出力する
    		printf("  hand[%d] (%6.1f,%6.1f,%6.1f), fingers:%d\n",
             	i, handCenter.x, handCenter.y, handCenter.z, fingerList.count());
    		for(j = 0; j < fingerList.count(); j++){
      			Finger finger = fingerList[j];
      			Vector currentPosition = finger.tipPosition();
			
      			//個別の指の情報を出力する
      			//printf("    finger[%d] (%6.1f,%6.1f,%6.1f)\n",
               		//j, currentPosition.x, currentPosition.y, currentPosition.z);
			//x = ((x + 100) / 29) - 3.5
			//y = ((y - 250) / 12.5)
			//-100 < x < 100 -> -3.5 < x < 3.5
			// 250 < y < 300 ->    0 < y < 4
    			fing[0]=j;
			fing[1]= ( (currentPosition.x + 100) / 29) - 3.5;
			fing[2]= ( (currentPosition.y - 250) / 25) + 6;
			fing[3]= currentPosition.z;
			//printf("%f  %f \n",fing[1],fing[2]); 
			glutIdleFunc(idle);
		}
  	}

  	//ジェスチャーの処理
  	GestureList gestures = frame.gestures();
  	for (i = 0; i < gestures.count(); i++){
    		Gesture gesture = gestures[i];

    		//ジェスチャーの種類の出力
    		printf("  gesture[%d] ",i);
    		switch (gesture.type()) {
      		case Gesture::TYPE_CIRCLE:
			if(shoot_flag == 0){
                                shoot_flag = 1;
                                shootx = fing[1];
                                shooty = fing[2];
                        }
                        glutIdleFunc(idle);
        		printf("CIRCLE\n");
			break;
      		case Gesture::TYPE_SWIPE:
        		printf("SWIPE\n");
			glutIdleFunc(idle);
        		break;
      		case Gesture::TYPE_KEY_TAP:
        		printf("KEY_TAP\n");
			break;
      		case Gesture::TYPE_SCREEN_TAP:
        		printf("SCREEN_TAP\n");
        		break;
      		default:
        		printf("unknown\n");
        		break;
    		}
  	}
}

SampleListener listener;

void CleanupExit(){
	controller.removeListener(listener);
	exit (1);
}

int GetRandom(double min, double max){
	return min + (double)(rand()*(max-min+1.0)/(1.0+RAND_MAX));
}

/****************** OpenGL ***************/

/* 地面を描く */
void myGround(double height){
	static GLfloat ground[][4] = {
		{ 0.6, 0.6, 0.6, 1.0 },
		{ 0.3, 0.3, 0.3, 1.0 }
	};
	
	int i,j;
	
	glBegin(GL_QUADS);
	glNormal3d(0.0, 1.0, 0.0);
	for(j = -D / 2; j < D / 2; ++j){
		for(i = -W / 2; i < W / 2; ++i){
			glMaterialfv(GL_FRONT, GL_DIFFUSE, ground[(i+j) & 1]); //質感
			glVertex3d((GLdouble)i, height, (GLdouble)j);
			glVertex3d((GLdouble)i, height, (GLdouble)(j+1));
			glVertex3d((GLdouble)(i+1), height, (GLdouble)(j+1));
			glVertex3d((GLdouble)(i+1), height, (GLdouble)j);
		}
	}
	glEnd();
}

/* 画面表示 */
void display(void){
	
	double rx,ry;
	srand((double)time(NULL));
	
	rx = GetRandom(0,7) - 3.5;
	ry = GetRandom(0,4);
	
	/* 光源の位置 */
	static GLfloat lightpos[] = { 3.0, 4.0, 5.0, 1.0 };
	
	/* 球の色 */
	static GLfloat white[]  = { 0.0, 1.0, 1.0, 1.0 };
	static GLfloat white2[] = { 1.0, 0.0, 0.0, 1.0 };
	
	/* 球の位置 */
	static double qx = fing[1], qy = fing[2];
	static double shootz = 0;
	
	/* 物理演算 */
	qx = fing[1];
	qy = fing[2];
	
	/* その他条件 */
	if(shoot_flag) {
		if( shootz < -10 ) shoot_flag = 0;
		shootz -= 0.1;
	}
	else shootz = 10; 
	/* 当たり判定 */
	if(shootz < -7 &&
	   rx - 0.5 < shootx && shootx < rx + 0.5 &&
	   ry - 0.5 < shooty && shooty < ry + 0.5){
		score += 1;
		if(score == 1){
			sleep(3);
			exit(0);
		}
	}
	/* 画面クリア */
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	/* モデルビュー変換行列の初期化 */
	glLoadIdentity();
	
	/* 光源の位置を設定 */
	glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
	
	/* 視点の移動(物体の方を奥に移す) */
	glTranslated(0.0, -QY, -D);
	
	/* 文字列の描画 */
	glColor3d(0.0, 0.0, 1.0);
	
	/* シーンの描画 */
	myGround(0.0);
	if(shoot_flag){
		glPushMatrix();
			glTranslated(shootx,shooty,shootz);
        	        glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
        	        glutSolidSphere(0.1, 16, 8);
		glPopMatrix();
	}
	
	glPushMatrix();
		glTranslated(qx,qy,0);
		glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
       		glutSolidSphere(0.05, 16, 8);
	glPopMatrix();
	
	glPushMatrix();
		glTranslated(rx,ry,-7);
                glMaterialfv(GL_FRONT, GL_DIFFUSE, white2);
                glutSolidSphere(0.5, 16, 8);
	glPopMatrix();
	
	glFlush();
}


void resize(int w, int h){
	/* ウインドウ全体をビューボート */
	glViewport(0, 0, w, h);
	
	/* 透視変換行列の設定 */
	glMatrixMode(GL_PROJECTION);
	
	/* 透視変換行列の初期化 */
	glLoadIdentity();
	gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0);
	
	/* モデルビュー変換行列の指定 */
	glMatrixMode(GL_MODELVIEW);
}
/*
void mouse(int button, int state, int x, int y){
	switch(button){
	case GLUT_LEFT_BUTTON:
		if(state == GLUT_DOWN){
			//アニメーション開始
			glutIdleFunc(idle);
			flag = 1;number++;
		}
		//else glutIdleFunc(0);
		break;
	case GLUT_RIGHT_BUTTON:
		if(state == GLUT_DOWN){
			// コマ送り(1ステップだけ進める)
			glutPostRedisplay();
		}
		break;
	//defaul:
	//	break;
	}
}
*/
void keyboard(unsigned char key, int x, int y){
	/* ETCで終了 */
	if(key == '\033') 
		exit(0);
}

void init(void){
	/*初期設定*/
	glClearColor(1.0, 1.0, 1.0, 1.0);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_CULL_FACE);
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
}

void ReSizeGLScene(int Width, int Height)
{
	if(Height==0)
		Height=1;
	screen_width = Width;
	screen_height = Height;
}

int main(int argc, char *argv[]){	
	const char *title = "Game";
 	SampleListener listener;
  	Controller controller;
	
	controller.addListener(listener);
	
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH);
	glutInitWindowSize(screen_width, screen_height);
	glutInitWindowPosition(0, 0);
	glutCreateWindow(title);
	glutDisplayFunc(display);
	glutReshapeFunc(resize);
	//glutMouseFunc(mouse);
	glutKeyboardFunc(keyboard);
	init();
	
	glutMainLoop();
	
	return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: OpenGL glut 文字の描画

#2

投稿記事 by みけCAT » 9年前

あまり詳しくないしテストもしていない予想ですが、gluPerspectiveでzが1.0~100.0のものしか描画しないように設定しているのに、
文字列の位置をz=-1.0にしているから描画されない、ということではないですか?
オフトピック
どうしてdisplay関数内で

コード:

srand((double)time(NULL));
を実行しているのだろう…?
しかも、どうしてわざわざtime関数の戻り値を一旦doubleにキャストしているのだろう…?

c - srand() — why call it only once? - Stack Overflow
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Toshita
記事: 23
登録日時: 9年前

Re: OpenGL glut 文字の描画

#3

投稿記事 by Toshita » 9年前

返信有難う御座います.

すみません,解決しました.
うすうす気づいてましたがフォントいれてませんでした.
お付き合いいただきありがとうございました.

下を追加したらいけました.

コード:

void *font = GLUT_BITMAP_HELVETICA_18;
/* 文字の描画 */
void DrawString(const char *str,void *font,float x,float y,float z)
{
	glRasterPos3f(x,y,z);
	while(*str){
		glutBitmapCharacter(font, *str);
		++str;
	}
}


********************************************************************************
試してみたのですが、やはり描画できてないようです....
というか,画面外に描画されているのか,文字の色が背景と同化してるのか,
そもそも描画されてないのかがわかりませんでした.
何か確認方法はないのでしょうか?
もしかしてフォントいれてないからでしょうか?


ランダム関数は毎回計算しなおして,タイムラグでもでてくれたらいいなと思いあそこに置いてます.(いいのか悪いのかはわかりませんが)
double型にしたのは,ランダムに取得した値が小数点もいれれたらと思ってやってます(取得後-3.5してdouble型に代入するため)

コード:

/* サンプルコード */
/* 文字の描画 */
void printString(float x, float y, const char* str, int length){
	float z = 4.0f;
	glRasterPos3f(x, y, z);
	
	for (int i = 0; i < length; i++){
		glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]);
	}
}

/******略*********/

/* 画面表示 */
void display(void){
	
	double rx,ry;
	srand((double)time(NULL));
	
	rx = GetRandom(0,7) - 3.5;
	ry = GetRandom(0,4);
	
	/* 光源の位置 */
	static GLfloat lightpos[] = { 3.0, 4.0, 5.0, 1.0 };
	
	/* 球の色 */
	static GLfloat white[]  = { 0.0, 1.0, 1.0, 1.0 };
	static GLfloat white2[] = { 1.0, 0.0, 0.0, 1.0 };
	
	/* 球の位置 */
	static double qx = fing[1], qy = fing[2];
	static double shootz = 0;
	
	/* 物理演算 */
	qx = fing[1];
	qy = fing[2];
	
	/* その他条件 */
	if(shoot_flag) {
		if( shootz < -10 ) shoot_flag = 0;
		shootz -= 0.1;
	}
	else shootz = 10; 
	/* 当たり判定 */
	if(shootz < -7 &&
	   rx - 0.5 < shootx && shootx < rx + 0.5 &&
	   ry - 0.5 < shooty && shooty < ry + 0.5){
		score += 1;
		if(score == 1){
			sleep(3);
			exit(0);
		}
	}
	/* 画面クリア */
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	/* モデルビュー変換行列の初期化 */
	glLoadIdentity();
	
	/* 光源の位置を設定 */
	glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
	
	printString(0, 3, "HogeHoge", 16);
	
	/* 視点の移動(物体の方を奥に移す) */
	glTranslated(0.0, -QY, -D);
	
	/* 文字列の描画 */
	glColor3d(0.0, 0.0, 1.0);
	
	/* シーンの描画 */
	myGround(0.0);
	if(shoot_flag){
		glPushMatrix();
			glTranslated(shootx,shooty,shootz);
        	        glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
        	        glutSolidSphere(0.1, 16, 8);
		glPopMatrix();
	}
	
	glPushMatrix();
		glTranslated(qx,qy,0);
		glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
       		glutSolidSphere(0.05, 16, 8);
	glPopMatrix();
	
	glPushMatrix();
		glTranslated(rx,ry,-7);
                glMaterialfv(GL_FRONT, GL_DIFFUSE, white2);
                glutSolidSphere(0.5, 16, 8);
	glPopMatrix();
	
	glFlush();
}

int main(int argc, char *argv[]){	
	const char *title = "Game";
 	SampleListener listener;
  	Controller controller;
	
	controller.addListener(listener);
	
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH);
	glutInitWindowSize(screen_width, screen_height);
	glutInitWindowPosition(0, 0);
	glutCreateWindow(title);
	glutDisplayFunc(display);
	glutReshapeFunc(resize);
	//glutMouseFunc(mouse);
	glutKeyboardFunc(keyboard);
	init();
	
	glutMainLoop();
	
	return 0;
}

閉鎖

“C言語何でも質問掲示板” へ戻る