Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 07:58

Foren-Übersicht » Programmierung » OpenGL
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Problem mit Skalierung
BeitragVerfasst: Mi Jun 22, 2005 08:57 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Tach,

leute ich bin ziemlich am verzweifeln momentan.
Wie manche vielleicht wissen arbeite meine firma an einem "Führerstand" (Bahn) Simulator.
Mein teil ist der komplette Renderpart.

Wir haben einen Streckenfilm mit ca. 40000 Bilder im JPEG Format.
Diese sind gespeichert in einem Binären file wo vorher noch nen header und ne Index table schlummert.
Dieser wird geladen und ein neues bild in jedem neuem renderschritt geladen, tut einwandfrei ;)
Danke mal an die mir tips gegeben haben !

Was noch dazu kommt: Alle Signale müssen durch eigene ersetzt werden.
Sprich die Lampenstellung muss zur Laufzeit geändert werden können.

Das haben wir folgendermassen gelösst:

Ich hab via opengl, alle Signaltypen nachgezeichnet und die grundform in ne Displayliste verfrachtet.
Beim zeichnen werden dann noch Kreise für die Lampen welche ich über einen einfachen algo erzeuge dazugezeichnet.
So wird die grundform erstellt:

Code:
  1.  
  2. var
  3.   Punkte : array of TVector2d;
  4.   I      : Integer;
  5.   TX, TY : Single;
  6. begin
  7.   // VSW Signal (vorsignal wiederholung)
  8.   SetLength(Punkte, 4);
  9.   Punkte[0] := CreateVector2d(0, 58);
  10.   Punkte[1] := CreateVector2d(0, 0);
  11.   Punkte[2] := CreateVector2d(36, 0);
  12.   Punkte[3] := CreateVector2d(36, 58);
  13.  
  14.   TexcoordCalc(Punkte, TX, TY);
  15.  
  16.   VSWList := glGenLists(1);
  17.   glNewList(VSWList, GL_COMPILE);
  18.     glBegin(GL_LINE_LOOP); // GL_LINE_LOOP nur zu testzwecken !
  19.       for I := Low(Punkte) to High(Punkte) do
  20.       begin
  21.         glTexcoord2f(TX * Punkte[I].X, TY * (Punkte[I].Y - 58));
  22.         glVertex2d(Punkte[I].X, Punkte[I].Y - 58);
  23.       end;
  24.     glEnd;
  25.   glEndList;
  26. end;
  27.  


gezeichnet wird es dann so:

Code:
  1.  
  2. procedure DrawCircle(X, Y : Double; Radius : glfloat; Segments : Integer);
  3. const
  4.   TWO_PI = PI * 2;
  5. var
  6.   arc,
  7.   theta,
  8.   nx,
  9.   ny    : Single;
  10. begin
  11.   arc := TWO_PI / Segments;
  12.   glBegin(GL_POLYGON);
  13.     theta := 0;
  14.     while theta < TWO_PI do
  15.     begin
  16.       nX := X + (Sin(theta) * Radius);
  17.       nY := Y + (Cos(theta) * Radius);
  18.       glVertex2f(nX, nY);
  19.       theta := theta + arc;
  20.     end;
  21.   glEnd;
  22. end;
  23.  
  24. procedure Signal_VSW(X, Y : Double; Scale : Double; Farben : array of TRGB);
  25. const
  26.   SignalHeight = 58;
  27. begin
  28.   glPushMatrix;
  29.     glTranslated(X, Y, 0);
  30.     if ESignalRatioScaled then glScaled(VideoRatio1, VideoRatio2, 0); // Original Video ist 720x576, gestreckt wirds aber via OpenGL auf 1024x768, man sollte also auch die ratio dazustecken :P
  31.     glScaled(Scale, Scale, 0);
  32.  
  33.     glColor3f(1, 1, 1);
  34.     glEnable(GL_TEXTURE_2D);
  35.     //glLineWidth(2);
  36.     glCallList(VSWList);
  37.     //glLineWidth(1);
  38.     glDisable(GL_TEXTURE_2D);
  39.  
  40.     if Length(Farben) = 2 then
  41.     begin
  42.       glColor3ub(Farben[0].R,Farben[0].G,Farben[0].B);
  43.       DrawCircle(10, 48 - SignalHeight, 5, 16);
  44.       glColor3ub(Farben[0].R,Farben[0].G,Farben[0].B);
  45.       DrawCircle(26, 24 - SignalHeight, 5, 16);
  46.     end;
  47.   glPopMatrix;
  48. end;
  49.  


