現在地: メニュー >> 基本編25 >> 基本編25::まとめコード3

問題


基本編25::まとめコード1のプログラムを変更して、垂直同期をオフにして実行せよ。

答え

「wglew.h」による「WGL_EXT_swap_control拡張」を使用した。
#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <GL/glew.h>
#include <GL/wglew.h>//glew.hに加え「wgl**関数」を使う
#include <GL/glut.h>

//--------- 各種外部変数 ------------//
//最大値
const int MaxParticle = 1000;

struct Particles        //パーティクル
{
	float life; //生存期間
	float fadeSpeed; //消滅速度
	float x,y,z; //現在値
	float r,g,b,a; //色
	float MoveX,MoveY,MoveZ; //移動方向
	float xg,yg,zg; //重力
};
Particles balls[MaxParticle];

const float SlowDown = 10.0;


//マウスの状態
struct MOUSE
{
	int Xstart,Ystart;
	bool flag;
	double weight;
};
MOUSE MouseStatus={0,0,false,0.5};

//回転関係
struct ObjectRotate
{
	double xAngle,yAngle;
};
ObjectRotate ObjRot={0,0};


int GLframe = 0; //フレーム数
int GLtimenow = 0;//経過時間
int GLtimebase=0;//計測開始時間



//----------- プロトタイプ宣言 ------------//
void display();
void reshape(int w, int h);
void myMouseFunc(int button,int state,int x,int y);
void myMouseMotion(int x,int y);
void idle();

void DRAW_XYZ();
void InitParticles();
void DrawParticles();
void CalcNextStatus();


//------------- OpenGLの初期設定 ------------------//
void GLUT_INIT()
{
	glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH); //ダブルバッファ、Zバッファ
	glutInitWindowSize(640,480);
	glutCreateWindow("Basic Particle");
}


void GLUT_CALL_FUNC()
{
	glutDisplayFunc(display);
	glutReshapeFunc(reshape);
	glutMouseFunc(myMouseFunc);
	glutMotionFunc(myMouseMotion);
	glutIdleFunc(idle);
}

void MY_INIT()
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_DEPTH_TEST);  //Zバッファ有効化
}

//パーティクルの初期化
void InitParticles()
{
	srand( static_cast<unsigned int>( time(NULL) ) );

	for(int loop = 0; loop < MaxParticle; ++loop){
		//生存時間の設定
		balls[loop].life = 1.0; //初期生存時間
		balls[loop].fadeSpeed = static_cast<float>((rand() % 100)) / 1000 + 0.003f; //消滅速度(0.001〜0.099 + 0.003)
		//初期位置の設定
		balls[loop].x = balls[loop].y = balls[loop].z = 0;

		//各移動量決定
		balls[loop].MoveX = static_cast<float>( (rand() % 50 - 26.0) ) * 10;
		balls[loop].MoveY = static_cast<float>( (rand() % 50 - 25.0 ) ) * 10;
		balls[loop].MoveZ = static_cast<float>( (rand() % 50 - 25.0 ) ) * 10; 

		balls[loop].xg = 0;
		balls[loop].yg = -1.0;
		balls[loop].zg = 0;
	}
}

//----------- メイン関数 --------------//
int main(int argc, char **argv)
{
	glutInit(&argc,argv);

	GLUT_INIT();
	
	//----glew の初期設定-----//
	GLenum err = glewInit();
	if (err != GLEW_OK){
		std::cerr << glewGetErrorString(err) << "\n"; //エラーを出力
		return -1;
	}


	GLUT_CALL_FUNC();
	MY_INIT();

	wglSwapIntervalEXT(0);//垂直同期をしない

	InitParticles(); //パーティクルの初期化

	glutMainLoop();

	return 0;
}


