Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Kombi von 2D mit 3D Elementen, auch ohne OpenGL ? (https://www.delphipraxis.net/81072-kombi-von-2d-mit-3d-elementen-auch-ohne-opengl.html)

Der_Unwissende 23. Nov 2006 09:12

Re: Kombi von 2D mit 3D Elementen, auch ohne OpenGL ?
 
Zitat:

Zitat von CloudyofSky
@Der_Unwissende:
Ich habe nun auch deines Ausprobiert und mit dem was du geschrieben hast, klappt es prima, kann sogar sehen das er die Datei anlegt. Was jedoch nicht klappt ist, das ich ein Bild draus lade und dieses dann per TImage ausgeben kann :-(

Ja, das Problem liegt im direkten Laden der Bitmap aus dem Stream. Ein Stream hat einen Positionszeiger, der immer auf die akutelle Lese/Schreibposition zeigt. Lädst du also eine Bitmap aus dem Container in einen Stream, so wird dieser Stream natürlich geschrieben. Beim anlegen des Streams zeigt der Zeiger auf Position 0, nach dem schreiben auf das nächste Byte, dass geschrieben werden kann.
Wenn du jetzt das Bitmap aus diesem Stream lädst, dann zeigt der Zeiger auf das erste Byte das geschrieben werden kann (also noch nicht gesetzt ist). Damit wird kein Bitmap geladen und etwas zu zeichnen, dass keine Dimension hat ist dann auch schwierig. Deshalb musst du einfach nur vor dem Laden den Zeiger zurück setzen. Am einfachsten änderst du in der Funktion readNextFromContainer wie folgt:
Delphi-Quellcode:
...
if Container.Position + length <= Container.Size then
begin
  result := TMemoryStream.Create;
  result.CopyFrom(Container, length);
end // if Container.Position + length < Container.Size
...
Denke dass es einfach nur das war, der Rest sollte funktionieren. Ach ja, die Abfrage muss auch geändert werden, <= statt kleiner, also halt wie hier, sonst geht das letzte Bild verloren.

Gruß Der Unwissende

CloudyofSky 23. Nov 2006 14:08

Re: Kombi von 2D mit 3D Elementen, auch ohne OpenGL ?
 
Die Änderung ist nur das ändern von < auf <= ? Weil einen anderen Unterschied hab ich nicht gefunden :-(
Oder meinst du ich soll alles andere aus der Funktion rausnehmen? Entschuldige bitte, aber irgend wie hab ich das ganze nicht so richtig verstanden :-(
Falls du die Zeit und last hast, könntest du mir bitte die ganze Funktion zeigen?

Zur Zeit sieht meine Funktion so aus:
Delphi-Quellcode:
function readNextFromContainer(const Container : TStream) : TStream;
var
  length : Integer;
begin
  if Container.Position + sizeof(Integer) < Container.Size then
  begin
    Container.Read(length, sizeof(Integer));
    if Container.Position + length <= Container.Size then
    begin
      result := TMemoryStream.Create;
      result.CopyFrom(Container, length);
    end else result := nil;
  end else result := nil;
end;
Mit der Änderung aus deiner letzten Nachricht.

Oder liegt das vielleicht an dem Inhalt? Ich mußte leider ein .size weglassen, ich dachte es ist zu viel? Weil mir auch dir Fehlermedlung sagte, das er da was anderes erwartet:
Delphi-Quellcode:
procedure addToContainer(const Stream : TStream; const Container : TStream);
begin
  if assigned(Stream) and assigned(Container) then
  begin
    Container.Write(Stream, sizeof(Integer));

    Container.CopyFrom(Stream, 0);
  end;
end;
Ich meine die Zeile mit "Container.Write(Stream, sizeof(Integer));", deine Variante mag er nicht wirklich mit "Container.write(Stream.Size, sizeOf(Integer));" :-(

Der_Unwissende 23. Nov 2006 14:49

Re: Kombi von 2D mit 3D Elementen, auch ohne OpenGL ?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von CloudyofSky
Die Änderung ist nur das ändern von < auf &lt;= ? Weil einen anderen Unterschied hab ich nicht gefunden :-(

Eigentlich sollte da eine ganze Zeile mehr drin sein, die hab ich wohl vergessen, peinlich :oops:

Zitat:

Zitat von CloudyofSky
Oder liegt das vielleicht an dem Inhalt? Ich mußte leider ein .size weglassen, ich dachte es ist zu viel? Weil mir auch dir Fehlermedlung sagte, das er da was anderes erwartet:
Delphi-Quellcode:
procedure addToContainer(const Stream : TStream; const Container : TStream);
begin
  if assigned(Stream) and assigned(Container) then
  begin
    Container.Write(Stream, sizeof(Integer));

    Container.CopyFrom(Stream, 0);
  end;
end;

Ja, dass weglassen war ganz schlecht. Ist mein Fehler, war halt ungetesteter Code, hätte ich deutlich sagen sollen. Jedenfalls kurz zur Theorie was du da machst, du schreibst etwas in einen Stream. Ein Stream kannst du dir dabei als einen Strom von Bytes vorstellen, der hat sonst keinerlei Logik. Alles was du den gibst ist einfach eine Adresse von der aus er liest und sagst ihm wieviele Bytes da stehen. So hat der Datentyp Byte z.B. genau ein Byte, eine Word hat zwei Byte, ein String hat pro Zeichen ein Byte + 4 Byte für die Längenangabe, ein ShortString hat hingegen pro Zeichen ein Byte + ein Byte für die Längenangabe, usw.
Da du jeden Datentypen in so einen Stream schreiben kannst, nimmst du etwas sehr allgemeines (wie gesagt es ist eigentlich nur eine Adresse), wieviele Bytes von hier zu dem eigentlichen Datum das geschrieben werden soll gehören, musst du als zweiten Parameter angeben. sizeOf(X) gibt dir halt die Größe des Datentyps X an. Bei den primitiven Datentypen und Records (ohne String) liefert es die erwarteten Ergebnisse. Bei dyn. Arrays oder z.B. auch Klassen sieht es anders aus. Hier speicherst du implizit immer nur einen Zeiger auf die Datenstruktur, sizeOf würde dir nur die Größe des Zeigers (ein Prozesswort) liefern.
Delphi-Quellcode:
procedure addToContainer(const Stream : TStream; const Container : TStream);
var buffer : Integer;
begin
  if assigned(Stream) and assigned(Container) then
  begin
    // Stream ist nur eine Referenz auf eine Instanz vom Typ TStream
    // Du schreibst hier also die Adresse der Instanz, nicht die Größe des Stream
    Container.Write(Stream, sizeof(Integer));

    buffer := Stream.Size;
    // hier schreibst du jetzt den Wert von buffer in den Stream
    // da du hier die Stream.Size zugewiesen hast, also die Anzahl der Bytes in dem Stream
    Container.Write(buffer, sizeOf(Integer));

    Container.CopyFrom(Stream, 0);
  end;
end;
Das was der hier anderes erwartet hatte war eine Variable. Buffer ist hier auch wirklich variabel, Container.Size hingegen eine Eigenschaft.


Ich hab mal ein kleines (einfaches) Beispiel angehängt. Einfach einen Container erstellen, ein (oder beliebig viele Bitmaps hinzufügen) den Container laden (muss auch gemacht werden, wenn du ihn im selben Lauf angelegt hast) und dann halt mit getNext das nächste Bild anzeigen lassen. Ist kein schöner Code, es wird hier nicht geprüft ob du alles in der richtigen Reihenfolge machst, also schön drauf achten (sonst gibt es halt Fehler).

Gruß Der Unwissende


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:57 Uhr.
Seite 2 von 2     12   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz