2017-11-19 1 views
1

Ich arbeite an einem 3D Platformer, wo eine große Plattform und ein Charakter aus mehreren Würfeln besteht.Wie rotiere ich diese Gruppe von Würfeln in ihrem Mittelpunkt?

Wenn ich jedoch versuche, die Y-Achse der Zeichenwürfel zu drehen, dreht sie diese nicht an ihrem Mittelpunkt. Sie umkreisen als ganzes die Plattform in einem riesigen Kreis. Ich nehme an, meine glRotatef's sind in der falschen Reihenfolge, aber ich kann nicht herausfinden, in welcher Reihenfolge sie sein sollten, um die Gruppe von Würfeln nur um ihren Mittelpunkt rotieren zu lassen.

Mein Code für deren Zeichnung ist:

for (int i = 0; i < Models.size(); i++){ // theres only one model this has to go through that stores the group of cubes for the character 
    glPushMatrix(); // set rotation for the whole group (I would expect...) 
    glRotatef(Models.at(i)->ModelRotation.X,1,0,0); 
    glRotatef(Models.at(i)->ModelRotation.Y,0,1,0); 
    glRotatef(Models.at(i)->ModelRotation.Z,0,0,1); 
    for (int j = 0; j < Models.at(i)->Parts.size(); j++) // For each cube in the character, 
     Models.at(i)->Parts.at(j)->Render(); // draw the cube 
    glPopMatrix(); 
} 

Modell ist eine Struktur, die nur ein vector3 namens „ModelRotation“ und einen Normalvektor „Teile“ genannt, die für den Charakter, alle Würfel speichert.

Meine Funktion Cube in der Cube-Klasse für die Darstellung ist:

void Render(){ 
    glPushMatrix(); 
    glTranslatef( Position.X, 
        Position.Y, 
        Position.Z 
    ); 
    glColor3f(  Color.R, 
        Color.G, 
        Color.B 
    ); 
    glScalef(  Size.X, 
        Size.Y, 
        Size.Z 
    ); 

    // Render the front quad 
    //glBindTexture(GL_TEXTURE_2D, Faces[0]); 
    glBegin(GL_QUADS); 
     glTexCoord2f(0, 0); glVertex3f( 1.0f, -1.0f, -1.0f); 
     glTexCoord2f(1, 0); glVertex3f(-1.0f, -1.0f, -1.0f); 
     glTexCoord2f(1, 1); glVertex3f(-1.0f, 1.0f, -1.0f); 
     glTexCoord2f(0, 1); glVertex3f( 1.0f, 1.0f, -1.0f); 
    glEnd(); 

    // Render the left quad 
    //glBindTexture(GL_TEXTURE_2D, Faces[1]); 
    glBegin(GL_QUADS); 
     glTexCoord2f(0, 0); glVertex3f( 1.0f, -1.0f, 1.0f); 
     glTexCoord2f(1, 0); glVertex3f( 1.0f, -1.0f, -1.0f); 
     glTexCoord2f(1, 1); glVertex3f( 1.0f, 1.0f, -1.0f); 
     glTexCoord2f(0, 1); glVertex3f( 1.0f, 1.0f, 1.0f); 
    glEnd(); 

    // Render the back quad 
    //glBindTexture(GL_TEXTURE_2D, Faces[2]); 
    glBegin(GL_QUADS); 
     glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, 1.0f); 
     glTexCoord2f(1, 0); glVertex3f( 1.0f, -1.0f, 1.0f); 
     glTexCoord2f(1, 1); glVertex3f( 1.0f, 1.0f, 1.0f); 
     glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, 1.0f); 
    glEnd(); 

    // Render the right quad 
    //glBindTexture(GL_TEXTURE_2D, Faces[3]); 
    glBegin(GL_QUADS); 
     glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, -1.0f); 
     glTexCoord2f(1, 0); glVertex3f(-1.0f, -1.0f, 1.0f); 
     glTexCoord2f(1, 1); glVertex3f(-1.0f, 1.0f, 1.0f); 
     glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, -1.0f); 
    glEnd(); 

    // Render the top quad 
    //glBindTexture(GL_TEXTURE_2D, Faces[4]); 
    glBegin(GL_QUADS); 
     glTexCoord2f(0, 1); glVertex3f(-1.0f, 1.0f, -1.0f); 
     glTexCoord2f(0, 0); glVertex3f(-1.0f, 1.0f, 1.0f); 
     glTexCoord2f(1, 0); glVertex3f( 1.0f, 1.0f, 1.0f); 
     glTexCoord2f(1, 1); glVertex3f( 1.0f, 1.0f, -1.0f); 
    glEnd(); 

    // Render the bottom quad 
    //glBindTexture(GL_TEXTURE_2D, Faces[5]); 
    glBegin(GL_QUADS); 
     glTexCoord2f(0, 0); glVertex3f(-1.0f, -1.0f, -1.0f); 
     glTexCoord2f(0, 1); glVertex3f(-1.0f, -1.0f, 1.0f); 
     glTexCoord2f(1, 1); glVertex3f( 1.0f, -1.0f, 1.0f); 
     glTexCoord2f(1, 0); glVertex3f( 1.0f, -1.0f, -1.0f); 
    glEnd(); 
    glPopMatrix(); 
}; 

Jede Hilfe sehr geschätzt würde. Ich vermute, es ist nur ein einfacher Fehler, den ich nicht zusammensetzen kann. Ich zeige mehr Code, wenn es benötigt wird.

Dank

+0

Bewegen Sie den 'glRotatef'-Operation in die' Render'-Funktion, nach der 'glTranslatef'-Operation – Rabbid76

+3

Mögliches Duplikat von [Rotieren eines mehrteiligen Objekts] (https://stackoverflow.com/questions/46720166/rotating-a-multipart-object) – Rabbid76

Antwort

0

Wenn Sie ein Objekt um seine lokale Achse drehen, die Sie haben den glTranslatef Betrieb vor dem glRotatef Betrieb zu tun:

void Render() 
{ 
    glPushMatrix(); 
    glTranslatef(Position.X, Position.Y, Position.Z); 
    glRotatef(ModelRotation.Y,0,1,0); 

    .... 

    glPopMatrix(); 
} 

Der glTranslatef und glRotatef Betrieb erstellen eine Übersetzung oder Rotationsmatrix und multipliziere die aktuelle Matrix auf dem Matrixstapel mit der neuen Translation oder Rotation.

Diese Bedeutung von glTranslatef von glRotatef gefolgt ist translate * rotate:

translate * rotate

Im Gegenteil glRotatef gefolgt von glTranslatef ähnlich ist rotate * translate:

rotate * translate

Siehe auch Rotating a multipart object

0

Die Art, wie OpenGL die Transformationen anwendet, ist von unten nach oben zwischen PopMatrix() und PushMatrix(), das ist die Umkehrung von der Art, wie Sie sie tatsächlich codieren.

In Ihrem Code, die Reihenfolge, in der Sie anrufen, wie diese umgedreht wird:

Rotatef(); 
Translatef(); 
Scalef(); 

Es sollte sein:

Translatef(); 
Rotatef(); 
Scalef(); 

Mit anderen Worten, immer als letzten übersetzen (Das bedeutet, dass Sie es in Ihren Code als die allererste Zeile nach der PopMatrix() einfügen), es sei denn, Sie haben einen guten Grund (einen bestimmten Grafikeffekt oder Szene Rendering), so dass Sie zuerst Skalierungs- und Rotationstransformationen anwenden und dann das Objekt in Weltkoordinaten übersetzen.

Für mehrteiliger Objekte drehen (wie Ihr Fall) sollten Sie vielleicht zweimal übersetzen, wie hier erklärt: Rotating a multipart object

So Ihr Code außerhalb des Würfels Klasse könnte so etwas wie:

for (int i = 0; i < Models.size(); i++){ 
    glPushMatrix(); 
    glTranslatef( 
     Models.at(i)->WorldPosition.X, 
     Models.at(i)->WorldPosition.Y, 
     Models.at(i)->WorldPosition.Z, 
    ); 
    glRotatef(Models.at(i)->ModelRotation.X,1,0,0); 
    glRotatef(Models.at(i)->ModelRotation.Y,0,1,0); 
    glRotatef(Models.at(i)->ModelRotation.Z,0,0,1); 
    for (int j = 0; j < Models.at(i)->Parts.size(); j++) 
     Models.at(i)->Parts.at(j)->Render(); // draw the cube 
    glPopMatrix(); 
} 
Verwandte Themen