//----------- ここからコールバック --------------//
void display()
{

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glLoadIdentity();

	gluLookAt(0.0, 0.0, 8.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
	glRotated(ObjRot.xAngle,1,0,0);
	glRotated(ObjRot.yAngle,0,1,0);

	DRAW_XYZ();  //XYZ軸の描画


	DrawParticles();

	glColor3d(1,1,1); //色のリセット

	glutSwapBuffers();

	CalcNextStatus(); //パーティクルの次の状態を計算

}

void reshape(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 myMouseFunc(int button,int state,int x,int y)
{
	if(button == GLUT_LEFT_BUTTON &&state == GLUT_DOWN){
		MouseStatus.Xstart = x;
		MouseStatus.Ystart = y;
		MouseStatus.flag = true;
	}
	else{
		MouseStatus.flag =false;
	}
}

void myMouseMotion(int x,int y)
{
	if(MouseStatus.flag == false)return;

	static int xdir,ydir;

	xdir = x - MouseStatus.Xstart;
	ydir = y - MouseStatus.Ystart;

	ObjRot.xAngle += (double)ydir * MouseStatus.weight;
	ObjRot.yAngle += (double)xdir * MouseStatus.weight;

	MouseStatus.Xstart = x;
	MouseStatus.Ystart = y;
}


void idle(void)
{
	glutPostRedisplay();   //再描画( ※display()関数を呼び出す関数 )
	GLframe++; //フレーム数を+1
	GLtimenow = glutGet(GLUT_ELAPSED_TIME);//経過時間を取得
	if (GLtimenow - GLtimebase > 1000)      //1秒たったらfpsを出力
	{
		printf("fps:%f\r",GLframe*1000.0/(GLtimenow-GLtimebase));
		GLtimebase = GLtimenow;//基準時間を設定                
		GLframe = 0;//フレーム数をリセット
	}

}


//----------- ここから各種関数 ---------------//
void DRAW_XYZ()
{
	glBegin(GL_LINES);

	glColor3f(0,1,0);//x
	glVertex2f(-100,0);
	glVertex2f(100, 0);

	glColor3f(1,0,0);//y
	glVertex2f(0,0);
	glVertex2f(0,100);

	glColor3f(0,0,1);//z
	glVertex3f(0,0,-100);
	glVertex3f(0,0, 100);
	glEnd();
}

void DRAW_TRI()
{
	glBegin(GL_TRIANGLES);
	glVertex2f(0,1);
	glVertex2f(-0.5, 0);
	glVertex2f(0.5, 0);
	glEnd();
}

//------- パーティクル描画 -------//
void DrawParticles()
{
	glEnable(GL_BLEND);
	glPointSize(3);
	glBegin(GL_POINTS);
	for(int loop = 0; loop < MaxParticle; ++loop){
		glColor4f(1,0,1,balls[loop].life);
		glVertex3f(balls[loop].x,balls[loop].y,balls[loop].z);
	}
	glEnd();
	glDisable(GL_BLEND);
	glPointSize(1);
}


void CalcNextStatus()
{
	for(int loop = 0; loop < MaxParticle; ++loop)
	{
		balls[loop].life -= balls[loop].fadeSpeed;//ライフを減らす

		if (balls[loop].life <= 0)//ライフチェック
		{
			balls[loop].life = 1.0; //初期生存時間
			balls[loop].fadeSpeed = static_cast<float>((rand() % 100)) / 1000 + 0.003f; //消滅速度(0.001〜0.099 + 0.003)
			//初期位置の設定
			balls[loop].x = balls[loop].y = balls[loop].z = 0;
			//各移動量決定
			balls[loop].MoveX = static_cast<float>( (rand() % 50 - 26.0) ) * 10; //最大230 
			balls[loop].MoveY = static_cast<float>( (rand() % 50 - 25.0 ) ) * 10; //最大240
			balls[loop].MoveZ = static_cast<float>( (rand() % 50 - 25.0 ) ) * 10; //最大240
			//
			balls[loop].xg = 0;
			balls[loop].yg = -0.8;
			balls[loop].zg = 0;
		}else{
			//位置更新
			balls[loop].x += balls[loop].MoveX/(SlowDown*1000);
			balls[loop].y += balls[loop].MoveY/(SlowDown*1000);
			balls[loop].z += balls[loop].MoveZ/(SlowDown*1000);

			balls[loop].MoveX += balls[loop].xg;
			balls[loop].MoveY += balls[loop].yg;
			balls[loop].MoveZ += balls[loop].zg;
		}

	}
}
×

この広告は60日間更新がないwikiに表示されております。

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます