OpenGLでスカイボックスの内部にジェットコースターを作成していますが、機能やコンピュータグラフィックスの背景があまりないため、非常に困難です。私はCatmull-Romスプライン補間を使ってローラーコースターを描き、glVertex3fで各点を描きました。今度は、update()
関数を50msごとに呼び出して、カメラをトラックの周りに移動したいと考えています。 gluLookAt()
は奇妙な結果を生み出しています。画面からトラックを削除したり、黒い画面を表示したりしています。私は行列関数の一部を移動する必要があると思いますが、それぞれをどこに置くのかはわかりません。ここに私のコードは、これまでです:OpenGL gluLookAt()が意図したとおりに動作しない
int main(int argc, char** argc)
{
// ... load track, etc ...
// Init currpos, nextpos, iter, up
currpos = Vec3f(0, 0, 0);
nextpos = currpos;
iter = 0;
up = Vec3f(0, 1, 0);
deque<Vec3f> points;
Vec3f newpt;
// Loop through the points and interpolate
for (pointVectorIter pv = g_Track.points().begin(); pv != g_Track.points().end(); pv++)
{
Vec3f curr(*pv); // Initialize the current point and a new point (to be drawn)
points.push_back(curr); // Push the current point onto the stack
allpoints.push_back(curr); // Add current point to the total stack
if (points.size() == 4) // Check if there are 4 points in the stack, if so interpolate
{
for (float u = 0.0f; u < 1.0f; u += 0.01f)
{
newpt = interpolate(points[0], points[1], points[2], points[3], u);
glColor3f(1, 1, 1);
glVertex3f(newpt.x(), newpt.y(), newpt.z());
allpoints.push_back(newpt);
}
points.pop_front();
}
}
// glutInit, InitGL(), etc...
}
void InitGL(GLvoid)
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(100.0, (GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT, .0001, 999999);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
}
void display (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(currpos.x(), currpos.y(), currpos.z(), nextpos.x(), nextpos.y(), nextpos.z(), up.x(), up.y(), up.z());
glPushMatrix();
glEnable(GL_TEXTURE_2D); // Enable texturing from now on
/* draw skybox, this was from previous assignment and renders correctly */
glPopMatrix();
// now draw rollercoaster ...
glPushMatrix();
glBegin(GL_LINE_STRIP);
deque<Vec3f> points;
Vec3f newpt;
for each (Vec3f pt in allpoints)
{
glColor3f(1, 1, 1);
glVertex3f(pt.x(), pt.y(), pt.z());
}
glutTimerFunc(50, update, 1);
glEnd();
glPopMatrix();
// Swap buffers, so one we just drew is displayed
glutSwapBuffers();
}
void update(int a)
{
if (iter < allpoints.size())
{
currpos = allpoints[iter];
nextpos = allpoints[iter + 1];
gaze = nextpos - currpos;
gaze.Normalize();
Vec3f::Cross3(binorm, gaze, up);
binorm.Normalize();
Vec3f::Cross3(up, binorm, gaze);
up.Normalize();
glutPostRedisplay();
}
iter++;
}
アイデアは、私はスプラインの制御点と補間点を含めたグローバル両端キューallpoints
を保管しておりますということです。それが完了したら、update()
を50msごとに呼び出し、allpoints
の各ポイントに沿ってカメラを移動します。以前のバージョンのプロジェクトでは、ローラーコースターが正しく描かれていたことがわかりました。 gluLookAt()
ですが、私はそれをしたいとは思えません。上記のコードでは、カメラはスカイボックスの片側をローラーコースターの一部で見てカメラから始まり、update()
が呼び出されるとローラーコースターは消えるが、カメラは動かない。 OpenGLの行列関数をどこに置いているのか、どこにあるのかによっては、空白の画面が表示されることがあります。update()
申し訳ありませんが、 'glPopMatrix()'はローラーコースターの前にスカイボックスコードの最後にあります(私はスカイボックスコードを含んでいないので、それを忘れてしまいました)またはそれはジェットコースターの描画の後にする必要がありますか? –
@Logan実行時に制御フローが同じでも、 'glPopMatrix'は' glPushMatrix'と同じスコープになければなりません。 –
'glPopMatrix()'は、コメントされたスカイボックスコードの後(rcが 'glVertex3f'で描画される前)であるべきですか、' glVertex3f'でrcを描画するループの後にあるべきですか? –