現在 C++ で Glut で OpenGLを描いています.
そこで描画がうまくできず悩んでいます.
下のプログラムを実行すると,画面をクリックするたびに球が発射されます。
しかし,私がやりたいのは,クリックのたびに球が発射され,100コ目が発射されたら,また0番目の球を発射していくという流れなのですが,
何を間違えたのかクリックするたびに全ての球が元の位置に戻りかつ,上にずらーっと100コ並んで進んでいます.
どこでそんなことになってるのか全くわからないです.y軸は固定しているつもりなのですが・・・.
教えて欲しいのは
100コある球を個別に発射し,(クリックのたびに1つ発射),100コ目がきたら
0コ目の球を発射する.
↓これがだめなのでしょうか?
for(int i=0;i<100;i++){
glTranslated(0, 1.5, make[number].pz);
glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
glutSolidSphere(0.05, 16, 8);
}
いい方法を教えて下さい.
また,リープモーションは無視していただいても大丈夫です.
Makefile
CFLAGS = -I/usr/X11R6/include
LDLIBS = -L/usr/X11R6/lib -lglut -lGLU -lGL -lXi -lXext -lX11 -lm -lpthread -Wall /usr/lib/Leap/libLeap.so -I/usr/local/include/Leap
#all: main.cpp
#start: main.cpp
# $(CC) $(CFLAGS) main.cpp -o start $(LDLIBS)
start: main.cpp
$(CC) $(CFLAGS) main.cpp -o start $(LDLIBS)
/* Include */
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include "Leap.h"
/* フィールド生成用 */
#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;
typedef struct{
double px;
double py;
double pz;
}qmake;
int number;//球の番号
int window;
int screen_width = DEFAULT_WIDTH;
int screen_height = DEFAULT_HEIGHT;
int flag = 0;
Controller controller;
Screen screen;
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);
}
}
//ジェスチャーの処理
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:
printf("CIRCLE\n");
break;
case Gesture::TYPE_SWIPE:
glutIdleFunc(idle);
flag = 1;number++;
printf("SWIPE\n");
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);
}
/****************** 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){
if(number >= 100) number = 0;
/* 光源の位置 */
static GLfloat lightpos[] = { 3.0, 4.0, 5.0, 1.0 };
/* 球の色 */
static GLfloat white[] = { 0.0, 1.0, 0.0, 0.0 };
/* 球の位置 */
qmake make[QM];
static double px=QX,py=QY,pz=QZ;
make[number].px = px;
make[number].py = py;
make[number].pz = pz;
pz -= 0.01;
/* 物理演算 */
if(flag) {
pz = 10;
flag = 0;
}
make[number].px += 0.000;
make[number].py += 0.000;
make[number].pz -= 0.01;
/* 画面クリア */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* モデルビュー変換行列の初期化 */
glLoadIdentity();
/* 光源の位置を設定 */
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
/* 視点の移動(物体の方を奥に移す) */
glTranslated(0.0, -QY, -D);
/* シーンの描画 */
myGround(0.0);
for(int i=0;i<100;i++){
glTranslated(0, 1.5, make[number].pz);
glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
glutSolidSphere(0.05, 16, 8);
}
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;
}