Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

john

Alter Hase

Beiträge: 786

Beruf: Schüler

  • Private Nachricht senden

11

30.04.2006, 22:18

Tja, so ist das nun mal. :rolleyes: ;)
mfg
john

12

30.04.2006, 22:37

D3DX ist heute doch unumgänglich, oder ladet ihr heute noch jede Textur noch manuell?

mfg Markus

Anonymous

unregistriert

13

30.04.2006, 23:03

Zitat von »"lannms11"«

D3DX ist heute doch unumgänglich
Sehr guter Witz. Wofür? Um eine Projektionsmatrix zu erstellen? Lachhaft. Man merkt, tiefe Materie beherrschst Du nicht.

Zitat von »"lannms11"«

ladet ihr heute noch jede Textur noch manuell?
Ja und sogar zurecht! Besseres Filtermanagement, höherer Lernpegel, keine Zusatzlibs, kleinere Dateien, flexibler, erweiterbarer, usw. usw. usw. Die Vorteile eines eigenen Loaders übersteigen die von D3DX Texturladefunktionen bei weitem.

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

14

01.05.2006, 00:31

Wo du schon dabei bist... kennst du ein gutes Tut in welchem ein eigener Loader entwickelt wird? Im Prinzip gehts ja nur darum, zu wissen WIE D3D eine Texture haben möchte...

//edit:
Hab den anderen Post gelesen... die Frage ist damit beantwortet... ^^
http://germangamedev.de/index.php?site=article&id=11
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Anonymous

unregistriert

15

01.05.2006, 00:38

Black-Panther
ACHTUNG UR ALTER CODE!

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// ///////////////////////////////////////////////////////////////////////////

// PUBLIC

// 

// Funktion zum vertauschen von Daten

// ///////////////////////////////////////////////////////////////////////////

void flip (unsigned char* image, unsigned long bytesPerLine, unsigned long height)
{
        // Speicher bereit stellen

    unsigned char *line1 = new unsigned char [bytesPerLine];
    unsigned char *line2 = new unsigned char [bytesPerLine];    

        // Spiegeln

    for (unsigned long i=0; i<height/2; ++i)
    {
        memcpy (line1, &image [i * bytesPerLine], bytesPerLine);
        memcpy (line2, &image [(height - 1 - i) * bytesPerLine], bytesPerLine);

        memcpy (&image [i * bytesPerLine], line2, bytesPerLine);
        memcpy (&image [(height - 1 - i) * bytesPerLine], line1, bytesPerLine);
    }

        // Aufräumen nach der Party

    delete [] line1;
    delete [] line2;
}

// ///////////////////////////////////////////////////////////////////////////

// PUBLIC

// 

// Läd eine Bitmap in eine Direct3D Surface

// ///////////////////////////////////////////////////////////////////////////

