現在、OpenGLによる3次元プログラミングというコロナ社の教科書を使って勉強しています。
ロケットの、円柱の部分、円錐の部分、羽と、噴出口の部分を、y軸回りに全て回転させたいのですが、うまくいきません。。
この状態で実行すると、ロケットの円柱と、円錐の部分の形が崩れてしまいます・・
idel関数等を追加したら、このようにロケットの原型もない形になってしまいました。
また、glRotatef()は各部分の前に差し込めばいいのでしょうか。
教えていただける方いましたら宜しくお願いします。
上のプログラムが、ロケットに①アニメーション設定中のプログラム、下が、②ロケットのプログラムになります。
#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
float theta = 0.0;
void display( void )
{
float r;
r = 2.0;
glClear( GL_COLOR_BUFFER_BIT );
glPushMatrix();
glTranslatef( 0.0, 0.0, -20.0 );
glPushMatrix();
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.0,0.0);
glutWireCone( 1.0, 2.0, 12, 3 );
glPopMatrix();
glTranslatef( 0.0, -1.0, 0.0 );
glColor3f(1.0, 0.0, 0.0);
myWireCylinder( 1.0, 2.0, 12 );
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, 0.0, -20.0);
glPushMatrix();
glTranslatef(-1.0, -1.0, 0.0);
glPushMatrix();
glPopMatrix();
glColor3f(1.0, 1.0, 1.0);
glutWireCube(r);
glPopMatrix();
glPushMatrix();
glTranslatef(1.0, -1.0, 0.0);
glutWireCube(r);
glPopMatrix();
glTranslatef(0.0, -2.5, 0.0);
glRotatef(-90.0, 1.0, 0.0, 0.0);
glutWireCone(0.5, 1.0, 12, 3);
glutSwapBuffers();
}
void idle(void)
{
theta = fmod(theta + 0.5, 360.0);
glutPostRedisplay();
}
void myKbd( unsigned char key, int x, int y )
{
if( key == KEY_ESC ) exit( 0 );
}
void myInit (char *progname)
{
int width = 300, height = 600;
float aspect = (float) width / (float) height;
glutInitWindowPosition(0, 0);
glutInitWindowSize( width, height );
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA );
glutCreateWindow(progname);
glClearColor (0.0, 0.0, 0.0, 1.0);
glutKeyboardFunc( myKbd );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, aspect, 1.0, 50.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
myInit(argv[0]);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMainLoop();
return( 0 );
}
①
#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
float theta = 0.0;
void display( void )
{
float r;
r = 2.0;
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0, 0.0, -20.0);
glPushMatrix();
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.0, 0.0);
glutWireCone(1.0, 2.0, 12, 3);
glPopMatrix();
glTranslatef(0.0, -1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
myWireCylinder(1.0, 2.0, 12);
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, 0.0, -20.0);
glPushMatrix();
glTranslatef(-1.0, -1.0, 0.0);
glPushMatrix();
glPopMatrix();
glColor3f(1.0, 1.0, 1.0);
glutWireCube(r);
glPopMatrix();
glPushMatrix();
glTranslatef(1.0, -1.0, 0.0);
glutWireCube(r);
glPopMatrix();
glTranslatef(0.0, -2.5, 0.0);
glRotatef(-90.0, 1.0, 0.0, 0.0);
glutWireCone(0.5, 1.0, 12, 3);
glFlush();
}
void myKbd( unsigned char key, int x, int y )
{
if( key == KEY_ESC ) exit( 0 );
}
void myInit (char *progname)
{
int width = 500, height = 500;
float aspect = (float) width / (float) height;
glutInitWindowPosition(0, 0);
glutInitWindowSize( width, height );
glutInitDisplayMode(GLUT_RGBA);
glutCreateWindow(progname);
glClearColor (0.0, 0.0, 0.0, 1.0);
glutKeyboardFunc( myKbd );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, aspect, 1.0, 50.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
myInit(argv[0]);
glutDisplayFunc(display);
glutMainLoop();
return( 0 );
}
②
Open GLのアニメーションについて
Re: Open GLのアニメーションについて
パーツがバラバラになるのはdisplay関数でglPushMatrixとglPopMatrixの対応が合っていないためです。
元からある不具合です。
回転を単純にするため、Z軸方向に-20ずらして配置されていたモデルを、原点中心に配置するようにしました。
その分、gluLookAtを使って視点をZ軸方向に20ずらします。
元からある不具合です。
回転を単純にするため、Z軸方向に-20ずらして配置されていたモデルを、原点中心に配置するようにしました。
その分、gluLookAtを使って視点をZ軸方向に20ずらします。
► スポイラーを表示
Re: Open GLのアニメーションについて
有り難うございます。実行してみたところ回転させることができました。
もう一つ質問なのですが、本ではglLookAtをdisplay関数上で使って動かしているようで、それと同じようにやってみたいと思い、少しdisplay関数を変更して
実行してみたところスクリーン上に何もうつらなくなってしまいました。よろしければ修正していただけると有り難いです。
宜しくお願いします。
#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
float theta = 0.0;
void display(void)
{
float r;
r = 2.0;
glClear(GL_COLOR_BUFFER_BIT);
gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(theta, 0.0f, 1.0f, 0.0f);
glPushMatrix();
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.0, 0.0);
glutWireCone(1.0, 2.0, 12, 3);
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, -1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
myWireCylinder(1.0, 2.0, 12);
glPushMatrix();
glTranslatef(-1.0, -1.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glutWireCube(r);
glPopMatrix();
glPushMatrix();
glTranslatef(1.0, -1.0, 0.0);
glutWireCube(r);
glPopMatrix();
glTranslatef(0.0, -2.5, 0.0);
glRotatef(-90.0, 1.0, 0.0, 0.0);
glutWireCone(0.5, 1.0, 12, 3);
glutSwapBuffers();
}
void idle(void)
{
theta = fmod(theta + 0.5, 360.0);
glutPostRedisplay();
}
void myKbd(unsigned char key, int x, int y)
{
if (key == KEY_ESC) exit(0);
}
void myInit(char *progname)
{
int width = 300, height = 600;
float aspect = (float)width / (float)height;
glutInitWindowPosition(0, 0);
glutInitWindowSize(width, height);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow(progname);
glClearColor(0.0, 0.0, 0.0, 1.0);
glutKeyboardFunc(myKbd);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, aspect, 1.0, 50.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
myInit(argv[0]);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMainLoop();
return(0);
}
もう一つ質問なのですが、本ではglLookAtをdisplay関数上で使って動かしているようで、それと同じようにやってみたいと思い、少しdisplay関数を変更して
実行してみたところスクリーン上に何もうつらなくなってしまいました。よろしければ修正していただけると有り難いです。
宜しくお願いします。
#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
float theta = 0.0;
void display(void)
{
float r;
r = 2.0;
glClear(GL_COLOR_BUFFER_BIT);
gluLookAt(0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(theta, 0.0f, 1.0f, 0.0f);
glPushMatrix();
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.0, 0.0);
glutWireCone(1.0, 2.0, 12, 3);
glPopMatrix();
glPushMatrix();
glTranslatef(0.0, -1.0, 0.0);
glColor3f(1.0, 0.0, 0.0);
myWireCylinder(1.0, 2.0, 12);
glPushMatrix();
glTranslatef(-1.0, -1.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glutWireCube(r);
glPopMatrix();
glPushMatrix();
glTranslatef(1.0, -1.0, 0.0);
glutWireCube(r);
glPopMatrix();
glTranslatef(0.0, -2.5, 0.0);
glRotatef(-90.0, 1.0, 0.0, 0.0);
glutWireCone(0.5, 1.0, 12, 3);
glutSwapBuffers();
}
void idle(void)
{
theta = fmod(theta + 0.5, 360.0);
glutPostRedisplay();
}
void myKbd(unsigned char key, int x, int y)
{
if (key == KEY_ESC) exit(0);
}
void myInit(char *progname)
{
int width = 300, height = 600;
float aspect = (float)width / (float)height;
glutInitWindowPosition(0, 0);
glutInitWindowSize(width, height);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow(progname);
glClearColor(0.0, 0.0, 0.0, 1.0);
glutKeyboardFunc(myKbd);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, aspect, 1.0, 50.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
myInit(argv[0]);
glutDisplayFunc(display);
glutIdleFunc(idle);
glutMainLoop();
return(0);
}
Re: Open GLのアニメーションについて
わたしの提示したコードに元々あったglLoadIdentityを戻し、余計に加えられたglPushMatrixを削除します。
結果としてgluLookAtの場所を移動しただけになります。
結果としてgluLookAtの場所を移動しただけになります。
► スポイラーを表示