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

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

03.02.2011, 19:14

TGA Dateien für Texturen laden

Hallo,

ja ich meld mich mal wieder :). Mein altes Thema hat sich auf jeden Fall erledigt, meine Festplatte war kaputt (-.-) und konnte deswegen nicht antworten.

So mein neues Problem steht in der Überschrift, ich weiß das es TGA Loader gibt usw. aber ich möchte es gerne selber schaffen. Hier hab ich meine Funktion die das Bild in den RAM lesen soll:


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
// tga_data Variable
struct tga_data{
    unsigned char depth;
    short int w, h;
    unsigned char* data;
};

// TGA Datei laden
tga_data* loadTGA(char* path){            
    tga_data* tga;
    void* tga_pointer;
    FILE* file;
    int pixel, bytes;
    
    // Speicher bereitstellen, Datei oeffnen
    tga = malloc(sizeof(tga_data));    
    file = fopen(path, "rb");

    if(!file){
        fprintf(stderr, "Error: Problem opening TGA file (%s).\n", path);
    }    
    else{
        tga = malloc(sizeof(tga_data));
                                                                          
        // Breite
        fseek(file, 12, SEEK_SET);
        fread(&tga->w, sizeof(unsigned int), 1, file);
           
        // Hoehe
        fseek(file, 14, SEEK_SET);
        fread(&tga->h, sizeof(unsigned int), 1, file);
        
        // Bytes pro Pixel
        fseek(file, 16, SEEK_SET);
        fread(&tga->depth, sizeof(unsigned int), 1, file);
        
        // Anzahl der Pixel, Bytes
        pixel = tga->depth/8;
        bytes = tga->h*128*pixel;
        
        tga = malloc(sizeof(unsigned char)*bytes);

        // Bildinformationen
        fseek(file, 18, SEEK_SET);
        fread(tga->data, sizeof(unsigned char), bytes, file);

        fclose(file);
    }

    return tga;
}


Das Bild soll dann mithilfe dieser Funktion geladen werden:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void loadTexture(){  
    tga_data* texture = loadTGA("texture.tga");
                    
    glBindTexture(GL_TEXTURE_2D, *textures);
    glTexImage2D(GL_TEXTURE_2D,
                 0,                      
                 1,          
                 128,          
                 128,  
                 0,       
                 GL_RGB,           
                 GL_UNSIGNED_BYTE,  
                 texture->data);  

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}


So, das erste was nicht verstehe: warum ließt der bei "// Breite" nicht die Breite der Datei ein? Ich hab mir das Format von TGAs angeschaut. Es kommt immer, egal was ich mache nur "10140" (oder so) raus, bei Höhe funktioniert dies allerdings korrekt (128px).

Und natürlich warum es insgesammt nicht Funktioniert, die Pixeldaten sollte ja jetzt in "texture->data" enthalten sein.

MfG DK

[EDIT]

Zudem will er mir nicht malloc compilieren, obwohl ich doch einen Zeiger benutze?

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (03.02.2011, 19:53)


dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

03.02.2011, 22:49

Dass er das nicht kompilieren will liegt wohl dran dass dein Code da ein Mittelding aus C und C++ ist und du offenbar versuchst ihn mit einem C++ Compiler zu kompilieren. C++ erlaubt keine implizite Konvertierung von void*. D.h. du brauchst einen cast:

C-/C++-Quelltext

1
tga = (tga_data*)malloc(sizeof(tga_data));


Der Grund warum beim Einlesen der Werte was schief läuft ist ganz einfach dass du zuviel einliest. Höhe und Breite sind nur 16bit integer, das Bit per Pixel Feld hat sogar nur 1 Byte. Du liest aber in allen Fällen einen unsigned int (4 Byte) ein was dazu führt dass über den struct Member hinaus in den darauf folgenden geschrieben und dessen Wert verändert wird. Die Berechnung deiner Variable bytes stimmt auch nicht (funktioniert nur wenn das Bild 128 Pixel breit ist). Abgesehen davon solltest du beachten dass eine TGA Datei auch durch RLE komprimiert sein kann, in dem Fall werden die Farbdaten kürzer sein als Width * Height * BytesPerPixel.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

04.02.2011, 14:23

Zitat

Die Berechnung deiner Variable bytes stimmt auch nicht (funktioniert nur wenn das Bild 128 Pixel breit ist). Abgesehen davon solltest du beachten dass eine TGA Datei auch durch RLE komprimiert sein kann, in dem Fall werden die Farbdaten kürzer sein als Width * Height * BytesPerPixel.


Das war nur zum Test da tga->w ja falsch eingelesen wurde, das Bild ist definitiv nicht RLE komprimiert. Es kommt jetzt keine Fehlermeldung mehr und das Programm startet, angezeigt wird die Textur trotzdem nicht. Hier mal alles an relevantem 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
// tga_data Variable
struct tga_data{
    unsigned char depth;
    short int w, h;
    unsigned char* data;
};
                