ok soweit so gut, nun damit das ganze natürlich realistischer wirkt müssen die signale auch über die originalen Signale im jpeg movie drübergelegt werden.

Damit ich nicht in jedes einzelne bild, die X, Y Koordinate speichern muss hab ich mir nur pro Signal 8 Punkte rausgesucht (Startpunkt, Endpunkt und 6 zwischenpunkte) (Bildnummern) welche ich dann KoEffizienten für ein (8-Faches Polynom berechne) die daten liegen in ner excel tabelle welche ich beim start auslese.

Das wird dazu verwendet um die aktuelle Left, Top Position aus der aktuellen Bildnummer ausrechnen, welches ganz gut klappt, sofern man gute Zwischenpunte gewählt hat, ansonsten kanns passieren das die Signale sonst wo sind :p

Jetzt kommt wo ich probleme habe und das ist der Skalierungspart.
Sprich damit die Original Signale die anderen überdecken müssen die "Kunst" Signale genau drüber gelegt werden und gleich skaliert sein.

Hab dazu also den StartPunkt und den Endpunkt (Bildnummern) genommen und mir daraus zwei skalierungsfaktoren ausgesucht, bsp: 0,04 wenns grad zu erscheint, und 1,2 wenns verschwindet.
Daraufhin hab ich mir ne Geradengleichung gemacht wie aus der Bildposition, BildAnfang und BildEnde den jetzigen Skalierungsfaktor.
Die werte die rauskommen scheinen ok zu sein, allerdings skaliert er ein bischen komisch :(

Hier sind paar screenshots zur verdeutlichung:

Man beachte die Roten umkreisung
Man beachte den NScale wert Links Unten, welches den aktuellen Skalierungsfaktor enthält

Signal wo es grad sichtbar wird ohne Eigenes drübergelegt
Bild

Signal wo es verschwindet ohne Eigenes drübergelegt
Bild

Signal wo es grad sichtbar wird mit Eigenem drübergelegt
Bild

Signal wo es verschwindet mit Eigenem drübergelegt
Bild

Bisher scheint alles ok zu sein, nun kommen 2 Bilder wo dazwischen liegen:

Bild

Bild


Totale muckenkotze, da passt hinne und vorne nix...
Was ist da faul ?
Hat wer ne idee wie man das geschickter lösen könnte, so das die Skalierung immer stimmt ?


Was später dann noch dazukommt, ist nen Fragment Shader für Unschärfe je nachdem wie nah/weit das signal ist, weil momentan siehts so aus wie nen böser fremdkörper der absolut nicht in den Film passt.
Das kommt aber wirklich erst wenn das Oben alles so passt, vorher nicht.



Danke schonmal fürs lesen,
und freue mich auf antworten



Hätte keine probleme mal den src zu posten da der Videopart eh nix weltbewegendes ist :p
Allerdings ohne Streckenfilm welcher 2,9 GB hat, hat das nicht viel sinn.[/b]


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 22, 2005 09:51 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Wow. Das ist ja auch mal ein nicht leichtes Problem. Ich bin zwar nicht so der Freak was Gleichungen angeht aber ich denke mal nicht, dass du mit einer linearen Gleichung dort so sonderlich gut hinkommen wirst. Zum ersten weil die Strecke nun mal meist in Kurven liegt und weil je nach Entfernung des Signals dessen Geschwindigkeit und Größe stetig zu nimmt. Also am Ende wird es am schnellsten bewegt und am schnellsten skaliert. Ich weiß nicht ob die Auflösung die du da hast ausreicht. Weil du auch ungleichmäßige abstände bräuchtest und somit unterschiedliche zeitabstände hättest.

Zusätzlich käme auch noch eine perspektive Verzerrung wenn sich der Winkel dazu ändert. Aber das kann man wohl außer acht lassen.

Ich persönlich würde diese Informationen wahrscheinlich pro Bild abspeichern. Und zwar so, dass man das vorherige abgespeicherte dann mit in das einfließen lassen kann. Sprich ich habe bei Bild 20 die Elemente gesetzt und bei Bild 21 sehe ich die Position von 20 noch und kann diese entsprechend an die des Bildes 21 anpassen. So kann man ein wenig vermeiden, dass da 1 oder 2 Bilder dabei sind die von der Position echt weit vom Rest entfernt sind. Das ist zwar mehr arbeit aber so dürfte das Ergebniss am genauesten sein. Allerdings könnte es sein, dass die dennoch unruhig wirken. Evtl könnte man das per Algo noch ein wenig beruhigen.

Zitat:
Was später dann noch dazukommt, ist nen Fragment Shader für Unschärfe je nachdem wie nah/weit das signal ist, weil momentan siehts so aus wie nen böser fremdkörper der absolut nicht in den Film passt.

Da hast du recht. Die wirken ein wenig Fremd. Aber das mit dem Shader halte ich für eine ziemlich schlechten Idee, wenn ich ehrlich bin. Verstehe das nicht falsch aber das ist wirklich wirklich wirklich ein mega Bombe auf die auf ne super kleine Mücke geschossen wird. Schon mal daran gedacht für so etwas eine Textur zu nehmen. Die kannst du doch mittels Alphakanal am Rand weich machen. Kombiniert mit Blending sollte das dein Probleme mit der Unschärfe lösen. Außerdem kannst du dann so auch noch eine echte Lampe nehmen und der Realismuseffekt dürfte wesentlich höher sein als mit jedem Shader. Der im übrigen mehr an Rechenleistung fressen dürfte als ein Quad mit ner Textur.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 22, 2005 09:59 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Zitat:
Daraufhin hab ich mir ne Geradengleichung gemacht wie aus der Bildposition, BildAnfang und BildEnde den jetzigen Skalierungsfaktor.


Bedeutet das, dass der skalierungsfaktor linear mit der Zeit (und demnach auch etwa Z-Wert) zusammen hängt? Dem ist nämlich nicht so. Die Größe eines Objektes ist indirekt Proportional zu seiner Entfernung, also
Größe = Wirkliche_Größe / Entfernung
Also wenn es in 10 Einheiten Entfernung 20 Pixel groß ist, dann ist es in 100 Einheiten Entfernung 2 Pixel groß.

Und wie Lossy eX schon erwähnt hat wundert es mich auch etwas, dass du bei den ~ 40-100 KB die du je Bild brauchst nicht nocht genug Platz für die ~10 Byte eines Lichtleins hast. Und selbst wenns zum editieren durch das Angeben von nur 8 Positionen etwas einfacher geht so stellt sich mir doch die Frage wieso du nicht beliebig viele Positionen angeben kannst, vor allem wenn das Lichtlein dann öfter als 6 mal auftaucht und wieder verschwindet weil es von irgendwas verdeckt wird. Du brauchst ja dann auch kein x-beliebig Gradiges Polynom wenn du die Abschnitte unterteilst wie mans halt bei Splines und so macht.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 22, 2005 10:53 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Also,

das mit ner Linearen Geraden gleichung nicht geht war mir klar aber der Prof meint das wäre so korrekt -.-
Sein lautsatz war "Das liegt 100pro an OpenGL, das skaliert nicht richtig, mit ner Geraden Gleichung muss es gehen".

Es muss doch irgendwie möglich sein ne gescheite Skalierungsroutine zu bauen, welche aus dem 8 Punkten die ich eh immer habe den Skalierungsfaktor berechnet ohne dieses beschissene Polynom zu nehmen.

Zitat:
Bedeutet das, dass der skalierungsfaktor linear mit der Zeit (und demnach auch etwa Z-Wert) zusammen hängt?


Ich rechne nicht mit Zeit, sondern nur mit der aktuellen-, start- und endbildnummer.
Es läuft nen sehr komplexes steuersystem auf nem anderen rechner welche mir daten via TCP/IP schickt welche ich daraus nen Faktor ausrechne um zu wissen welche Bildnummer alle 40 ms kommen muss.

Z Achse gibts nicht, da ich von Anfang an alles auf glOrtho also 2D ausgerichtet habe.

Also wenn ich für jedes Signal zu jedem einzelnen Bild die Positionen und Skalierung speichern würde, wäre das sehr zeit aufwendig. Bei 40000 bilder, also effektiv mit signalen 30000 bilder gehts noch... aber wir wollen ja später grössere Filme machen, die dann auch mal 1-2 std fahrt sind anstatt 5 min :p und das sind dann halt mal nen paar x-mio bildern.

Zitat:
Schon mal daran gedacht für so etwas eine Textur zu nehmen. Die kannst du doch mittels Alphakanal am Rand weich machen.


Jop, da wir aber hier ne GF 6800 GT mit nem schnellem P4 haben kann ich da ruhig auf PixelShader setzten.
Werd aber beides mal ausprobieren.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 22, 2005 12:58 
Offline
DGL Member
Benutzeravatar

Registriert: Di Dez 02, 2003 12:47
Beiträge: 300
Wohnort: Marburg
Wie wäre es, wenn du für die Skalierung ausser Start und Endwehrt auch noch zwischenpunkte machst und nen Polynom draus, wie bei den Positionen??? (Vielleicht genügen da ja weniger zwischenpunkte um Aufwand zu sparen)

P.s. Ich hoffe das hat noch niemand gesagt, habe gerade wenig Zeit :-)

