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

1

06.01.2007, 18:57

Fehler bei eigenem BMP-Loader

Hallo,

ich arbeite grad an einem Spiel mit Direct3D und würde gerne Texturen ohne Hilfe von D3DX erstellen. Deshalb habe ich mir einen eigenen Loader geschrieben, funktioniert auch gut:


(Link)


Allerdings nur, so lange die Breite nicht größer als 100 Pixel ist. Ist das der Fall, passiert folgendes:


(Link)


Hier ist mal der Code zum laden:

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
std::basic_ifstream<char> Input (Filename.c_str (), std::ios::binary);

Input.read (reinterpret_cast<char *> (&bmfh), sizeof (bmfh));

Input.read (reinterpret_cast<char *> (&bmih), sizeof (bmih));

Texture->Width_ = bmih.biWidth;
Texture->Height_ = Abs (bmih.biHeight);

// Buffer für Bitmapdaten

RGBData *Buffer = new RGBData[Texture->Width_ * Texture->Height_];

std::basic_ofstream<wchar_t> Output1 (L"Test1.txt");

// Pixeldaten herauslesen

for (unsigned long y = 0; y < Texture->Height_; y++)
{
    for (unsigned long x = 0; x < Texture->Width_; x++)
    {
        // Zwischenspeicher für Farben

        unsigned char Blue = 0;
        unsigned char Green = 0;
        unsigned char Red = 0;

        // Daten lesen

        Input.read (reinterpret_cast<char *> (&Blue), sizeof (Blue));
        Input.read (reinterpret_cast<char *> (&Green), sizeof (Green));
        Input.read (reinterpret_cast<char *> (&Red), sizeof (Red));

        // Daten speichern

        Buffer[x + y * Texture->Width_].Blue_ = Blue;
        Buffer[x + y * Texture->Width_].Green_ = Green;
        Buffer[x + y * Texture->Width_].Red_ = Red;

        if (Buffer[x + y * Texture->Width_].Blue_ == 255
            && Buffer[x + y * Texture->Width_].Green_ == 0
            && Buffer[x + y * Texture->Width_].Red_ == 255)
        {
            Output1 << L".";
        }
        else
        {
            Output1 << L"X";
        }
    }
    Output1 << std::endl;;
}

Output1.close ();

Input.close ();


Das ist natürlich nur der erste Teil, aber durch den Output1-Stream habe ich festgestellt, dass der Fehler bereits hier auftritt.

Ich komme hier selber einfach nihct mehr weiter, und hoffe deshalb auf eure Hilfe, danke schonmal dafür.

mfg Manuel

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

06.01.2007, 20:11

die scanlines in einer bmp datei sind 4 byte alinged. d.h. wenn du am ende einer zeile bist, musst du noch eine bestimmte anzahl an leerbytes lesen/überspringen, bis du bei einem vielfachen von 4 bytes bist. erst dann fängt die nächste zeile an (ich könnte mir vorstellen, dass das hier das problem ist).
nur für den fall, dass du das nicht berücksichtigt hast (was ich angesichts der tatsachen aber nicht glaub ;) ): es ist immer aufzupassen beim lesen von ganzen structs aus einer datei (stichwörter: alignment, packing, padding bytes); nur für den fall, dass du das nicht berücksichtigt hast (was ich aber eher nicht glaub).

und noch ein kleines codeschnipsel, das 24 bit bmps lädt; zur inspiration ;):

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
dword* bmp::loadBMP( const char* fileName, int* width, int* height )
{

    FILE* file = fopen( fileName, "rb" );

    if( file == 0 )
        return 0;

    BMPFileHeader header;
    BMPInfoHeader info;

    fread( &header, sizeof( BMPFileHeader ), 1, file );

    if( header.bfType != 19778 )
    {
        fclose( file );
        return 0;
    }

    fread( &info, sizeof( BMPInfoHeader ), 1, file );

    if( info.biBitCount != 24 )
    {
        fclose( file );
        return 0;
    }

    *width = info.biWidth;
    *height = info.biHeight;
    dword* pBmp = new dword[info.biWidth*info.biHeight];

    if( pBmp == 0 )
    {
        fclose( file );
        return 0;
    }

    fseek(file, header.bfOffBits, SEEK_SET);
    int padding = ( *width * 3 ) % 4;

    for( int y = *height-1; y >= 0; --y )
    {
        dword* scanline = pBmp + y * (*width);
        for( int x = 0; x < *width; ++x )
        {
            fread( scanline, 3, 1, file );
            *scanline++ |= 0xFF000000;
        }

        fseek( file, padding, SEEK_CUR );    // skip padding

    }

    fclose( file );

    return pBmp;
}

3

06.01.2007, 21:58

Hey, danke, dass mit dem Alignment hab ich bisher noch nicht gewusst, jetzt funktioniert alles wie es sollte. :)

Werbeanzeige