Sto facendo un rollercoaster all'interno di uno skybox in OpenGL e senza molto background sulle sue funzioni o la grafica del computer si sta dimostrando molto difficile. Ho disegnato un rollercoaster utilizzando l'interpolazione di Catmull-Rom spline e ho disegnato ogni punto con glVertex3f. Ora voglio chiamare una funzione update()
ogni 50ms per spostare la telecamera attorno alla traccia. gluLookAt()
sta producendo risultati strani, sia rimuovendo la traccia dallo schermo, producendo uno schermo nero, ecc. Penso di aver bisogno di spostare alcune delle funzioni della matrice, ma non sono sicuro di dove metterle. Ecco il mio codice finora:OpenGL gluLookAt() non funziona come previsto
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++;
}
L'idea è che sto mantenendo un deque globale allpoints
che include i punti di controllo della spline ei punti interpolati. Una volta completato, chiamo update()
ogni 50 ms e spostiamo la fotocamera lungo ciascun punto in allpoints
. In una versione precedente del progetto, ho potuto vedere che le montagne russe venivano disegnate correttamente. È gluLookAt()
che non sembra funzionare come voglio. Con il codice sopra, il programma inizia con la telecamera guardando un lato dello skybox con una parte delle montagne russe, e quindi quando viene chiamato lo update()
, le montagne russe scompaiono ma la telecamera non si muove. Ho lavorato con le funzioni della matrice OpenGL e, a seconda di dove sono a volte, update()
causerà anche uno schermo vuoto.
Scusa, il 'glPopMatrix()' si trova alla fine del codice skybox, prima delle montagne russe (dato che non includevo il codice skybox, è per questo che l'ho dimenticato nella domanda) - è dove dovrebbe andare, o dovrebbe essere dopo il disegno delle montagne russe? –
@Logan Mentre il flusso di controllo può essere lo stesso in fase di esecuzione, 'glPopMatrix' dovrebbe essere nello stesso scope di' glPushMatrix', poiché entrambi rappresentano un'unità e dovrebbero sempre venire in coppia. –
Voglio dire, dovrebbe 'glPopMatrix()' essere dopo il codice skybox commentato (prima che rc sia disegnato con 'glVertex3f') o dopo il ciclo per disegnare il rc con' glVertex3f'? –