D3DXCreateTextureFromFileInMemoryEx

06/28/2014 01:16 Terrat#1
Hallo,
ich möchte gerne diese Funktion hier nutzen um ein PNG in ein D3D zu laden. Habe mich auch schon etwas "angelesen". Ein Beispiel habe ich vor mir welches ich verstehe. Aber wie kriege ich das PNG als so nen Code ?
06/28/2014 02:10 Jeoni#2
Sind doch nur die rohen Bytes, aus denen die Datei besteht in einem Array, oder irre ich mich da? Ist doch nicht zu schwer ein kleines Tool zu schreiben, was Byte für Byte (Binär) aus der gewünschten Datei ausliest und diese in einen String formatiert bspw. in eine Datei ausgibt.
Hab diesen C++-Code hier eben zusammengeklatscht. Es ist schon spät, daher verzeih bitte Flüchtigkeitsfehler oder fehlende Performanceoptimierungen (Bytes buffern).
Code:
#include <fstream>
#include <iomanip>
#include <string>

int main()
{
	const std::string file("C:\\Users\\Jeoni\\Desktop\\MyFile.png");

	std::ifstream in;
	std::ofstream out;
	int data = 0; // using zero initialized int here, so that LSByte is filled by in.read and everything gets well formated when written to out. this may be optimized
	unsigned int counter = 0;

	in.open(file, std::ifstream::in | std::ifstream::binary);
	out.open(file + "_code.txt", std::ofstream::out | std::ofstream::trunc);

	out << std::hex << std::setfill('0');
	out << "BYTE array[] = {";

	do
	{ // buffersize is 1 byte. increase it for optimization if you want to
		in.read(reinterpret_cast<char*>(&data), 1);
		if (counter++ % 16 == 0) out << std::endl << "\t";
		out << "0x" << std::setw(2) << data << ", ";
	} while (!in.eof());

	in.close();
	out.seekp(out.tellp() - std::streampos(2)); // overwrite the last comma and space
	out << std::endl << "};";
	out.close();

	std::cout << "Done." << std::endl;
	std::cin.get();
	return 0;
}
Selbst die Datei (samt Pfad) ist hardgecodet, aber es tut, was es soll, musst den Pfad selber ändern oder zur Laufzeit abfragen oder so :D
Outputdatei ist danach im gleichen Ordner, wie die Inputdatei, mit "_code.txt" am Dateinamen dran. Das ganze geht logischerweise mit sämtlichten Dateien, nicht nur PNGs.
MfG
Jeoni
06/29/2014 13:08 Terrat#3
Quote:
Originally Posted by Jeoni View Post
Sind doch nur die rohen Bytes, aus denen die Datei besteht in einem Array, oder irre ich mich da? Ist doch nicht zu schwer ein kleines Tool zu schreiben, was Byte für Byte (Binär) aus der gewünschten Datei ausliest und diese in einen String formatiert bspw. in eine Datei ausgibt.
Hab diesen C++-Code hier eben zusammengeklatscht. Es ist schon spät, daher verzeih bitte Flüchtigkeitsfehler oder fehlende Performanceoptimierungen (Bytes buffern).
Code:
#include <fstream>
#include <iomanip>
#include <string>

int main()
{
	const std::string file("C:\\Users\\Jeoni\\Desktop\\MyFile.png");

	std::ifstream in;
	std::ofstream out;
	int data = 0; // using zero initialized int here, so that LSByte is filled by in.read and everything gets well formated when written to out. this may be optimized
	unsigned int counter = 0;

	in.open(file, std::ifstream::in | std::ifstream::binary);
	out.open(file + "_code.txt", std::ofstream::out | std::ofstream::trunc);

	out << std::hex << std::setfill('0');
	out << "BYTE array[] = {";

	do
	{ // buffersize is 1 byte. increase it for optimization if you want to
		in.read(reinterpret_cast<char*>(&data), 1);
		if (counter++ % 16 == 0) out << std::endl << "\t";
		out << "0x" << std::setw(2) << data << ", ";
	} while (!in.eof());

	in.close();
	out.seekp(out.tellp() - std::streampos(2)); // overwrite the last comma and space
	out << std::endl << "};";
	out.close();

	std::cout << "Done." << std::endl;
	std::cin.get();
	return 0;
}
Selbst die Datei (samt Pfad) ist hardgecodet, aber es tut, was es soll, musst den Pfad selber ändern oder zur Laufzeit abfragen oder so :D
Outputdatei ist danach im gleichen Ordner, wie die Inputdatei, mit "_code.txt" am Dateinamen dran. Das ganze geht logischerweise mit sämtlichten Dateien, nicht nur PNGs.
MfG
Jeoni
Dankö :) hat geklapt war ja vollkomen auf dem falschen weg ;)
06/29/2014 14:49 MrSm!th#4
Ich würde ja eher eine der XXXFromFile Textur Methoden nutzen, die Datei zur Laufzeit auslesen und mit dem ausgelesenen Inhalt die D3DXCreateTextureFromFileInMemory aufrufen oder, wenn es keine physische Datei sein darf, mit Ressourcen und den dafür vorgesehenen Funktionen arbeiten, als mir den Quellcode mit solchen Arrays vollzumüllen.
07/03/2014 18:08 Ende!#5
Quote:
Originally Posted by MrSm!th View Post
Ich würde ja eher eine der XXXFromFile Textur Methoden nutzen, die Datei zur Laufzeit auslesen und mit dem ausgelesenen Inhalt die D3DXCreateTextureFromFileInMemory aufrufen oder, wenn es keine physische Datei sein darf, mit Ressourcen und den dafür vorgesehenen Funktionen arbeiten, als mir den Quellcode mit solchen Arrays vollzumüllen.
Ich mach's auch meistens so, hat durchaus seine Vorteile. Zum Beispiel wenn man auf Manual-Mapping setzt, gestaltet sich das mit Resources nicht so einfach (die Resource-Routines erfordern einen Eintrag in der Module-List im PEB). Hab dazu noch folgendes Makro, um die "Resources" (die Byte-Arrays) in 'ne extra PE-Section zu moven:
Code:
#ifdef _MSC_EXTENSIONS
#  pragma   section(".nrsrc", read)
#  define   NAREA_RSRC __declspec(allocate(".nrsrc"))
#else
#  define   NAREA_RSRC
#endif
Nutzt man dann einfach so:
Code:
NAREA_RSRC static const uint8_t myFancyResource[] = 
{
   0x00, 0x11, 0x22, 0x33, 0x44, 0x55, /* ... */
};
Klappt nur bei MSVC, wird ansonsten einfach ignoriert.
07/04/2014 13:08 MrSm!th#6
Dass man es beim hacken anders macht als in einem legit Projekt, wo man auf guten Code Wert legt, ist nichts neues.
War nur ein allgemeiner Vorschlag zur Lösung des Problems in den allermeisten Fällen. Ich bezweifle, dass der TE sich mit Edge Cases wie Manual Mapping vor Reverse Engineering oder Anti Cheats schützen muss.