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

Aktuelle Zeit: Sa Jul 05, 2025 17:48

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 9 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Problem mit Snapshot
BeitragVerfasst: Fr Aug 22, 2008 23:07 
Offline
DGL Member

Registriert: Do Aug 14, 2008 16:25
Beiträge: 15
Auch diese Frage hatte ich bereits einmal gestellt und auch diese ging im Wust unter, daher nochmals lösgelöst vom Ursprungsthread ;).
Auf einem Panel wird gerendet. Davon soll dann ein Snapshot erstellt werden und dieser auf ein leeres TBitmap kopiert werden. Selbiges hat Übermass so dass die freien Bereiche zum Beschriften mittels TextOut genutzt werden können. Die Bildschirmdarstellung nutzt einen schwarzen Hintergrund derweil der Snapshot einen weissen Hintergrund haben soll (wg. Ausdruck desselben). Das fertige TBitmap wird zum Abschluss als BMP-Datei gespeichert und der Hintergrund wieder auf schwarz umgeschaltet.
WhiteHunter hatte mir schon einen prima Tip gegeben wie ich den Snapshot auf TBitmap bringe, danke dafür :).
Ein Problem hält sich aber hartnäckig: Auf manchen PCs (z.B. meinem Laptop) erscheint der Hintergrund im Snapshot nicht weiss sondern bleibt schwarz. Wobei das so eigentlich nicht ganz stimmt, während des Save-Dialogs ist der weisse Hintergrund schön zu erkennen...nur im gespeicherten BMP ist er schwarz.

Hier mal wieder der Code:

Code:
  1.  
  2. {***************************************************************************
  3.  Screenshot erstellen
  4. ****************************************************************************}
  5. procedure TForm1.ScreenShot(sender: TObject);
  6.  var
  7.      BMPname     : string;
  8.      FileInfo    : BITMAPINFOHEADER;
  9.      FileHeader   : BITMAPFILEHEADER;
  10.      Viewport    : array[0..3] of integer;
  11.      RohBild,
  12.      Bild          : TBitmap;
  13.      i            : integer;
  14.  
  15. begin
  16.  
  17.  // Testweise um ein unkontrolliertes Rendern während des Speicherns zu verhindern - bringt
  18.  // aber auch nix...
  19.  Timer1.enabled := false;  
  20.  
  21.  // Backgrund = weiss
  22.  glClearColor(1, 1, 1, 0);
  23.  
  24.  // Bisheriges Bild löschen
  25.  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  26.  
  27.  // Bild neu aufbauen; letzte Zeile in Render ist übrigens glFinish;
  28.  Render;  
  29.  
  30.  //Snapshotroutine von WhiteHunter
  31.  glGetIntegerv(GL_VIEWPORT, @Viewport);
  32.  Rohbild := TBitmap.Create;
  33.  try
  34.  Rohbild.Width := Viewport[2];
  35.  Rohbild.Height := Viewport[3];
  36.  Rohbild.PixelFormat := pf24bit;
  37.  for i := 0 to Viewport[3] - 1 do
  38.  glReadPixels(0, Viewport[3] - i, Viewport[2], 1, GL_BGR, GL_UNSIGNED_BYTE, Rohbild.ScanLine[i]);
  39.  
  40.  
  41.  // Eigentliches Bitmap mit Übermass erstellen
  42.  Bild := TBitmap.Create;
  43.  Bild.PixelFormat := pf24bit;
  44.  Bild.Width := RohBild.Width + 225;
  45.  Bild.Height := RohBild.Height + 100;
  46.  
  47.  // Beschriftungen einfügen
  48.  Bild.Canvas.textout(10,Bild.Height-70 ,MaskEdit1.Text);
  49.  Bild.Canvas.textout(10,Bild.Height-50 ,MaskEdit2.Text);
  50.  Bild.Canvas.textout(10,Bild.Height-30 ,MaskEdit3.Text);
  51. .
  52. .
  53. .
  54.  
  55.  // Gepuffertes Bitmap ins eigentliche Bitmap
  56.  Bild.Canvas.Draw ( 225,0,Rohbild);
  57.  
  58.  // Fertiges Bitmap speichern
  59.  BMPname := Dateipfad + '-' + DateToStr(Date);
  60.  SaveDialog1.FileName := BMPname;
  61.  if SaveDialog1.Execute then BMPname:=SaveDialog1.FileName;
  62.  Bild.SaveToFile(BMPname);
  63.  
  64.  finally
  65. //  Bild.Free;       ---> Diese auskommentierten Einträge bedeuten
  66. //  RohBild.Free;  --->  einen sicheren Programmabsturz ?!?
  67.  end;
  68.  
  69.  // Background wieder auf schwarz stellen
  70.  glClearColor(0, 0, 0, 0);
  71.  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  72.  
  73.  // Timergesteuertes Rendern wieder freigeben
  74.  Timer1.enabled := true;
  75.  
  76. end;
  77.  


Auf meinem vergleichsweise schnellen Desktop ist alles i.O., auf meinem Laptop mit Onboard-Grafik bleibt der Hintergrund schwarz.
Aaaaber: In meiner ersten Version habe ich den Snapshot zunächst in eine BMP-Datei gespeichert, dann wieder in ein TBitmap geladen und mit dem grösseren TBitmap verheiratet. Da konnte ich mir noch helfen indem ich ganz oben nach dem ersten 'Render' eine kleine Delayroutine aufgerufen habe die das Programm 1sek beschäftigt hat. Jetzt funktioniert auch das nicht mehr, der Hintergrund des Screenshots bleibt schwarz egal welche Zeit ich dort eintrage. Wohlgemerkt aber nur in der fertigen Datei, beim Save-Dialog ist er auf dem Bildschirm weiss.

Ich habe mal irgendwo von möglichen Problemen in Zusammenhang mit Scanline gelesen (Edit: http://www.delphi-treff.de/tutorials/gr ... ps/page/2/ ), das 'richtige' Pixelformat ist aber doch eingestellt. Und könnte sich das auf verschiedenen Rechnern unterschiedlich äussern? Vielleicht könnte sich mal jemand erbarmen und das bei sich ausprobieren?

Ich bin echt ratlos, was kann das sein?... :?

Gruss
Toenne


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 07:22 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Sorry, hab meinen Beitrag hier falsch gepostet.
Traude


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 17:56 
Offline
DGL Member

Registriert: Do Aug 14, 2008 16:25
Beiträge: 15
Hmm, wird wohl doch wieder ein Monolog... :(

Ich habe mal versucht herauszubekommen wo was wie schiefgeht.
Dazu habe ich als erstes bei ...
Code:
  1.  // Bild neu aufbauen; letzte Zeile in Render ist übrigens glFinish;
  2.  Render;

...das 'Render' mit '//' auskommentiert, es wird also zwar der Bildschirm gelöscht aber nicht neu gezeichnet. Erfolg: Das gespeicherte Bitmap ist tatsächlich weiss.

Render sieht (verkürzt) wie folgt aus:

Code:
  1. {***************************************************************************
  2.  Zeichnung erstellen
  3. ****************************************************************************}
  4. procedure TForm1.Render;
  5. var
  6.   BoolDummy : boolean;
  7.  
  8. begin
  9.  
  10.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  11.  
  12.   gluPerspective(1.05 * 30, Panel1.Width/Panel1.Height, NearClipping, FarClipping);
  13.  
  14.   glMatrixMode(GL_MODELVIEW);
  15.   glLoadIdentity;
  16.  
  17.   Distanz := -SpanneYWert/2 / tan(degtorad(30/2));
  18.  
  19.   glTranslatef(0,0,Distanz);
  20.  
  21.   if SpeedButtonPunkte.down then BoolDummy := Punkte;;
  22.   if SpeedButtonLinien.down then BoolDummy := Linien;
  23.   if SpeedButtonFlaechen.down then BoolDummy := Dreiecke;
  24.  
  25.   SwapBuffers(DC);
  26.   glFinish;
  27. end;
  28.  
  29.  

Verkürzt deswegen weil ich der übersichtlichkeit halber diverse Skalier- und Drehoptionen weggelassen habe.
Es wird aus Render heraus also je nach Status dreier Buttons in Funktionen verzweigt, exemplarisch mal die kürzeste:

Code:
  1. {***************************************************************************
  2.  Punkte zeichnen
  3. ****************************************************************************}
  4. function TForm1.Punkte: boolean;
  5. var
  6.   u, v : Integer;
  7.   BoolDummy : boolean;
  8. begin
  9.  
  10.   for v:=1 to (WievielY-1) do
  11.    begin
  12.     for u:=1 to (WievielX-1) do
  13.      begin
  14.       glBegin(GL_points);
  15.        BoolDummy:= RGBErmitteln(Daten[u,v]);
  16.        glColor3f(Rot,Gruen,Blau); glVertex3f((u-WievielX/2-0.5)*Xstep,(v-WievielY/2-0.5)*Ystep, Amplitude*(Daten[u,v]-ZMittelwert));
  17.       glEnd;
  18.      end;
  19.     end;
  20. end;

Nur zur Erklärung: In einem zweidimensionalen Array sind die Z-Werte der durch u und v definierten X/Y-Koordinaten hinterlegt, das klappt auch alles tadellos.
Wie man sieht passiert hier auch nichts nervenzerfetzendes, zumindest nix was den Hintergrund betrifft.

Eines zumindest wollte ich noch probieren:
Die Snapshotfunktion beginnt mit
Code:
  1.  // Background = weiss
  2.  glClearColor(1, 1, 1, 0);
  3.  
  4.  // Bisheriges Bild löschen
  5.  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

...bevor nach Render verzweigt wird. Render beginnt aber auch wieder mit ' glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);' - ob dieser zweifache Aufruf hintereinander die Probleme verursacht?
Also habe ich noch eine Boolsche Variable 'SaveFlag' eingefügt die bei der Formerstellung erstmal auf False gesetzt wird. Render sieht nun so aus...
Code:
  1. begin
  2.   if SaveFlag = true then  glClearColor(1, 1, 1, 0) else glClearColor(0, 0, 0, 0);
  3.   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

...und die Snapshotroutine so...
Code:
  1. begin
  2.  SaveFlag := true;
  3.  Timer1.enabled := false;
  4.  Render;
  5. .
  6. .
  7. .
  8. SaveFlag := false;

Das Umschalten des Bildschirmhintergrundes wird also komplett nach Render verschoben, auf dem Bildschirm ist auch alles bestens. Der Hintergrund im Snapshot bleibt aber schwarz...
Ich verstehe das einfach nicht. Würde die Snapshotfunktion selbst das Problem verursachen so müsste der Snapshot auch nach Auskommentierung von Render schwarz sein...ist er aber nicht, er ist weiss.
Render selbst schaltet den Bildschirm in oben gezeigter Fassung korrekt um was man auf dem Bildschirm auch sieht...dennoch ist der Hintergrund auf dem exportierten Bitmap aber schwarz.

Was läuft da schief, echt keiner mit irgendeiner Idee?

Gruss
Toenne


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Sa Aug 23, 2008 20:24 
Offline
DGL Member

Registriert: Do Aug 14, 2008 16:25
Beiträge: 15
Für den Fall dass es irgend jemanden interessiert: Ich muss am Anfang der Snapshotfunktion 'Render' zweimal hintereinander ausführen, dann klappt es wie gewünscht.
Warum? Ich habe keinen blassen Schimmer... :?

Gruss
Toenne


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 28, 2008 19:58 
Offline
DGL Member

Registriert: Mo Jun 30, 2008 12:47
Beiträge: 69
machst doch mit BitBLT()

Edit: Ich habe es gerade an meinem Projekt probiert und es klappt wunderbar !

_________________
...GOD is wearing black...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 28, 2008 20:08 
Offline
DGL Member

Registriert: Fr Dez 28, 2007 20:24
Beiträge: 62
Wohnort: Berlin
ignoriert mich einfach...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Aug 28, 2008 23:20 
Offline
DGL Member

Registriert: Do Aug 14, 2008 16:25
Beiträge: 15
Emre hat geschrieben:
machst doch mit BitBLT()

Edit: Ich habe es gerade an meinem Projekt probiert und es klappt wunderbar !

Kurze Frage: Hattest du meinen obigen Code auch getestet und dabei die gleichen Probleme gehabt? Wenn die Probleme bei dir nicht aufgetreten sind dann hilft mir der Hinweis auf BitBLT leider nur eingeschränkt weiter, dann ist ja keinesfalls ausgeschlossen dass ich nicht vom Regen in die Traufe komme ;).
Auf meinem Desktop-PC funktionierte ja auch alles prächtig, nur auf dem Laptop nicht :cry: .

Gruss
Toenne


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Aug 31, 2008 23:33 
Offline
DGL Member

Registriert: Mo Jun 30, 2008 12:47
Beiträge: 69
Toenne hat geschrieben:
Auf meinem Desktop-PC funktionierte ja auch alles prächtig, nur auf dem Laptop nicht Crying or Very sad .

Das ist mir auch aufgefallen:
Bei meinem aktuellen Projekt mit Lukasiver ( DP ) gehen zb. die Sprites bei ihm nicht, aber bei mir schon ... Wir haben es auch an unzähligen anderen Leuten getestet --> Bei manchen ging es und bei manchen nicht :S

Ich weiß auch nicht woran das liegt... Man sollte eher fragen ob das n allgemeiner Fehler ist .. Kann ja auch sein dass es an der Hardware liegt, woran ich aber gar nicht glaube ... Denn heutzutage wird wohl jeder Gamer ne super-duper graka haben - und sone Karte schafft es glaube ich, eine billige Sprite abzuspielen :roll:

Mich würde nun auch interessieren, warum ein Code bei Einem geht und bei einem Anderen nicht !!!

EDIT:
Und nein ich habe deinen Code nicht probiert ... :roll:

MfG

_________________
...GOD is wearing black...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 01, 2008 16:28 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Die Superduper Karten müssen nicht zwangsläufig auch gut sein beim verarbeiten der Oldschool Sachen.
Ich hatte mal so ein Problem mit Texturen. Bei mir gingen nämlich non Power of 2 Texturen (obwohl der Treiber uralt war -> undokumentiertes Feature), bei allen anderen nicht. Vielleicht kann man den Fehler ja auf eine GraKa bzw. einen Hersteller einschränken.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


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


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 7 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 | 16 Queries | GZIP : On ]