Registriert: Mi Jul 15, 2009 20:48 Beiträge: 111 Wohnort: Berlin
Programmiersprache: Delphi,JS,PHP,AS3,C#
Hi^^
Folgendes: Ich hab gestern vor der Arbeit Zeit gefunden, an meinem Spiel weiter zu basteln, da ist mir etwas seltsames passiert.
Ich verwende in meinem Spiel mehrere Arrays des Ur-Objects meines Spiels, TSSObject. In diese Listen schreiben sich meine Objecte im Create rein, wenn sie von der Renderprocedur erfasst werden wollen (meine Objekte rendern sich nicht "selbst"). Da gibs die VisList, die Quads etc malt, und andere Listen, u.a. die BlendList. "List" ist jetzt sicherlich etwas verwirrend, das hat nichts mit Displaylisten zu tun, unpassender Name, ich denk mir heute noch was neues aus!^^ Ist das Object also in der BlendList angekommen, wird es in der Schleife in der Renderprozedur gerendert. Ich hab die VisList erfolgreich implementiert, und es gab keine Probleme. Copy-Paste, umschreiben auf Blending. Nun passiert aber Folgendes: In meinen Viewport passt genau meine Map, die aus der Vogelperspektive betrachtet wird. sie ist 55 x 31 OGL-Einheiten groß. Wenn ich nun mein Object an der Stelle (7,7,0) spawne, wird es aber ca bei Feld (14,14,0) gerendert... :/ hmmm jetzt könnte man denken AHAAA irgendwo nicht richtig gescalet? Ich rufe im gesammten Spiel glScalef nur mit Einsen und Minus-Einsen auf. es ist mir also ein Rätzel wieso das Objekt flasch angezeigt wird. Mir ist aufgefallen, dass die Map in Blending-Einheiten nur etwa halb so groß ist... also ein glScalef(0.5,0.5,0.5) eingebaut, und alles ist viiiel besser. Ich setz beim Rendern meine Modelmatrix auf den Mittelpunkt des zu rendernden Objekts, komsicher weise kann ich die letzte Verschiebung nur aufheben, wenn ich sie an den unteren rechten Punkt setze... öööööh... alles klappt.... was ist hier bitte los??? Ich vermute hier ist das glScalef(0.5,0.5,0.5) dran schuldt, aber Moment, beim normalen Matrix setzen ist das auch kein problem... Ich schäme mich oft für meinen Quelltext, da ich vermutlich viel suboptimal mache, aber ich lass euch heute mal dran teilhaben...^^
Code:
procedure TSSEngine.DrawBlend;
var i,k:integer;
begin
glEnable(GL_BLEND);
glDepthFunc(GL_ALWAYS);
for k :=0toHigh(BlendList)do
begin
i:=High(BlendList)-k;{rückwärts durchgehen, kannte heute morgen "downto" statt "to" noch nicht... soviel dazu!}
if BlendList[i]=nilthen{wenn objekt nicht vorhanden, gucken obs das letzte in der liste ist und dann einfach löschen ansonsten das letzte an die stelle setzen und dann array kürzen}
begin
if i=High(BlendList)then
SetLength(BlendList,High(BlendList))else
begin
BlendList[i]:=BlendList[High(BlendList)+1];
SetLength(BlendList,High(BlendList))
end;//siehe oben
endelse
begin//los gehts mit dem rendern
glMatrixMode(GL_MODELVIEW);
glPushMatrix;
glLoadIdentity;//sollte hier nciht schon das sclaing resetet sein???
glScalef(0.5,0.5,0.5);//stranges glScalef....
glTranslatef(BlendList[i].Position.XR+(BlendList[i].Size.XR),BlendList[i].Position.YG+(BlendList[i].Size.YG),BlendList[i].Position.ZB);//Size nicht halbiert....
Ich rekonstruiere mal, wie es nciht geklappt hat... die geänderten Zeilen:
Code:
//glScalef(0.5,0.5,0.5); ausgekommentiert
glTranslatef(BlendList[i].Position.XR+(BlendList[i].Size.XR/2),BlendList[i].Position.YG+(BlendList[i].Size.YG/2),BlendList[i].Position.ZB);{Size halbieren, wie es für mich sin machen würde!}
Hilfe!! Alles funktioniert, aber so unschön.. ich will wissen, was abgeht!^^
Kann jemand erahnen wo das Problem liegen könnte???
_________________ thanks to the internet we have rule 34, wich states that if something exists, theres a pornographic version of it,
es würde unter Umständen helfen, wenn du auch mal die Procedure für das Zeichnen der nicht geblendeten Objekte posten würdest. Sonst sehe ich ja keinen Unterschied. ^^
Und ja, das glLoadidentity setzt die Modell-View-Matrix zurück. Fuschst du etwas in der Projection-Matrix rum? Die wird ja mit verrechnet. Auch könnte es sein, dass alles richtig ist, aber wenn sich das Objekt selbst einträgt, trägt es sich falsch ein? Vielleicht ist "BlendList[i].Position.XR" schont falsch gespeichert?
_________________ Denn wer nur schweigt, weil er Konflikte scheut, der macht Sachen, die er hinterher bereut. Und das ist verkehrt, denn es ist nicht so schwer, jeden Tag zu tun als ob's der letzte wär’. Und du schaust mich an und fragst ob ich das kann. Und ich denk, ich werd' mich ändern irgendwann. _________________Farin Urlaub - Bewegungslos
Registriert: Do Jul 23, 2009 04:33 Beiträge: 157
Programmiersprache: Turbo Delphi Pro
Was da genau abgeht kann ich dir nicht sagen, auch weil meine eigenen OpenGL Kenntnisse da noch nicht reichen ^^, aber trotzdem ein Hinweis: BlendList scheint ein dynamsiches Array zu sein. Du könntest stattdessen ein TList-Objekt verwenden, das hat den Vorteil dass man Elemente einfach mit TList.add einfügen und mit TList.delete entfernen kann. Elemente die nil sind kann man mit TListe.pack automatisch bereinigen lassen. Damit kannst du deinen Code vielleicht etwas eleganter Formulieren. Wie gesagt mit dynamischen Arrays gehts auch, aber mit Listen kann man sich teilweise Code sparen. (Ausserdem sind dynamische Arrays in einigen Delphi-Versionen buggy und laden den Speicher voll aber das nur am Rande).
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen. (Koreanisches Sprichwort)
rufe ich einmal auf wenn die map geladen wird. wie gesagt, nur einsen und minus-einsen und ich sehe bei einsen wirklich keine chance es zu verkacken^^
das array ist ein array of TSSObject, und wird dann mit "BlendList[1]:=BeispilObjekt;" wobei BeispielObjekt natürlich schon "Create" erfahren hat, weil es sich ja genau dann einschreibt.
alle zeichenprozeduren aufzählen??.. kleinen moment.
zur TList: Ich hab schon früher dynamische arrays verwendet und sehe kaum einen vorteil bei einer liste. mit dem einschreiben und austragen hab ich keine probleme, und so hab ich auf jedenfall nichts unnötiges an prozeduren dabei. natürlich weiß ich nciht was schneller ist, aber so ist es sehr einfach eig.^^ danke trozdem für den tipp.
edit - grad nochmal getestet: der fehler trifft auch auf, wenn ich nichts außer blendeffekten rendere.
_________________ thanks to the internet we have rule 34, wich states that if something exists, theres a pornographic version of it,
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
hast du schoneinmal überlegt nicht beim scalef sondern beim translatef zu suchen? Es könnte ja sein, dass du die bewegung/verschiebung deiner Objekte doppelt in die Matrix rechnest und dadurch die doppelten Werte entstehen. Das glscalef kann das natürlich wieder rückgängig machen, aber sollte es an einem doppelten translatef aufruf liegen sollte eher dieser doppelte aufruf verschwinden.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Ja das finde ich auch. Es geht hier nicht um das Skalieren, sondern um das grundlegende Verständnis für den Prozess. Daher konzentrieren wir uns mal auf den relevanten Code, nämlich der, der am verdächtigsten ist: das Verschieben und Rotieren:
(BlendList[i].Size.YG),BlendList[i].Position.ZB);//Size nicht halbiert....
glRotatef(BlendList[i].BlendRotation.XR,1,0,0);
glRotatef(BlendList[i].BlendRotation.YG,0,1,0);
glRotatef(BlendList[i].BlendRotation.ZB,0,0,1);
Mit Verlaub, Du rotierst und verschiebst hier ziemlich viel. Du hast einen Hinweis gegeben, dass dein OpengL Kenntnisse noch nicht gefestigt sind. Ist Dir bewusst, dass alle diese Translationen und Rotationen in genau der umgekehrten Reihenfolge erfolgen, wie Du sie hineingeschrieben hast? Zum Beispiel der Code für die ModelView Matrix beginnt mit der Rotation um die Z-Achse, arbeitet sich über die Y und X-Achse weiter vor und verschiebt erst zuletzt? Und nachher kommen erst die Verschiebungen und zusätzlichen Rotationen, die Du für die Projektionsmatrix vorgesehen hast.
Das Scalef kannst Du getrost weglassen. Das macht es nur falscher, nicht richtiger.
Ich an Deiner Stelle würde das ganze erst mit einem ganz einfachen Testprogramm und einem Quad probieren, am besten ein texturiertes Quad, da weiß man dann gleich auch, ob links/rechts/oben/unten stimmt. Ich mache das immer so. Bei einem umfangreicheren Programm verliert man schnell den Blick fürs Wesentliche. Und ich würde zunächst mal alle Modelview-Transformationen beieinander lassen, denn es kann ganz leicht passieren, dass man die im Fehlerfall einfach vergisst und beim Herummurksen macht man dann mehr Fehler rein als vorher drin waren (ich spreche aus eigener Erfahrung ).
Dann die erste Transformation hinzufügen. Wenn man mit dieser zufrieden ist (was heißt zufrieden - man muss 100% sicher sein), die zweite Transformation VOR die erste Transformation setzen, und so weiter, bis man alles durch hat.
Viele Grüße
Traude
EDIT: habe grade noch etwas gesehen:
Zitat:
//sollte hier nicht schon das scaling resetet sein???
Ich weiß jetzt nicht, auf welches Scaling sich diese Frage bezieht, denn Du hast zwei, eine bei der Projektions- und auch eine bei der Modelview-Matrix. Aber eigentlich ist es egal. Ein glLoadIdentitiy direkt nach dem Setzen eines Modus bezieht sich immer auf die Matrix des jeweiligen Modus und wird vor allen anderen Transformationen ausgeführt. Die Antwort auf diese Frage lautet einfach: "Nein".
Registriert: Mi Jul 15, 2009 20:48 Beiträge: 111 Wohnort: Berlin
Programmiersprache: Delphi,JS,PHP,AS3,C#
Traude hat geschrieben:
EDIT: habe grade noch etwas gesehen:
Zitat:
//sollte hier nicht schon das scaling resetet sein???
Ich weiß jetzt nicht, auf welches Scaling sich diese Frage bezieht, denn Du hast zwei, eine bei der Projektions- und auch eine bei der Modelview-Matrix. Aber eigentlich ist es egal. Ein glLoadIdentitiy direkt nach dem Setzen eines Modus bezieht sich immer auf die Matrix des jeweiligen Modus und wird vor allen anderen Transformationen ausgeführt. Die Antwort auf diese Frage lautet einfach: "Nein".
In meiner kleinen Welt hat glLoadIdenty den Effekt, dass die zuvor ausgewählte Matrix resetet wird. oO Ich les nachher mal was dazu, habe grade kaum Zeit.
Die doppelte Matrixtransformation ist eine gute Idee, die hatte ich noch nicht. Wobei ich nicht weiß wo das geschehen soll oO Immerhin rufe ich vor jeder Transformation DIREKT glLoadidentity auf. Aber wie gesagt, mein Bild vom Effekt dieses Aufrufs scheint falsch zu sein. Naja, danke für die Hilfe
_________________ thanks to the internet we have rule 34, wich states that if something exists, theres a pornographic version of it,
Registriert: Fr Jan 04, 2008 21:29 Beiträge: 419 Wohnort: Lübeck
ganz falsch ist es nicht. GlLoadIdentity setzt die aktuelle Matrix auf die EinheitsMatrix, die quasi ein unverändertes Koordinatensystem darstellt. Die Transformationsaufrufe sorgen dann für weitere Modifikation des Koordinatensystems. Evtl. solltest du nicht immer GlLoadIdentity benutzen, sondern zunächst deine Grundausrichtung der Szene gestalten und anschließend alle Objekttransformationen in glPushMatrix und glPopMatrix einkreisen. Diese Methode ist nicht unbedingt die günstigste, aber dafür eine sehr wirkungsvolle.
Registriert: Di Okt 03, 2006 14:07 Beiträge: 1277 Wohnort: Wien
Zitat:
In meiner kleinen Welt hat glLoadIdenty den Effekt, dass die zuvor ausgewählte Matrix resetet wird.
Manchmal ist es schwer, etwas so rüberzubringen, dass es so ankommt, wie es gemeint ist. Vor allem hier, weil ich jetzt nicht genau weiß, was Du mit "zuvor ausgewählte Matrix" meinst.
Wenn Du damit die Modelviewmatrix des vorigen Frame (= des vorigen Zeichenvorgangs) meinst, dann hast Du recht, dass glLoadIdentity das glScalef "wegputzt". Es putzt aber auch alle anderen Transformationen des letzten Zeichenvorgangs weg. Wenn man glLoadIdentity benutzt, beginnt man immer ganz von vorn (das ist der übliche Weg). glLoadIdentity ist Dein Freund.
Wenn Du damit die Projektionsmatrix des gleichen Frame meinst, dann ist das nicht so. In einem Frame sind beide glScalef aktiv, sowohl das glScalef(1,-1,1), das bei der Projektionsmatrix steht, als auch das glScalef(0.5,0.5,0.5), das bei der ModelviewMatrix steht. Das meinte ich vorher.
Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.