::IDirect3DSurface9* loadSurfaceFromFile (const std::basic_string<wchar_t>& fileName, ::IDirect3DDevice9* device)
{
    DEBUG_STACK;

        // Sicherheitstests

    if (!device)
        EXCEPTION (L"Invalid parameters");

        // Hilfsstrukturen /-variabeln

    ::BITMAPFILEHEADER  FileHeader;     // BMP Datei Header

    ::BITMAPINFOHEADER  InfoHeader;     // BMP Datei Info Header

    unsigned long       mem;            // Zwischenspeicher

    unsigned long       pitch;          // lPitch der Surface >> 1

    void*               dest;           // Für die Pixeldaten

    ::D3DLOCKED_RECT    rectLock;       // Enthält Speicheradresse

    ::IDirect3DSurface9 *result = NULL; // Rückgabesurface


        // BMP Datei öffnen

    ::HANDLE file = ::CreateFile (fileName.c_str(),         // Datei Name

                                  GENERIC_READ,             // Nur lesen

                                  FILE_SHARE_READ,          // andere auch

                                  NULL,                     // keine Attrib.

                                  OPEN_EXISTING,            // exist. Datei

                                  FILE_ATTRIBUTE_NORMAL,    // norm.Attrib.

                                  NULL);                    // unbenutzt


        // Hat es geklappt?

    if (file == INVALID_HANDLE_VALUE) 
        EXCEPTION (L"Invalid file! (FILE_SHARE_READ)");

        // BMP Header einlesen

    if (!::ReadFile(file, &FileHeader, sizeof(FileHeader), &mem, NULL)) 
    {
        ::CloseHandle(file);
        EXCEPTION (L"Invalid file! (BMPFILEHEADER)");
    }

        // BMP Info-Header einlesen

    if (!::ReadFile(file, &InfoHeader, sizeof(InfoHeader), &mem, NULL)) 
    {
        ::CloseHandle(file);
        EXCEPTION (L"Invalid file! (BMPINFOHEADER)");
    }

        // Hat das Bitmap das gewünschte Format

    if (InfoHeader.biBitCount != 24) 
    {
        ::CloseHandle(file);
        EXCEPTION (L"Invalid file! (File must be 24bpp)");
    }

        // Initialisiere Surface Objekt im Bildschirmformat

    if (device->CreateOffscreenPlainSurface (InfoHeader.biWidth, InfoHeader.biHeight, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &result, NULL) != D3D_OK)
    {
        ::CloseHandle(file);
        EXCEPTION (L"Invalid file! (BMPFILEHEADER)");
    }

        // Speicher dynamisch bereitstellen

    unsigned char* data = new unsigned char [InfoHeader.biSizeImage];

        // Lies die eigentlichen Bilddaten des BMP

    if (!::ReadFile (file, data, InfoHeader.biSizeImage, &mem, NULL)) 
    {
        ::CloseHandle(file);
        EXCEPTION (L"Invalid file! (Reading imagedata)");
    }

        // Schliesse die Datei wieder

    ::CloseHandle(file);

        // Surface verriegeln

    if (result->LockRect (&rectLock, NULL, 0) != D3D_OK) 
        EXCEPTION (L"IDirect3DSurface9::LockRect");

    pitch   = rectLock.Pitch >> 2; // Byte/2 weil 32bpp = 4 Byte

    dest    = (unsigned long *)rectLock.pBits;

    flip (data, InfoHeader.biSizeImage/InfoHeader.biHeight, InfoHeader.biHeight);

        // Wir müssen jeden Pixel umwandeln, also Pixel für Pixel

        // das Bild kopieren, und zwar von unten nach oben

    for (unsigned long cy=0; cy<static_cast<unsigned long>(InfoHeader.biHeight); ++cy) 
    {
        for (unsigned long cx=0; cx<static_cast<unsigned long>(InfoHeader.biWidth); ++cx) 
        {
                // Farbe mit Alpha = 100 % initialisieren

            unsigned long color = 0xff000000;

                // Kopiere 24 Bit Farbe in den 32 Bit Wert

            memcpy (&color, &data[(cy*InfoHeader.biWidth + cx)*3], sizeof(unsigned char)*3);

                // Pixel in 32 Bit Farbe schreiben

            ((unsigned long*)dest)[cx + (cy*pitch)] = color;
        }
    }

        // Entriegeln der Surface nach dem Schreiben der Daten

    result->UnlockRect();

        // Speicher freigeben

    if (data != NULL)
    {
        delete [] data;
        data = NULL;
    }

    return (result);
}

Laden einer Textur

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// ///////////////////////////////////////////////////////////////////////////

// PUBLIC 

//

// Läd eine 24Bit (!!!) Bitmap in den Texturmanager

// ///////////////////////////////////////////////////////////////////////////

void texture::loadTexture (const std::basic_string<wchar_t>& fileName)
{
        // Ist die zu ladene Textur schon enthalten?

    if (textures_.find(fileName) != textures_.end()) 
        return;

        // Hilfsstrukturen

    ::IDirect3DTexture9*    texture         = NULL;
    ::IDirect3DSurface9*    surface         = loadSurfaceFromFile (fileName, direct3d::getInstance().direct3d_device_);
    ::D3DSURFACE_DESC       desc_surface;
    ::D3DLOCKED_RECT        locked_surface;
    ::D3DLOCKED_RECT        locked_texture;

        // Daten der Surface abfragen

    surface->GetDesc (&desc_surface);

        // Größe berechnen

    unsigned long size = desc_surface.Width*desc_surface.Height*2*2;
        // Speicher für Bilddaten bereitstellen

    unsigned char* data = new unsigned char [size*sizeof(unsigned char)];

        // Bilddaten aus der Surface kopieren

    surface->LockRect (&locked_surface, NULL, D3DLOCK_READONLY);
    memcpy (data, locked_surface.pBits, size * sizeof(unsigned char));
    surface->UnlockRect ();
       
        // Surface freigeben

    safeRelease (surface);
    
        // Initialisiere das IDirect3DTexture9 Objekt

    if (direct3d::getInstance().direct3d_device_->CreateTexture 
       (desc_surface.Width, desc_surface.Height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &texture, NULL) != D3D_OK)
        EXCEPTION (L"IDirect3DDevice9::CreateTexture(); failed!");

          
        // Farbdaten von der Surface in die Textur kopieren

    texture->LockRect (0, &locked_texture, NULL, 0);
    memcpy (locked_texture.pBits, data, size * sizeof(unsigned char));
    texture->UnlockRect (0);

    delete [] data;

        // Alphakey setzen

    setAlphakey (&texture, 0xFFFF00FF, 0x00FFFFFF);

        // Textur und Dateiname in den Manager einfügen

    textures_.insert (std::make_pair(fileName, texture));
}
Setzen eines Alphakeys

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// ///////////////////////////////////////////////////////////////////////////

// GLOBAL

// 

// Gibt einer Textur einen Alphakey

// ///////////////////////////////////////////////////////////////////////////

void setAlphakey (::IDirect3DTexture9** texture, unsigned long colorkey, unsigned long alpha)
{
        // Hilfsobjekte

    static ::D3DSURFACE_DESC    describe;
    static ::D3DLOCKED_RECT     rect;

        // Surfacebeschreibung holen

    (*texture)->GetLevelDesc(0, &describe);

        // Textur verriegeln

    (*texture)->LockRect(0, &rect, NULL, 0);

        // 32 Bit Pointer auf Bilddaten in der Textur

    for (unsigned long y=0; y<describe.Height; ++y) 
    {
        for (unsigned long x=0; x<describe.Width; ++x) 
        {
            if ((static_cast<unsigned long*>(rect.pBits))[describe.Width*y+x] == colorkey)
                (static_cast<unsigned long*>(rect.pBits))[describe.Width*y+x] = alpha;
        }
    }

        // Textur entriegeln

    (*texture)->UnlockRect(0);
}

Die 1., 3. und 4. Funktion kann man für alles benutzen. Die 2. muß man je nach Format anpassen um eine Surface zu laden.

Vorteil:
- Schnell
- kleiner von der Programmgröße
- keine Unnütze Zusatzlib
- Lerneffekt ist höher
- Flexibler (kann man beliebig erweitern)

Klar man kann auch Direkt die Daten in die Textur laden, jedoch könnte es dort Formatierungsprobleme geben. D3DXCreateTexture-Dingens macht eigentlich absolut nichts anderes als meine Funktion. Nur sie sieht unschöner aus und man kann nicht an ihr soviel basteln ;)

Easy? Easy!

16

01.05.2006, 08:09

Lass mich raten. Das ".dds" und ".x" Format is kompletter Mist, oder?

mfg Markus

Anonymous

unregistriert

17

01.05.2006, 11:03

lannms11
Warum auf einmal so unsachlich?

X-Format ist ein 3D Format und keine Textur. Das X-Format gibt es schon seit Direct3D3 und da gab es noch keine Direct3D Extensions. X-Formate lade ich ebenfalls per Hand mit den IDirectXFile Interface. Dafür D3DX zu benutzen und sich selbst die Handschellen anzulegen ist etwas - bescheuert. Da man auch hier wieder nur diverse Effekte (damit meine ich jetzt nicht Grafikeffekte) gar nicht oder nur über größere Umwege erreichen kann.

DirectDrawSurface-Files benutze ich nicht, ich benutz ein eigenes Format. Und wenn: David Reinig hat mal eine feine Formatbeschreibung rausgebracht, womit ich mir ebenfalls damals einen Loader geschrieben habe:
http://www.germangamedev.de/index.php?site=article&id=21

Ich sehe bisher keinen einzigen Vorteil von Direct3D Extensions in Deinen bisherigen Argumenten, sondern eher allgemeinen Kram womit D3DX schöngeredet wird, aber was man viel per Hand machen kann und man danach viel Flexibler ist.

Aber hier gleich rumzuwerfen "alles mist". Zeugt eher von "Mama, der hat mich net mehr lieb, der ist blöd".

Denk mal drüber nach, was Du für einen Müll verzapfst.

- Patrick

Phili

unregistriert

18

01.05.2006, 14:36

@nix da ich stelle auch gerade alles auf D3D ohne X um. Ich hab alles(Auch die projetionsmatrix;-) ;) ) bis auf die Texturen bereits "Gereinigt". Und wegen der Texturen hab ich mich ja bereits letztens erkundigt...

Aber D3DX ist halt doch gerade am Anfang ziemlich verlockend ...

Anonymous

unregistriert

19

01.05.2006, 14:45

Phili
Verlockend ja, sind Zigaretten auch - nur davon los zu kommen, ist ne andere Geschichte. Doch am Ende hat man mehr davon wenn man es nie benutzt hat.

Projektionsmatrix:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// ///////////////////////////////////////////////////////////////////////////

// PUBLIC

// 

// Erstellung einer perspektivischen Projektionsmatrix

// ///////////////////////////////////////////////////////////////////////////

void direct3d::createProjection (float fov, float aspect, float nearPlane, float farPlane)
{
        // Sicherheitsabfragen

    if (abs<float>(farPlane-nearPlane) < epsilon<float>::value)
        return;
    if (abs<float>(sin<float>(deg2rad<float>(fov)/2)) < epsilon<float>::value)
        return;

        // Zwischenwerte berechnen

    const float cosin  = cos<float>(deg2rad<float>(fov)/2) / sin<float>(deg2rad<float>(fov)/2);
    const float farinv = farPlane / (farPlane - nearPlane);

        // Temporäres Objekt

    ::D3DMATRIX temp;

        // Einheitsmatrix erstellen

    matrixIdentity (&temp);

        // Matrix verändern

    temp._11 = aspect*cosin;
    temp._22 = 1.0f*cosin;
    temp._33 = farinv;
    temp._34 = 1.0f;
    temp._43 = -farinv*nearPlane;
    temp._44 = 0.0f;

        // Projektionsmatrix setzen

    direct3d_device_->SetTransform (D3DTS_PROJECTION, &temp);
}

Auch hier wieder: Alter Code

Black-Panther

Alter Hase

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

20

01.05.2006, 14:48

Und statt Effekten soll man verwenden...?
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Werbeanzeige