Ich arbeite ja im Moment sehr fleißig an meiner Grafikengine. Ein Problem über dass ich stolperte, erinnerte mich wieder daran wie wichtig es ist über die Sprache und die Bibliotheken mit denen man arbeitet Bescheid zu wissen. Diese Erfahrung möchte ich euch natürlich nicht vorenthalten 🙂
Schauen wir uns mal folgenden Versuchsaufbau an:
class Drawable{
public:
float position3f[3];
}
Irgendwo rufe ich nun auf: glLightfv(GL_LIGHT+light.index,GL_POSITION,light.position), wobei light natürlich von Drawable abgeleitet wird.
Das alles funktioniert so lange, wie ich den Code nicht folgendermaßen erweitere:
class Drawable{
public:
float position3f[3];
bool active;
}
Die Änderung führt dazu dass die OpenGL-Beleuchtung nicht mehr funktioniert. Idee warum?
Ein kleiner Tipp: Die Beleuchtung funktionierte wieder wenn ich active vor position deklariere.
Gelöst? Nicht schlimm, auch ich kam nicht auf Anhieb darauf.
Die Lösung des Ganzen erfordert Hintergrundwissen sowohl in OpenGL als auch in Speicherverwaltung:
- OpenGL arbeitet wenn es um Positionierung (= Verschiebung) geht mit affinen Abbildungen (3×3 Matrix + Verschiebung), was durch die Nutzung von 4×4 Matrizen umgesetzt wird. Jetzt schnackelts. Ich nutze einen Vektor mit 3 Komponenten, OpenGL will aber 4. Die Vierte (sogenannte w-)Komponente ist eigentlich überflüssig, kann aber als Flag genutzt werden(wie in diesem Fall). Ich gehe mal davon aus dass openGL auf irgendeine Art eine 0 aus dem bad-pointer machte, so genau will ich das gar nicht wissen.
- Die Variable position3f liegt auf dem Stack. Durch das übergeben des Pointers an glLightfv wurde für das vierte Element „ins Leere gegriffen“. Sicher warf dies irgendwo intern eine Exception, aber openGL verzichtet in solchen Fällen vollständig auf Funktionsrückgaben – Warum auch immer o.O
- Jedenfalls. Durch Erstellen einer zweiten Variable auf dem Stack war der Bereich nach der 3. Float-Komponente nicht mehr leer, ganz fatal: Er war sogar von einem anderen Datentyp belegt. Und OpenGL liefert keinen Fehlercode, nein, die ganze Beleuchtung schaltet sich einfach aus.
Ich behob das Ganze natürlich damit dass ich position um eins vergrößerte. Kudos an Prof. Hahn und Prof. Kriha für die 1A-Vorlesungen in dem Bereich. An solchen Fehlern wird man ohne eingehendes Wissen über Kompiler und Sprache verzweifeln. Darum mein Aufruf:
Leute guckt euch gut an mit was ihr arbeitet! Im Java-Sandkasten mag man sich austoben können, aber gerade in C hat man kaum eine Chance sauber zu programmieren, wenn man die Konzepte nicht versteht!
PS.: Bevor Missverständnisse aufkommen: C ist natürlich trotzdem (oder gerade deshalb) viel cooler als Java 🙂
2 Kommentare
Comments feed for this article
Dezember 28, 2008 um 5:47 pm
momo
Im Java Sandkasten, da krieg ich ja schon wieder fast nen roten Kopf. In meinen Augen macht das Problem das du beschreibst sehr deutlich wie nötig andere Ansätze für Sprachen sind. In diesem Fall gingen nur die Lampen aus, aber oft genug führt sowas zu massiven Sicherheitslöchern oder so. Das Problem ist ja nicht dass es mächtige Möglichkeiten gibt ( Pointerarithmetik ), sondern vielmehr dass die meisten Leute nen minimalen Plan haben wie die funktionieren. Und solang das so ist, und für die meisten Aufgaben andere Sprachen und Umgebungen ausreichende Ergebnisse liefern, hat sowas wie Java definitiv ne richtig fette berechtigung. Ansonsten wieder mal ein sehr interessanter Artikel!
Februar 3, 2011 um 7:29 pm
Vechie Kucker
Da frage ich mich beim groben Durchlesen schon, ob man nicht komplett auf den Kopf gefallen ist. Danke fur Ihre Einsichten