Hio =)
Zuallererst, dies ist in erster Linie ein Projekt, das mir beim Lernen hilft. Bevor ich es begonnen hab wusste ich nicht mal wie man mit Matrizen rechnet =)
Bin gerade soweit, dass einfache Linien in einer Farbe und einem Alpha-Wert in 3d gezeichnet werden können. Die Matrix-Funktionen funktionieren soweit einwandfrei (Translation, Rotation, ViewAt, Inverse, ...).
Schritte um eine Linie zu zeichnen:
- Aufruf der Funktion mit den 3 Parametern $from, $to und $color (zb 0xaaffee11 - aa=alpha ffee11=rgb)
- Ermittle 2d Coordinaten von $from und $to
- Stutze die Linie (Crop)
- Ermittle Richtung der Linie und Anzahl der zu zeichnenden Pixel
- foreach (jeden zu zeichnenden Pixel)
- - ermittle $x und $y Position
- - speicher $color im globalen Array $data
Ich speicher also nicht nur die x- und y-Positionen, sondern auch die z-Positionen (Tiefe), damit ich
später die tatsächliche Farbe in diesem Pixel berechnen kann.
Nachdem alle Linien "gezeichnet", also in $data gespeichert wurden, wird die Funktion present() aufgerufen,
welche nun wirklich berechnet welche Farbe auf welchem Pixel wirklich angezeigt werden soll:
Für jeden xy-Pixel existiert ein Array: z => color
Die anfangsfarbe für den pixel wird von der image ressource genommen
(so kann man zb selber noch einen eigenen hintergrund wählen)
von hinten nach vorne wird nun jede farbe aus dem array hinzu "addiert"
Weshalb ich mich an euch wende ist folgendes:
Ich Teste das Script mit einem 1200x600 großen Bild, sowie mit 100 waagerechten und 100 senkrechten Linien.
Die image-Ressource verbraucht nur ca 2mb Speicher.
Das Array allerdings besitzt in meinem Test am ende mehr als 100.000 Einträge und verbraucht 40mb
Anfangs habe ich noch mit $data[$x][$y] gearbeitet und konnte mit der Änderung zu $data[$xy] den Speicherverbrauch um 3mb senken.
Aber 40mb sind immer noch weiiiiit zu viel.
Wie funktioniert eine Image-Ressource ? Ich meine, sie verbraucht so wenig mb, wo mein Array hingegen so viel verbraucht.
Mit meinem data-Array will ich lediglich so eine ressource nachbauen und mit einem z-wert erweitern.
Gibt es da evtl eine andere Möglichkeit? eine Möglichkeit die originale image-ressource "nachzubauen" ?
Kennt wer eine Seite mit infos wie diese Image Ressource arbeitet? Oder evtl sogar Infos darüber,
wie DirectX diesen Teil der Ausgabe handhabt?
Bin für jede hilfreiche Antwort die mich ein bisschen weiterbringt dankbar =)
Zuallererst, dies ist in erster Linie ein Projekt, das mir beim Lernen hilft. Bevor ich es begonnen hab wusste ich nicht mal wie man mit Matrizen rechnet =)
Bin gerade soweit, dass einfache Linien in einer Farbe und einem Alpha-Wert in 3d gezeichnet werden können. Die Matrix-Funktionen funktionieren soweit einwandfrei (Translation, Rotation, ViewAt, Inverse, ...).
Schritte um eine Linie zu zeichnen:
- Aufruf der Funktion mit den 3 Parametern $from, $to und $color (zb 0xaaffee11 - aa=alpha ffee11=rgb)
- Ermittle 2d Coordinaten von $from und $to
- Stutze die Linie (Crop)
- Ermittle Richtung der Linie und Anzahl der zu zeichnenden Pixel
- foreach (jeden zu zeichnenden Pixel)
- - ermittle $x und $y Position
- - speicher $color im globalen Array $data
PHP-Quellcode
- public function drawColoredLine($from, $to, $color)
- {
- $from = vectorMultiMatrix($this->mFinal, $from);
- $to = vectorMultiMatrix($this->mFinal, $to);
- if ($from[0] == $to[0] && $from[1] == $to[1]) return false;
- if (!cropScreenLineDepth($from, $to)) return false;
- $from[0] /= $from[2];
- $from[1] /= $from[2];
- $to[0] /= $to[2];
- $to[1] /= $to[2];
- if (!cropScreenLineSide($from, normalized3(array(
- $to[0] - $from[0],
- $to[1] - $from[1],
- $to[2] - $from[2]
- )))) return false;
- if (!cropScreenLineSide($to, normalized3(array(
- $from[0] - $to[0],
- $from[1] - $to[1],
- $from[2] - $to[2]
- )))) return false;
- $from[0] = $from[0] * $this->widthHalf + $this->widthHalf;
- $from[1] = $from[1] * $this->heightHalf + $this->heightHalf;
- $to[0] = $to[0] * $this->widthHalf + $this->widthHalf;
- $to[1] = $to[1] * $this->heightHalf + $this->heightHalf;
- $zero = array(
- $to[0] - $from[0],
- $to[1] - $from[1],
- $to[2] - $from[2]
- );
- $drawParts = max(abs($zero[0]), abs($zero[1]));
- $ray = array(
- $zero[0] / $drawParts,
- $zero[1] / $drawParts,
- $zero[2] / $drawParts
- );
- for ($i=0; $i<=$drawParts; $i++)
- {
- $xy = ((floor($from[1] + $i*$ray[1]))*$this->width) + floor($from[0] + $i*$ray[0]);
- if (!isset($this->data[$xy])) $this->data[$xy] = array();
- $z = $from[2]+$i*$ray[2];
- $this->data[$xy][$z] = $color;
- }
- }
Ich speicher also nicht nur die x- und y-Positionen, sondern auch die z-Positionen (Tiefe), damit ich
später die tatsächliche Farbe in diesem Pixel berechnen kann.
Nachdem alle Linien "gezeichnet", also in $data gespeichert wurden, wird die Funktion present() aufgerufen,
welche nun wirklich berechnet welche Farbe auf welchem Pixel wirklich angezeigt werden soll:
Für jeden xy-Pixel existiert ein Array: z => color
Die anfangsfarbe für den pixel wird von der image ressource genommen
(so kann man zb selber noch einen eigenen hintergrund wählen)
von hinten nach vorne wird nun jede farbe aus dem array hinzu "addiert"
PHP-Quellcode
- public function present()
- {
- foreach($this->data as $xy => $dataXY)
- {
- krsort($dataXY);
- $x = $xy % $this->width;
- $y = ($xy-$x) / $this->width;
- $back = imagecolorat($this->out, $x, $y);
- $r = ($back >> 16) & 0xFF;
- $g = ($back >> 8) & 0xFF;
- $b = $back & 0xFF;
- foreach($dataXY as $z => $color)
- {
- $a = (($color>>24)&0xFF)/255;
- $r = $r*($a) + (($color>>16)&0xFF)*(1-$a);
- $g = $g*($a) + (($color>>8)&0xFF)*(1-$a);
- $b = $b*($a) + (($color)&0xFF)*(1-$a);
- }
- imagesetpixel($this->out, $x, $y, (($r<<16)|($g<<8)|$b));
- }
- //$this->data = array();
- }
Weshalb ich mich an euch wende ist folgendes:
Ich Teste das Script mit einem 1200x600 großen Bild, sowie mit 100 waagerechten und 100 senkrechten Linien.
Die image-Ressource verbraucht nur ca 2mb Speicher.
Das Array allerdings besitzt in meinem Test am ende mehr als 100.000 Einträge und verbraucht 40mb
Anfangs habe ich noch mit $data[$x][$y] gearbeitet und konnte mit der Änderung zu $data[$xy] den Speicherverbrauch um 3mb senken.
Aber 40mb sind immer noch weiiiiit zu viel.
Wie funktioniert eine Image-Ressource ? Ich meine, sie verbraucht so wenig mb, wo mein Array hingegen so viel verbraucht.
Mit meinem data-Array will ich lediglich so eine ressource nachbauen und mit einem z-wert erweitern.
Gibt es da evtl eine andere Möglichkeit? eine Möglichkeit die originale image-ressource "nachzubauen" ?
Kennt wer eine Seite mit infos wie diese Image Ressource arbeitet? Oder evtl sogar Infos darüber,
wie DirectX diesen Teil der Ausgabe handhabt?
Bin für jede hilfreiche Antwort die mich ein bisschen weiterbringt dankbar =)