// TGA Datei laden
tga_data* loadTGA(char* path){            
    tga_data* tga = NULL;
    FILE* file;
    int pixel, bytes;
    
    // Speicher bereitstellen, Datei oeffnen
    tga = (tga_data*) malloc(sizeof(tga_data));    
    file = fopen(path, "rb");

    if(!file){
        fprintf(stderr, "Error: Problem opening TGA file (%s).\n", path);
    }    
    else{
        tga = (tga_data*) malloc(sizeof(tga_data));
                                                                          
        // Breite
        fseek(file, 12, SEEK_SET);
        fread(&tga->w, 2, 1, file);
         
        // Hoehe
        fseek(file, 14, SEEK_SET);
        fread(&tga->h, 2, 1, file);
          
        // Bytes pro Pixel
        fseek(file, 16, SEEK_SET);
        fread(&tga->depth, 1, 1, file);
         
        // Anzahl der Pixel, Bytes
        pixel = tga->depth/8;
        bytes = tga->h*tga->w*pixel;
             
        tga = (tga_data*) malloc(sizeof(char)*bytes);
        
        // Bildinformationen
        fseek(file, 18, SEEK_SET);
        fread(tga->data, sizeof(unsigned char), bytes, file);

        fclose(file);
                
        // BGR(A) zu RGB(A) umwandeln
        if(pixel >= 3){
            unsigned char tmp;

            /*for(int i = 0; i < bytes; i += pixel){
                tmp = tga->data[i];
                tga->data[i] = tga->data[i+2];
                tga->data[i+2] = tmp;
            }*/
        }
    }

    return tga;
}

GLuint textures;                                           // Texturen

// Textur laden
void loadTexture(){  
    tga_data* texture = loadTGA("texture.tga");
         
    glGenTextures(1, &textures);                    
    glBindTexture(GL_TEXTURE_2D, textures);
    glTexImage2D(GL_TEXTURE_2D,
                 0,                      
                 GL_RGB,          
                 texture->w,          
                 texture->h,  
                 0,       
                 GL_RGBA,           
                 GL_BYTE,   
                 texture->data);  

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}

// Graphische Ausgabe
void draw(){     
    glBindTexture(GL_TEXTURE_2D, textures);
     
    // Wuerfel  
    glBegin(GL_QUADS); 
        glTexCoord2f(0.0, 0.0); glVertex3f(0-10/2, 0-10/2, 0-10/2);
        glTexCoord2f(0.0, 1.0); glVertex3f(0-10/2, 0-10/2+10, 0-10/2);
        glTexCoord2f(1.0, 1.0); glVertex3f(0+10/2, 0-10/2+10, 0-10/2);
        glTexCoord2f(1.0, 0.0); glVertex3f(0+10/2, 0-10/2, 0-10/2);
    glEnd();  
}

int main(int argc, char **argv){    
    // Initialisierung
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGB);
    
    // Fenster
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Texturen");
    glutSetCursor(GLUT_CURSOR_NONE); // Cursor loeschen
    
    // Ausgabe
    glutReshapeFunc(reshape);
    glutDisplayFunc(display);
    // glutIdleFunc(display); // durch Timer ersetzt
    
    // Eingabe
    glutKeyboardFunc(keyPressed);
    glutKeyboardUpFunc(keyReleased);
    glutPassiveMotionFunc(mouseMotion);
    
    // Tiefenvergleich aktivieren
    glEnable(GL_DEPTH_TEST);
    
    // 2D Texturen aktivieren
    glEnable(GL_TEXTURE_2D);
    
    // Texturen laden
    loadTexture();
        
    Timer(0);
    glutMainLoop();    
    return 0;    
}


Ich bekomme es außerdem nicht hin texture->data auszugeben, mache ich vielleicht bei glut etwas falsch oder ist das Laden noch nicht korrekt? Der Inhalt der for-Schleife um BGR in RGB umzuwandeln bringt das Programm zum absturz, eine die z.B. nur "ok" schreibt macht dies nicht und es werden so viele "ok"s ausgegeben wie Speicher belegt wurde (ich gehe mal davon aus das dies richtig ist).

MfG

[EDIT]

Hab mir gerade mal das Buch Beginning OpenGL Game Programming geladen und ausgedruckt und les mal den Teil über Texturen :)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (04.02.2011, 19:07)


DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

4

06.02.2011, 19:42

Ok, ich bentzt VBOs... (ich sollte mal weiterlesen bevor ich was ausprobiere :))

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »DeKugelschieber« (07.02.2011, 11:34)


Werbeanzeige