OpenGL mit Shader: statt Textur nur schwarz



  • Nachdem mein Programm auf mehreren verschiedenen PC´s funktioniert hat, werden bei einem PC die Texturen nur schwarz dargestellt.
    Hier die dafür relevanten Codeausschnitte:

    Textur laden:

    glGenTextures(1, &Groups[i].Material.Textur.ID);								//Textur-ID bekommen
    glBindTexture(GL_TEXTURE_2D, Groups[i].Material.Textur.ID);						//Textur-ID binden
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);						//In s- und t- Richtung wiederholend
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
    
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    
    if((ImageType == FIT_BITMAP) && (BPP == 24)){						//Wenn Format=Bitmap und 24 bits per pixel
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,	GL_BGR, GL_UNSIGNED_BYTE, bits);}	
    else if((ImageType == FIT_BITMAP) && (BPP == 32)){								//wenn 32 bits per pixel
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,	GL_RGBA, GL_UNSIGNED_BYTE, bits);}
    
    glGenerateMipmap(GL_TEXTURE_2D);										//MipMaps erzeugen
    
    glBindTexture(GL_TEXTURE_2D,0);							//Textur entbinden
    

    Objekt mit Textur zeichnen:

    glActiveTexture(GL_TEXTURE0);								//Textur-Unit 0 aktivieren
    
    for(int i=0;i<NumGroups;i++){
    
    	glUniform4f(in_Material_Loc.Ambient, Groups[i].Material.Ambient[0] ,Groups[i].Material.Ambient[1] ,Groups[i].Material.Ambient[2] ,1.0);	//Material laden
    	glUniform4f(in_Material_Loc.Diffuse, Groups[i].Material.Diffuse[0] ,Groups[i].Material.Diffuse[1] ,Groups[i].Material.Diffuse[2] ,1.0);
    	glUniform4f(in_Material_Loc.Specular, Groups[i].Material.Specular[0],Groups[i].Material.Specular[1],Groups[i].Material.Specular[2],1.0);
    	glUniform1f(in_Material_Loc.Shininess, Groups[i].Material.Shininess);
    	glUniform1i(in_Material_Loc.TextureEnabled, Groups[i].Material.Textur.Name[0]);		//1. Zeichen im Name 0 -> keine Textur
    
    	if(Groups[i].Material.Textur.Name[0]){	
    		glBindTexture(GL_TEXTURE_2D, Groups[i].Material.Textur.ID);		//Wenn Textur, dann Textur binden
    		glUniform1i(in_Material_Loc.Texture, 0);						//Texturunit an Sampler im Shader übergeben
    	}
    	glBindVertexArray(Groups[i].VAO);									//VAO binden und zeichnen
    	glDrawArrays(GL_TRIANGLES, 0, Groups[i].NumTriangles*3);
    }
    

    Fragment-Shader:

    #version 110
    ...
    uniform sampler2D DiffuseTexture;
    ...
    varying vec2 pass_TexCoord;
    ...
    //Pixelfarbe berechnen Anmerkung: einziger Aufruf der Textur und der Texturkoordinaten
    gl_FragColor = vec4(Light.Color * (texture2D(DiffuseTexture, pass_TexCoord).rgb *(AmbientFaktor + DiffuseFaktor*diffuse) + SpecularFaktor*Material.Specular.rgb*specular), 1.0)*attenuation;
    

    Die Specular-Highlights werden korrekt angezeigt(diese multipliziere ich ja nicht mit der Textur). Wenn ich "texture2D(DiffuseTexture, pass_TexCoord).rgb" durch "vec3(0.8,0.8,0.8)" ersetze, dann wird alles wie zu erwarten dargestellt.
    Seltsamerweise funktionieren die mittels Shadowmapping generierten Schatten (Berechnung im Fragment-Shader mit shadow2DProj(ShadowMap, pass_PosInLight).r)

    Wenn ich mir im gDEBugger die Textur anschaue, dann ist sie richtig geladen.

    Hardware, bei der es funktioniert:
    NVIDIA GeForce 9600M GT mit aktuellem Treiber (OpenGL 3.3), Windows 7
    ATI Mobility Radeon HD 5165 mit älterem Treiber (OpenGL 2.1), Windows 7

    Hardware, für die das oben geschilderte zutrifft, bei der es also nicht funktioniert:
    ATI Mobility Radeon X700 mit aktuellem Treiber (OpenGL 2.1), Windows XP

    Hab schon power-of-2 Texturen und vereinfachte Beispielprogramme ohne Ergebnis versucht.
    Was kann da das Problem sein 😕


  • Mod

    pruefste du die opengl errors?

    es koennte out of memory sein (mobile grakas, besonders alte, haben nicht sonderlich viel vram, weil das vom main memory angezapft wird).

    x700 ist urisch alt, was fuer ein "neuster" treiber ist es? der selbe wie bei der 5150? oder eine version vom notebook hersteller?

    was meinst du mit "ab schon power-of-2 Texturen und vereinfachte Beispielprogramme ohne Ergebnis versucht."? kein ergebniss heisst mit anderen programmen sehen die texturen richtig aus? oder auch schwarz?

    es kann auch an falschen mipmaps liegen oder filter flags. stell alles auf nearest, vielleicht klappts.

    gDEBugger zeigt leider nur an was zur graka geschickt wird, nicht wie es auf ihr ausschaut :(. versuch auch mal andere formate, z.b. GL_BGRA_EXT als eingabe, vielleicht macht der treiber beim konvertieren etwas falsch.

    geh sicher dass die texture nur im fragment program deklariert wird, die neueren beiden koennen im vertex programm texturen nutzen, die x700 meines wissens nach nicht, was vielleicht zu einem fehler fuehren koennte bei einer deklaration, selbst wenn du die textur nicht im vertex program nutzt.

    erstmal out-of-ideas.



  • Danke rapso, die Mipmaps waren das Problem.
    Genauer gesagt funktionierte das generieren der Mipmaps mit "glGenerateMipmap" nicht.
    Der gleiche Fehler ist auch auf einer anderen Grafikkarte mit OpenGL 2.1 aufgetreten.

    Komisch kommt mir vor, dass laut glew diese Funktion auch von der x700 unterstützt wird.
    Heißt das, dass mir glew etwas falsches erzählt oder muss ich irgendetwas besonderes machen, damit glGenerateMipmap funktioniert?


  • Mod

    vielleicht ist es einfach nur ein treiber bug.
    normalerweise generiert man sich mipmaps mit einem externen tool, damit keine ladezeit drauf geht.
    falls du es wirklich zur ladezeit machen willst, schreib dir einen einfachen downscaler (einfach nur 2x2 pixel zu einem addieren und durch 4), dann ersparrst du dir die probleme.
    grundsaetzlich wuerde ich selten genutzte funktionen meiden bei ogl 😉



  • für alle, die irgendwann das selbe Problem haben, meine Lösung:

    habe für den OpenGL 2 Programmzweig "glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);" statt "glGenerateMipmap" verwendet, hatte aber immer noch einige Darstellungsfehler.
    Irgenwann habe ich dann power-of-2 Texturen verwendet und der Fehler war weg.
    Anscheinend kann eine Grafikkarte, die non-power-of-two Texturen unterstützt, nicht zwingend auch Mipmaps für solche Texturen erzeugen.


Anmelden zum Antworten