_________________
Nothing, oh sweet nothing,
today we are doing nothing at all...
http://www.geo-progs.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 22, 2005 13:22 
Offline
DGL Member

Registriert: Mi Okt 16, 2002 15:06
Beiträge: 1012
Jop, hab grad das mit dem Polynom gemacht, geht einwandfrei ;)
Hätte ich gleich drauf kommen können. :p

Das gleiche mach ich ja auch für Left und Top Position vom Signal ;)

Jetzt kommt dann wirklich nur noch das mit der Unschärfe/Verwischung dazu.

Aber erst muss der Chefs absegnen.

Ne frage noch:

Hat wer ne ahnung von Polynomen ?
Ich hab nicht wirklich viel ahnung davon, weil der Prof das ja gemacht hat in Excel :(
Daraus werden 8 Koeffezienten berechnet, welche ich dann über diese Formel die Richtige Left, Top und jetzt auch
Skalierungswert berechne:

Code:
  1.  
  2. procedure KoEff(const ArrX, ArrY, ArrS : array of Double; const BildNr, AnfangNr, EndNr : Integer; var X, Y, Scale : Double);
  3. var
  4.   IKX : Double;
  5. begin
  6.   if EndNr - AnfangNr <= 0 then Exit; // Div by zero anfangen
  7.   IKX := (BildNr - AnfangNr) / (EndNr - AnfangNr);
  8.   X := ArrX[0] + (IKX) * (ArrX[1] + (IKX) * (ArrX[2] + (IKX) * (ArrX[3] + (IKX) * (ArrX[4] + (IKX) * (ArrX[5] + (IKX) * (ArrX[6] + (IKX) * ArrX[7] ))))));
  9.   X := X * 100; // Faktor welches es erhöht werden muss
  10.   Y := ArrY[0] + (IKX) * (ArrY[1] + (IKX) * (ArrY[2] + (IKX) * (ArrY[3] + (IKX) * (ArrY[4] + (IKX) * (ArrY[5] + (IKX) * (ArrY[6] + (IKX) * ArrY[7] ))))));
  11.   Y := Y * 100; // Faktor welches es erhöht werden muss
  12.   Scale := ArrS[0] + (IKX) * (ArrS[1] + (IKX) * (ArrS[2] + (IKX) * (ArrS[3] + (IKX) * (ArrS[4] + (IKX) * (ArrS[5] + (IKX) * (ArrS[6] + (IKX) * ArrS[7] ))))));
  13. end;
  14.  


Muss ich mal erklären wie das bei uns abläuft bis überhaupt mal nen Signal erscheinen kann auf dem Bildschirm:

Startbild und Endbild wird gewählt für ein Signal, wos erscheint und verschwindet.
Danach werden 6 zwischenpunkte genommen davon, factor ist da (EndBild - StartBild) / 7.
Für alle 8 Punkte nun, wird der Signaltyp, Left, Top und Skalierungswert gesetzt und in eine eindeutige Binärdatei gespeichert. Pro Signal eine Datei.

Dann werden diese Binärdateien über ein Seperates tool in ne Excel Tabelle konvertiert.

Über nen Makro werden dann diese Excel Daten in ne andere Excel Tabelle kopiert und die Polynome für die 8 Koeffzieten pro signal ausrechnet und in ne weitere tabelle gespeichert welche noch andere infos stehen.

Dann kommt nen weiteres tool, welches dann wiederrum diese Excel Daten in 1 Binärdatei konvertiert.
Das ist dann die Signaltabelle:

Code:
  1.  
  2.   TSignal = packed record
  3.     Nr         : Integer;
  4.     Name       : String[20];
  5.     Typ        : Byte;
  6.     BildAnfang,
  7.     BildEnde   : Integer;
  8.     KoEffX     : array [0..7] of Double;
  9.     KoEffY     : array [0..7] of Double;
  10.     KoEffScale : array [0..7] of Double;
  11.     Status     : Byte;
  12.   end;
  13.  


Am liebsten wäre wenn das alles über Delphi laufen würde, und kein einziger weg mehr über Excel und so.

Thx bisher für antworten ;)


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jun 22, 2005 15:53 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Es ist ein lineares Gleichungssystem welches es zu lösen gilt. Du hast 8 Gleichungen der Form
Xi = P7*(Ti^7) + P6*(Ti^6) + P5*(Ti^5) + ... + P1*(Ti) + P0
Wobei Xi der X-Wert zum Zeitpunkt (Frame) Ti ist, gleiches gilt für Y-Werte.
P0-7 sind die Polynomfaktoren.

