Ich will ein Bitmap direkt über Rawimage über einen Timer befüllen. Aber leider wird es dies nicht gemacht, dies sieht man im Anhang.
Der Timer würde funktionieren, ansonsten würde man das Quadrat nicht sehen.
Aber komischerweise funktioniert das Befüllen in FormPaint.
Was läuft da falsch ?
Wir da irgendwie ein doppelter Puffer oder sonst was verwendet ?
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Interval := 100;
bitmap := TBitmap.Create;
bitmap.SetSize(320, 200);
end;
procedure TForm1.FormPaint(Sender: TObject);
var
i: integer;
begin
for i := 0 to 1000000 do begin
bitmap.RawImage.Data[Random(10000) + 10000] := Random($FF); // wird gemacht
end;
Canvas.Draw(10, 10, bitmap);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: integer;
begin
for i := 0 to 1000000 do begin
bitmap.RawImage.Data[Random(10000)] := Random($FF); // wird nicht gemacht
end;
bitmap.Canvas.Brush.Color := Random($FFFFFF);
bitmap.Canvas.Rectangle(10, 10, 50, 50);
for i := 0 to 1000000 do begin
bitmap.RawImage.Data[Random(10000)] := Random($FF); // wird nicht gemacht
end;
Repaint;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
bitmap.Free;
end;
Dateianhänge
Bildschirmfoto vom 2024-05-10 17-43-46.png (12.56 KiB) 489 mal betrachtet
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Hallo Matthias,
in einer Form kannst du nur in die Paint Procedure zeichnen. Mit jedem Invalidate wird der Canvas wieder gelöscht und nur das was in der Paint steht ist zu sehen.
Alternativ kannst du in eine Image zeichnen.
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Interval := 100;
bitmap := TBitmap.Create;
bitmap.SetSize(320, 200);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
i: integer;
begin
for i := 0 to 1000000 do begin
bitmap.RawImage.Data[Random(5000)] := Random($FF);
end;
Image1.Canvas.Draw(10, 10, bitmap);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
bitmap.Free;
end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Habe das Problem gelöst, ich habe einen kleinen Umweg über OpenGL gemacht.
Und es macht, was ich will.
Dies hat sogar noch den Vorteil, das ich meine Rohdaten, welche in einer Byte Array sind direkt ohne Umwandlung in den FrameBuffer kriege.
Meine Image hat ein Byte pro Pixel und ein Canvas hat für ein Pixel ein TColor.
@wennerer: Die Zwischenschritte mit dem RawImage kannst du dir sparen, denn du kannst mit einem einzigen Befehl (CreateIntfImage) ein TLazIntfImage aus einem TBitmap erzeugen:
var
AImage: TLazIntfImage;
...
BitTextur := TBitmap.Create;
AImage := BitTexture.CreateIntfImage;
// ... etwas mit dem LazIntfImage machen
BitTextur.LoadFromIntfImage(AImage); // IntfImage ins Bitmap zurück laden
AImage.Free;
Kann man das Create und Free nicht in den Constructor und Destructor auslagern. Man sollte nach Möglichkeit verhinder nach jedem Frames neuen Speicher anzulegen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot