OpenGLでのロケット製作について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
pity

OpenGLでのロケット製作について

#1

投稿記事 by pity » 13年前

[1] (1)ロケットをy軸回りに回転させよ。
(2)一段目(羽のついてる所)を異なる速度で回転させよ。
(3)polarviewを用いて、斜め上30度から見た画面にせよ。
(4)マウス操作で視点の変更を可能とする。
   ・左ボタンの左右方向のドラッグで物体が垂直軸回りに回転。また同ボタンの
    上下方向のドラッグで水平軸回りに回転。
   ・右ボタンのドラッグで、物体が拡大縮小する。
   ・ビューイング変換にはpolrviewを用いる。
(5)F1キーを押すと一段目が離れるようにせよ。
という宿題が出されました。

 [1.1] (3)(5)の作成をしたいと思っております。
 [1.2]

コード:

#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include "myShape.h"
#define KEY_ESC 27

void polarview( void );
void resetview( void );
unsigned char wireFlag = GL_TRUE;
unsigned char revolveFlag = GL_FALSE;
int xBegin, yBegin;

int mButton;
float distance, twist, elevation, azimuth;

float theta=0.0;  /*物体の回転角度*/
float theta2=0.0;  /*物体の回転角度*/

void display( void )
{
	glClear( GL_COLOR_BUFFER_BIT );
	glPushMatrix();

      glTranslatef( 0.0, 0.0, -20.0 );
	polarview();  /*ビューイング*/
        glPushMatrix();
	glRotatef( theta, 0.0, 1.0, 0.0 );  /*回転させたいところ*/
      glTranslatef( 0.0, 1.0, 0.0 );
	glColor3f(1.0,0.0,0.0);
	myWireCylinder( 1.0, 2.0, 12 );
	glTranslatef( 0.0, 1.0, 0.0);
	glRotatef( -90.0, 1.0, 0.0, 0.0 );
	glColor3f(1.0,0.5,0.0);

	glutWireCone( 1.0, 2.0, 12, 3 );
	glPopMatrix();
	glRotatef( theta2, 0.0, 1.0, 0.0 );  /*回転させたいところ*/
	glTranslatef( 0.0, -1.0, 0.0 );
	glColor3f(0.0,1.0,0.0);
	myWireCylinder( 1.0, 2.0, 12 );
	glPopMatrix();

	glPushMatrix();
	glTranslatef( 0.0, -1.0, -20.0);
	polarview();  /*ビューイング*/
	glRotatef( theta2, 0.0, 1.0, 0.0 );  /*回転させたいところ*/
    
	glTranslatef( 0.0, -1.5, 0.0);
	glRotatef( -90.0, 1.0, 0.0, 0.0 );
	glColor3f(0.0,1.0,1.0);
	glutWireCone( 0.5, 0.8, 12, 1 );

	glTranslatef(0.0,0.0,1.5);
	glScalef(0.8,0.07,0.5);
	glColor3f(1.0,0.0,1.0);
	glutWireCube(4.0);

	glTranslatef(0.0,0.0,0.0);
	glScalef(0.08,11.0,1.0);
	glColor3f(1.0,1.0,0.0);
	glutWireCube(4.0);

	glPopMatrix();
	glutSwapBuffers();  /*バッファをスワップする*/
}

void idle(void)  /*イベントがなければidleが常に実行される*/
{
      theta=fmod(theta+0.2,360.0);  /*回転角を0~360まで0.2ずつ増加*/
	theta2=fmod(theta2+2.0,360.0);  /*回転角を0~360まで2.0ずつ増加*/
	glutPostRedisplay();
}

void myKbd( unsigned char key, int x, int y )

{
      if( key == KEY_ESC ) exit( 0 );
}

void myMouse( int button, int state, int x, int y )
{
	if (state == GLUT_DOWN) {
		switch(button) {
		case GLUT_LEFT_BUTTON:
			mButton = button;
			break;
		case GLUT_MIDDLE_BUTTON:
			revolveFlag = !revolveFlag;
			if( revolveFlag == GL_TRUE )
				glutIdleFunc( idle );
			else
				glutIdleFunc(NULL);
			break;
		case GLUT_RIGHT_BUTTON:
			mButton = button;
			break;
		}
		xBegin = x;
		yBegin = y;
	}
}

void myMotion( int x, int y )
{
	int xDisp, yDisp;
	
	xDisp = x - xBegin;
	yDisp = y - yBegin;

	switch (mButton) {
	case GLUT_LEFT_BUTTON:
		azimuth += (float) xDisp/2.0;
		elevation -= (float) yDisp/2.0;
		break;
	case GLUT_RIGHT_BUTTON:
		distance += (float) yDisp/40.0;
		break;
	}
	xBegin = x;
	yBegin = y;
	glutPostRedisplay();
}

void myInit (char *progname)
{
      int width = 300, height = 600;
        float aspect = (float) width / (float) height;
        glutInitWindowPosition(0, 0);
      glutInitWindowSize( width, height );
      glutInitDisplayMode( GLUT_RGBA );
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);  /*ダブルバッファ宣言*/
      glutCreateWindow(progname);
      glClearColor (0.0, 0.0, 0.0, 1.0);
        glutKeyboardFunc( myKbd );
	glutMouseFunc(myMouse);
      glutMotionFunc(myMotion);
	resetview();

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(30.0, aspect, 1.0, 50.0);
      glMatrixMode(GL_MODELVIEW);
}

void resetview( void )
{
      distance = 5.0;
      twist = 0.0;
      elevation = 0.0;
      azimuth = 0.0;
} 

void polarview( void )
{
      glTranslatef( 0.0, 0.0, -distance);
      glRotatef( -twist, 0.0, 0.0, 1.0);
      glRotatef( -elevation, 1.0, 0.0, 0.0);
      glRotatef( -azimuth, 0.0, 1.0, 0.0);
}

int main(int argc, char** argv)
{
      glutInit(&argc, argv);
	myInit(argv[0]);
      glutDisplayFunc(display);
	glutIdleFunc(idle);  /*イベントがない場合にはidleを繰り返す*/
	glutMainLoop();
	return( 0 );
}
 [1.3] 特にありません。
 [1.4]4枚の羽根が作れず、その上視点を変えると羽と噴射口の位置がずれます。
どのように直せばよいのか分からないため、修正をお願い致します。

[2] 環境  
 [2.1] OS : Windows
 [2.2] コンパイラ名 : Microsoft Visual C++ 2010 Express
[3] その他
 ・初心者です。
 ・期限は12月5日までです。
どうぞ、よろしくお願いいたします。

アバター
うしお
記事: 56
登録日時: 14年前

Re: OpenGLでのロケット製作について

#2

投稿記事 by うしお » 13年前

全部追いかけたわけではありませんが、いくつか気になった所に触れてみます。

行列スタックの考え方で混乱してはいませんか?
projectionはdisplayでは操作していませんので問題ないとして、
polarviewでビュー行列を設定しようとしているのだとおもいますが、
基本的に描画のフローとしては、
ビュー行列掛け算→glPushMatrix→モデル1のワールド行列掛け算→モデル1を描画→glPopMatrix
           →glPushMatrix→モデル2のワールド行列掛け算→モデル2を描画→glPopMatrix....
という流れを意識されると整理されると思います。

なんとなく出題意図として「gluLookAtを使わないでやってみよう」という意志が感じられますが、
横着するならgluLookAt関数がいいかなと思います。

pity

Re: OpenGLでのロケット製作について

#3

投稿記事 by pity » 13年前

ご回答ありがとうございます。(3)については出来そうです。
>基本的に描画のフローとしては、
 ビュー行列掛け算→glPushMatrix→モデル1のワールド行列掛け算→モデル1を描画→glPopMatrix
         →glPushMatrix→モデル2のワールド行列掛け算→モデル2を描画→glPopMatrix....
 という流れを意識されると整理されると思います。

ということは、流れを整理できれば羽や噴射口がずれることはないということですか?
教科書レベルのものもまともにできないため、言葉のみで説明していただいてもこの頭では理解することができませんでした。
可能であれば、プログラムで説明していただければと思います。申し訳ありません。

アバター
うしお
記事: 56
登録日時: 14年前

Re: OpenGLでのロケット製作について

#4

投稿記事 by うしお » 13年前

一応ビルドして実行してみましたが(myWireCylinder以外)、
すみません、いまいちどこがずれていてどう直したいのかがわかりません。

ただ流れをはっきりと理解すれば、
どこが意図していないプログラムなのかが見つかりやすくなり、
バグ修正への道は開けます。

pity

Re: OpenGLでのロケット製作について

#5

投稿記事 by pity » 13年前

http://kie.nu/2lB
このリンク先の白黒画像の様にしたいのですが、カラー画像の様に羽と噴射口がずれてしまいます。
これを中央に直したいのです。逆さまにしてもロケットの形が崩れないようにもしたいです。
また、これは2つの四角形で羽を作ってますが、白黒画像の様に4枚羽にしたいと思っています。

アバター
うしお
記事: 56
登録日時: 14年前

Re: OpenGLでのロケット製作について

#6

投稿記事 by うしお » 13年前

► スポイラーを表示
できるだけ意味を把握しやすく整理してみました。
行列スタックの考え方をしっかりと把握することが大切かと思います。
例えば、
Push
 移動(右に1)
 物体1の描画
 Push
 回転(半回転)
 移動(右に2)
 物体2の描画
 Pop
Pop
という構造の時は、
物体1は 右に1移動した状態
物体2は 右に2移動→半回転→右に1移動した状態
という状態になります。
すこしややこしいでしょうか?
実際にためしながら、体で覚えるといいかと思います。

追記
openglutなのは気にせずglutで問題ないはずです。

pity

Re: OpenGLでのロケット製作について

#7

投稿記事 by pity » 13年前

教科書と文がだいぶ違っていたので初めは分かりませんでしたが、
何とか出来たと思います。有難うございました!

閉鎖

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