Man könnte das auch in Matrixschreibweise machen indem du dir mal ne Matrix auf stellst mit
M =
T0^7 | T0^6 | ... | T0 | 1
T1^7 | T1^6 | ... | T1 | 1
...
T7^7 | T7^6 | ... | T7 | 1

Und die Ergebniswerte als Vektor anschreibst
V = ( X0, X1, X2, ... X7 )

Das Gleichungssystem kannst du jetzt sehen als
V = M * P
wobei P die Polynomfaktoren sind, also
P = (P7, P6, P5, ..., P1, P0)
du willst P wissen also musst du M invertieren um mit
(M^-1) * V = P zu erhalten

Ein kleines Rechenbeispiel:
Code:
  1. M =
  2.    0    |    0   |  0  | 1
  3. 0.33^3 | 0.33^2 | 0.33 | 1
  4. 0.66^3 | 0.66^2 | 0.66 | 1
  5.    1   |    1   |   1  | 1

Also die 4 "Zeit-"punkte wo du die Punkte gegeben hast. Die Punkte sind nun beispielsweise:
V = (1, 3, 0, 5)

Code:
  1. M invertiert =
  2. -4.59137 | 13.7056 | -13.504 | 4.38982
  3. 9.13682 | -22.7513 | 17.9604 | -4.34592
  4. -5.54545 | 9.04568 | -4.45633 | 0.956102
  5.    1     |   0     |   0     | 0
  6.  

und
P = M * V = (77.106, -117.657, 42.5513, 1)

Nun weißt du das dein Polynom so ausschaut:
x = 77,106 * t^3 - 117,657 * t^2 + 42,5513 * t + 1


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 7 Beiträge ] 
Foren-Übersicht » Programmierung » OpenGL


Wer ist online?

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.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 15 Queries | GZIP : On ]