OpenGL: skalieren dann übersetzen? und wie?

Ich habe eine 2D-Geometrie. Ich möchte eine Begrenzungslinie um meine Geometrie ziehen und dann eine kleinere Version davon an einer anderen Stelle in der Ebene rendern. Hier ist mehr oder weniger der Code, den ich skalieren und übersetzen muss:

// source and dest are arbitrary rectangles.
float scaleX = dest.width / source.width;
float scaleY = dest.height / source.height;
float translateX = dest.x - source.x;
float translateY = dest.y - source.y;

glScalef(scaleX, scaleY, 0.0);
glTranslatef(translateX, translateY, 0.0);
// Draw geometry in question with its normal verts.

Dies funktioniert für eine bestimmte Dimension genau wie erwartet, wenn der Zielursprung 0 ist. Wenn jedoch der Ursprung für beispielsweise x ungleich Null ist, wird das Ergebnis weiterhin korrekt skaliert, sieht jedoch so aus, als ob (?) Es auf dieser Achse in einen Wert nahe Null übersetzt wird Sowieso - es stellt sich heraus, dass es nicht genau das gleiche ist, als ob dest.x Null wäre.

Kann jemand auf etwas hinweisen, das ich vermisse?

Vielen Dank!

ENDGÜLTIGES UPDATE Nach den Antworten von Bahbar und Marcus habe ich noch ein wenig experimentiert und dieses Problem gelöst. Adam Bowens Kommentar war der Hinweis. Mir fehlten zwei kritische Fakten:

Ich musste um die Mitte der Geometrie skalieren, die mir am Herzen lag.Ich musste die Transformationen in der entgegengesetzten Reihenfolge der Intuition anwenden (für mich).

Das erste ist im Nachhinein offensichtlich. Aber für letztere, für andere gute Programmierer / schlechte Mathematiker wie mich: Es stellte sich heraus, dass meine Intuition darin bestand, was das zu tun hatteRotes Buch Ruft ein "Grand, Fixed Coordinate System" auf, in dem es eine absolute Ebene gibt, und Ihre Geometrie bewegt sich mithilfe von Transformationen auf dieser Ebene. Dies ist in Ordnung, aber angesichts der Art der Mathematik, die hinter dem Stapeln mehrerer Transformationen in eine Matrix steckt, ist es das Gegenteil von der tatsächlichen Funktionsweise (siehe Antworten unten oder Red Book für weitere Informationen). Grundsätzlich werden die Transformationen in "umgekehrter Reihenfolge" auf die Darstellung im Code "angewendet". Hier ist die endgültige Arbeitslösung:

// source and dest are arbitrary rectangles.
float scaleX = dest.width / source.width;
float scaleY = dest.height / source.height;
Point sourceCenter = centerPointOfRect(source);
Point destCenter = centerPointOfRect(dest);

glTranslatef(destCenter.x, destCenter.y, 0.0);
glScalef(scaleX, scaleY, 0.0);
glTranslatef(sourceCenter.x * -1.0, sourceCenter.y * -1.0, 0.0);
// Draw geometry in question with its normal verts.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage