JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.php?sid=22499ab0e69ffd4c230c6d404d51c231Medaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Screenshots mit individuellem Namen
Gehe zu Seite 1, 2  Weiter
 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Tutorials
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Asto
JLI'ler


Alter: 37
Anmeldedatum: 30.05.2007
Beiträge: 114
Wohnort: Dortmund
Medaillen: Keine

BeitragVerfasst am: 14.06.2007, 14:03    Titel: Screenshots mit individuellem Namen Antworten mit Zitat

-------------------------------
Einleitung
-------------------------------

Ich habe die Funktion zum Screenshots erstellen aus dem Buch so erweitert, dass man jetzt nicht immer nur den Screenshot in einer Datei ablegt, sondern das man die Screenshots unter eigenen Namen in ein extra Unterverzeichnis ablegt.

Das bedeutet, das man so viele Screenshots machen kann, wie man mag, ohne das die alten überschrieben werden.

Im Beispiel werden die Dateien als PNG gespeichert.

-------------------------------
Entwicklungsumgebung
-------------------------------

Da ich hier die Klasse Direct3D aus dem Buch editiere, setze ich die Grundstruktur der Klasse vorraus. Des weiteren arbeite ich mit Visual C++ EE und dem DirectX SDK April 2007, dementsprechend also unter Windows (XP).

-------------------------------
Klassenheader
-------------------------------

Als erstes modifiziert man die Headerdatei der Klasse.
Dort fügt man einen optionalen Paramter hinzu, falls man den Screenshot unter einem bestimmten Namen speichern möchte:
CPP:
        // Screenshot erstellen
        void CreateScreenshot(char* name = NULL);


-------------------------------
Die Methode
-------------------------------

Dann zur Funktion selber:
CPP:
// Screenshot erzeugen
void Cdirect3d::CreateScreenshot(char* name)
{
   char Dateiname[100];


Als erstes wird überprüft, ob der Optionale Parameter immernoch NULL ist, oder ob er gesetzt wurde:
CPP:
   if(name == NULL)


Wurde er nicht gesetzt, sit er also NULL. Nun gilt es, einen würdigen Dateinamen für den Screenshot zu erstellen. Wink
Hierbei gebe ich dem Screenshot einen Namen in der Form: datum-zeit.png.
Dieser Dateiname enthält auch die Millisekunden, damit die Dateien sich nicht überschreiben, wenn man 2x in einer Sekunde einen Screenshot erstellen will.
Also fülle ich zuerst die Struktur systemtime mit den aktuellen Zeitdaten und hole mir Informationen über die aktuelle Zeitzone, damit anschließend die Zeit auf die aktuellen Zeitzonenoptionen angepasst wird (d.h.: Sommer- / Winterzeit, etc.).
Mit sprintf_s wird dann der Name erzeugt und in der Variablen Dateiname gespeichert:
CPP:
   {
      SYSTEMTIME systemtime; // Zeitstruktur mit Systemzeit
      GetSystemTime(&systemtime);

      TIME_ZONE_INFORMATION timezone; // Informationen über die Zeitzone
      GetTimeZoneInformation(&timezone);

      SYSTEMTIME time; // Zeitstruktur mit lokaler UTC-Zeit
      SystemTimeToTzSpecificLocalTime(&timezone, &systemtime, &time);

      // Dateiname festlegen (Datum + Zeit, für individuelle Dateinamen)
      sprintf_s(Dateiname, sizeof(Dateiname),
               "%d-%d-%d-%d-%d-%d-%d.png",
               time.wDay, time.wMonth, time.wYear, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);
   }


Ist der name jedoch nicht NULL, wurde ein Dateiname übergeben. Dieser wird dann alternativ verwendet:
CPP:
   else
   {
      strcpy_s(Dateiname, sizeof(Dateiname), name);
   }


Nun muss das Bildschirmfoto irgendwo gespeichert werden.
Dazu wird hier ein unterverzeichnis namens screenshots definiert.
Anschließend wird überprüft ob es existiert, oder noch neu angelegt werden muss:
CPP:
   char* Verzeichnisname = "./screenshots/";

   // Verzeichnis ./screenshots/ erstellen, falls nicht vorhanden
   if(GetFileAttributes(Verzeichnisname) != FILE_ATTRIBUTE_DIRECTORY)
      CreateDirectory("screenshots", NULL);


Nun müssen noch der Pfad und Dateiname zusammengefügt werden, damit sie später an die Funktion zum erstellen der Datei übergeben werden können. Dies habe ich einfach mit Strings gelöst. Wenn man bei char bleiben mag, kann man die char Variablen auch mit der Funktion strcnt_s(erste_var, sizeof(erste_var), anzuhaengende_var); aneinanderhängen.
CPP:
   // Verzeichnispfad und Dateiname zusammenhängen
   string DirAndFilename = Verzeichnisname;
   DirAndFilename += Dateiname;


Hier folgt dann der aus dem Buch bekannte Code. Es wird ein Surface erstellt, in das der aktuelle Inhalt des Frontbuffers gespeichert wird. SCR_WIDTH und SCR_HEIGHT sind bei mir Konstanten mit der Breite und Höhe des Fensters.
CPP:
   // Surface für den Screenshot anlegen
    LPDIRECT3DSURFACE9 lpScreenshotSurface;

    this->m_lpD3DDevice->CreateOffscreenPlainSurface(
                                  SCR_WIDTH, SCR_HEIGHT,
                                  D3DFMT_A8R8G8B8,
                                  D3DPOOL_SYSTEMMEM,
                                  &lpScreenshotSurface,0);
   
    // Inhalt des Frontbuffers in das Surface kopieren
    this->m_lpD3DDevice->GetFrontBufferData(0, lpScreenshotSurface);


Nun wird dieses Surface als Datei gespeichert. Hier muss beachtet werden, das man den String (falls man Strings verwendet) mit c_str() in den Typ char konvertiert:
CPP:
    // Surface in Datei speichern
   D3DXSaveSurfaceToFile(DirAndFilename.c_str(), D3DXIFF_PNG, lpScreenshotSurface, NULL, NULL);


Jetzt noch das Surface freigeben. Fertig.
CPP:
    // Freigeben
    lpScreenshotSurface->Release();
}


-------------------------------
Aufrufen
-------------------------------

Nun kann man, nach dem man ein Objekt der Klasse erstellt und ggf. initialisiert hat, einen Screenshot wie folgt erstellen:
CPP:
Direct3D.CreateScreenshot();


Möchte man einen eigenen Dateinamen festlegen, dann so:
CPP:
Game.Direct3D.CreateScreenshot("moo.png");


-------------------------------
Schlussworte
-------------------------------

Ich hoffe es war verständlich, wenn nicht: bitte nicht hauen Wink
Nehme gerne Verbesserungsvorschläge entgegen.
_________________
"A programmer started to cuss, Because getting to sleep was a fuss, As he lay there in bed, Looping 'round in his head, was: while(!asleep()) sheep++;", Unbekannt


Zuletzt bearbeitet von Asto am 14.06.2007, 16:05, insgesamt 5-mal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
fast hawk
Senior JLI'ler



Anmeldedatum: 15.07.2005
Beiträge: 237
Wohnort: Freiburg
Medaillen: Keine

BeitragVerfasst am: 14.06.2007, 14:21    Titel: Antworten mit Zitat

gute arbeit, nur würde ich millisekunde rausnehmen sonst wird der datei nahme zulang und UNICODE rein..... aber sonst STIFTUNG CODETEST: GUT^^ Wink
_________________
Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
Chriss
Senior JLI'ler



Anmeldedatum: 18.08.2004
Beiträge: 267

Medaillen: Keine

BeitragVerfasst am: 14.06.2007, 14:23    Titel: Re: Screenshots mit individuellem Namen Antworten mit Zitat

GreatFlo hat Folgendes geschrieben:
sondern das man die Screenshots unter eigenen Namen ... ablegt.


Kann ich hier nciht finden

CPP:
char Dateiname[100];

   // Dateiname festlegen (Datum + Zeit, für individuelle Dateinamen)
   sprintf_s(Dateiname, sizeof(Dateiname),
            "screens_%d%d%d-%d%d%d%d.png",
            time.wDay, time.wMonth, time.wYear, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds);


Eventuell noch die Übergabe eines optionalen Dateinames einbauen.

Ich finde deinen optimistischen Einsatz ja bewundernswert aber ein klein wenig mehr hätte es, für ein Tut., sein können. Vieleicht Erklärungen und mehr Funktionen.

EDIT: Wurde mittlerweile ja angepasst Wink


Zuletzt bearbeitet von Chriss am 15.06.2007, 07:05, insgesamt einmal bearbeitet
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Asto
JLI'ler


Alter: 37
Anmeldedatum: 30.05.2007
Beiträge: 114
Wohnort: Dortmund
Medaillen: Keine

BeitragVerfasst am: 14.06.2007, 14:30    Titel: Antworten mit Zitat

Nun okay, hätte eher in eine Funktionssammlung gehört, so wie ich es gepostet habe. :X

Werde es später mal eher in Richtung Tutorial editieren.

Die Millisekunden sind eingebaut, da man sonst nur einmal pro Sekunde ein Foto machen könnte Smile
_________________
"A programmer started to cuss, Because getting to sleep was a fuss, As he lay there in bed, Looping 'round in his head, was: while(!asleep()) sheep++;", Unbekannt
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 14.06.2007, 15:20    Titel: Antworten mit Zitat

Nummerier die Fotos doch pro Sekunde durch... Und ja, das ist egtl wirklich kein Tutorial.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Asto
JLI'ler


Alter: 37
Anmeldedatum: 30.05.2007
Beiträge: 114
Wohnort: Dortmund
Medaillen: Keine

BeitragVerfasst am: 14.06.2007, 15:28    Titel: Antworten mit Zitat

hmm naja ich hoffe jetzt ist es eines Wink

Pro Sekunde durchnummerieren == [...]_1.png, [...]_2.png, oder wie meinst du das? Könnte man machen... hmm, evt. baue ich es später ein.

was ich halt erstmal erreichen wollte, ist, dass man nicht immer nur eine datei hat, sondern das man so viele screens machen kann, wie man will.

Edit: Habe oben den Dateinamen etwas humaner gemacht ^^
_________________
"A programmer started to cuss, Because getting to sleep was a fuss, As he lay there in bed, Looping 'round in his head, was: while(!asleep()) sheep++;", Unbekannt
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
fast hawk
Senior JLI'ler



Anmeldedatum: 15.07.2005
Beiträge: 237
Wohnort: Freiburg
Medaillen: Keine

BeitragVerfasst am: 14.06.2007, 19:17    Titel: Antworten mit Zitat

naja du könntest ja die millisekunden weglassen und stattdessen denn namen vor dem speicher überprüfen.
nach dem motto
CPP:
int Durchaehler = 0;

sprintf_s(Dateiname, sizeof(Dateiname),
            "screens_%d%d%d-%d%d.png",
            time.wDay, time.wMonth, time.wYear, time.wHour, time.wMinute);
while(!CheckDatei(Dateiname))
{
     Durchaehler++;
sprintf_s(Dateiname, sizeof(Dateiname),
            "screens_%d%d%d-%d%d_%d.png",
            time.wDay, time.wMonth, time.wYear, time.wHour, time.wMinute, Durchzaehler);
}
[/code]
_________________
Jetziges Projekt: The Ring War
Status: 40%
-----------------------------------
Nicht weil es schwer ist, wagen wir es nicht, sondern weil wir es nicht wagen, ist es schwer.
--
Lucius Annaeus Seneca (4)
röm. Philosoph, Dramatiker und Staatsmann
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden Website dieses Benutzers besuchen
DirectXer
Dark JLI'ler



Anmeldedatum: 05.02.2005
Beiträge: 1201
Wohnort: Köln
Medaillen: Keine

BeitragVerfasst am: 17.06.2007, 18:19    Titel: Antworten mit Zitat

also ich finde den jetzigen Stand des Tutorials gut. Es gibt zwar weite Umfangsspannen von Tutorials, und dieses gehört sicherlich zu einer etwas kleineren davon. Aber da du nun alles bis ins kleinste Detail ausführlich erläutert hast, denke ich dass es insb. für Programmieranfänger sehr gut geeignet ist, da du eben so detailliert vorgegangen bist und die einzelnen kleinen Schritte sehr umfangreich eingefasst hast

Gruß DXer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Kronos
Senior JLI'ler



Anmeldedatum: 19.03.2004
Beiträge: 290

Medaillen: Keine

BeitragVerfasst am: 17.06.2007, 19:20    Titel: Antworten mit Zitat

David hat Folgendes geschrieben:
Nummerier die Fotos doch pro Sekunde durch... Und ja, das ist egtl wirklich kein Tutorial.

sagt wer? du? find ich amüsant.
nur weil du (wahrscheinlich) stundenlang an tutorials hockst und versuchst irgendwas perfektes rauszubringen, um respekt, genügend dankeschoens oder sonstwas zu ernten, um dein ego zu befriedigen..
das waere ja noch das beste, wenn du hier irgendwelche massstaebe fuer tutorials festlegst.
im prinzip geht es doch darum, dass wir von anderen noch was lernen koennen. das leute einfach mittels etwas text und code loesungen fuer probleme angeben, die wir alle sicherlich schonmal hatten oder die uns gerade beschaeftigen. dabei kommt es ueberhaupt nicht auf die komplexitaet des themas oder des codes an, oder auf irgendwelche anderen massstaebe. jeder, der denkt, etwas interessantes und hilfreiches hier beitragen zu koennen, soll es bitteschoen posten.
soweit kommts noch, dass du oder andere hier irgendwelche qualitativen und quantitativen bedingungen stellst, die jemand hier zu erfuellen haben muss.

in diesem sinne: danke fuer das tutorial, ich bin sicher damit ist hier einigen anfaengern oder kommenden leuten geholfen.
immer wieder schoen zu sehen, wenn leute mit anderen code, ideen und gedanken austauschen.
_________________
David hat Folgendes geschrieben:
Solang meine Beiträge konstruktiver sind als deiner bin ich zufrieden...

Kein Kommentar notwendig. :rolleyes:
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
David
Super JLI'ler


Alter: 39
Anmeldedatum: 13.10.2005
Beiträge: 315

Medaillen: Keine

BeitragVerfasst am: 17.06.2007, 19:35    Titel: Antworten mit Zitat

Kronos hat Folgendes geschrieben:
David hat Folgendes geschrieben:
Nummerier die Fotos doch pro Sekunde durch... Und ja, das ist egtl wirklich kein Tutorial.

sagt wer? du? find ich amüsant.
nur weil du (wahrscheinlich) stundenlang an tutorials hockst und versuchst irgendwas perfektes rauszubringen, um respekt, genügend dankeschoens oder sonstwas zu ernten, um dein ego zu befriedigen..
das waere ja noch das beste, wenn du hier irgendwelche massstaebe fuer tutorials festlegst.
im prinzip geht es doch darum, dass wir von anderen noch was lernen koennen. das leute einfach mittels etwas text und code loesungen fuer probleme angeben, die wir alle sicherlich schonmal hatten oder die uns gerade beschaeftigen. dabei kommt es ueberhaupt nicht auf die komplexitaet des themas oder des codes an, oder auf irgendwelche anderen massstaebe. jeder, der denkt, etwas interessantes und hilfreiches hier beitragen zu koennen, soll es bitteschoen posten.
soweit kommts noch, dass du oder andere hier irgendwelche qualitativen und quantitativen bedingungen stellst, die jemand hier zu erfuellen haben muss.

in diesem sinne: danke fuer das tutorial, ich bin sicher damit ist hier einigen anfaengern oder kommenden leuten geholfen.
immer wieder schoen zu sehen, wenn leute mit anderen code, ideen und gedanken austauschen.


Komm erstmal runter. Als ich das geschrieben habe war das Tutorial nurmehr ein Codefetzen und zwei Zeilen Text. Das ist maximal ein Codeschnippsel für eine Codedatenbank, oder sonstiges... So wie das Tutorial JETZT aufgebaut ist hab ich überhaupt keine Einwände mehr...

Also, erstmal langsam mit den Vorurteilen.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
xardias
JLI Master


Alter: 38
Anmeldedatum: 28.12.2003
Beiträge: 804
Wohnort: Palo Alto, CA
Medaillen: Keine

BeitragVerfasst am: 17.06.2007, 19:42    Titel: Antworten mit Zitat

Falls es da noch diskussionsbedarf gibt sollte man das von hier an am besten als private message fortführen.. das gibt doch nur wieder stress Wink
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Kronos
Senior JLI'ler



Anmeldedatum: 19.03.2004
Beiträge: 290

Medaillen: Keine

BeitragVerfasst am: 17.06.2007, 19:59    Titel: Antworten mit Zitat

David hat Folgendes geschrieben:

Komm erstmal runter. Als ich das geschrieben habe war das Tutorial nurmehr ein Codefetzen und zwei Zeilen Text. Das ist maximal ein Codeschnippsel für eine Codedatenbank, oder sonstiges... So wie das Tutorial JETZT aufgebaut ist hab ich überhaupt keine Einwände mehr...

Also, erstmal langsam mit den Vorurteilen.

ich habe sogar noch wahrscheinlich dazu geschrieben. also bitte nicht wieder irgendwo was reininterpretieren.
das ganze aendert nichts daran, dass du (und mMn. kein anderer hier) irgendwelche bestimmungen festlegen kannst, die ein beitrag hier zu erfuellen hat. 2 zeilen text und code koennen manchmal mehr helfen als irgendwelche z.B. langatmig, pseudolustige tutorials.
also lass doch das naechste mal einfach deine persoenlichen kommentare zum beitrag an sich, und trag lieber was konstruktives bei. dann ist auch alles in ordnung (und man demotiviert keine anfaenger, neulinge hier, auch wenn das nur eine vermutung ist)

schoenen abend dir noch.
_________________
David hat Folgendes geschrieben:
Solang meine Beiträge konstruktiver sind als deiner bin ich zufrieden...

Kein Kommentar notwendig. :rolleyes:
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 17.06.2007, 20:02    Titel: Antworten mit Zitat

Nehmt euch (eigentlich nur kronos bisher) ein beispiel an den Worten von xardias, ansosten wird der Thread geschlossen und erst auf bitten des TE wieder eröffnet.
_________________
"I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse."
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Maxim
Senior JLI'ler



Anmeldedatum: 28.03.2004
Beiträge: 249

Medaillen: Keine

BeitragVerfasst am: 17.06.2007, 20:08    Titel: Antworten mit Zitat

Déjà-vu Shocked Very Happy
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Asto
JLI'ler


Alter: 37
Anmeldedatum: 30.05.2007
Beiträge: 114
Wohnort: Dortmund
Medaillen: Keine

BeitragVerfasst am: 17.06.2007, 23:23    Titel: Antworten mit Zitat

evt. ich noch zur aufklärung:

@kronos: habe es nicht kenntlich gemacht im 1. beitrag, sry, aber danke für deinen einsatz Smile
an sich hatte david mit dem post ja recht, wobei du ansatzweise ja auch: ich ging halt davon aus, das es sich mehr oder weniger mit den kommentaren selbst erklärt, da ich ja nur ne funktion aus dem buch modifizierte.

ich habe zu beginn als er es geschrieben hatte nur die Einleitung gepostet, mit der gesamten funktion darunter, ohne die erläuterrungen.
daher wäre es eher was für eine funktionssammlung gewesen, als ein tutorial. insofern hatte er recht =)

aber nicht zanken Crying or Very sad
_________________
"A programmer started to cuss, Because getting to sleep was a fuss, As he lay there in bed, Looping 'round in his head, was: while(!asleep()) sheep++;", Unbekannt
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> Tutorials Alle Zeiten sind GMT
Gehe zu Seite 1, 2  Weiter
Seite 1 von 2

 
Gehe zu:  
Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.


Powered by phpBB © 2001, 2005 phpBB Group
Deutsche Übersetzung von phpBB.de

Impressum