2012-03-26 14 views
0

Ich muss eine indizierte Grafikdatei anzeigen, die zusätzlich pro Pixel Alphakanal hat. Außerdem muss ich sicherstellen, dass ich die Palette jederzeit ändern kann und das resultierende Bild ändert sich auch. Dazu habe ich zuerst Pixel Precomputing für Software verwendet, aber das war einfach zu langsam für Echtzeit-Rendering. Daher entschied ich mich, einen Shader zu schreiben, der indexierte Texturen auf der GPU-Seite verarbeiten wird. Das Problem ist, dass die zweite Textur (rec_colors) nicht geladen wird (zumindest scheint es so zu sein - jedes Texel, das von diesem Sampler gelesen wird, erscheint völlig leer).Mehrere Textureinheiten mit Fragment Shader funktionieren nicht

Daten von Null Textur lesen richtig, in schwarzem Bild mit dem rechten alpha resultierenden :)

Shader-Initialisierung bezogenen Code:

Application::Display->GetRC(); 
glewInit(); 
if(!GLEW_VERSION_2_0) return false; 

char* code_frag = loadCode("shader.frag"); 
char* code_verx = loadCode("shader.verx"); 

aShader_palette = glCreateShader(GL_FRAGMENT_SHADER); 
//glShaderSource(aShader_palette, 1, &aShaderProgram_palette, NULL); 
glShaderSource(aShader_palette, 1, (const GLchar**)&code_frag, NULL); 
glCompileShader(aShader_palette); 

GLint compiled = 0; 
glGetShaderiv(aShader_palette, GL_COMPILE_STATUS, &compiled); 

if(!compiled) 
{ 
    /* error-handling */ 
} 

GLuint texloc = glGetUniformLocation(aShader_palette, "rec"); 
glUniform1i(texloc, 0); 
texloc = glGetUniformLocation(aShader_palette, "rec_colors"); 
glUniform1i(texloc, 1); 

glsl_palette_Program = glCreateProgram(); 
glAttachShader(glsl_palette_Program, aShader_palette); 
glLinkProgram(glsl_palette_Program); 

und Rendering Gerichtet:

glPushAttrib(GL_CURRENT_BIT); 
glColor4ub(255, 255, 255, t_a); // t_a is overall alpha of sprite displayed 
glUseProgram(glsl_palette_Program); // this one is a compiled/linked shader declared above 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->m_SpriteData[idx].texture); 
glActiveTexture(GL_TEXTURE1); // at this point, it looks like texture unit is actually changed (I checked that via glGetIntegerv) 
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, this->m_PaletteTex); 
glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, 256, 1, GL_RGBA, GL_UNSIGNED_BYTE, palette); // update possibly changed palette on each render 
glActiveTexture(GL_TEXTURE0); 
glBegin(GL_QUADS); 
    glTexCoord2i(0, 0); 
    glVertex2i(x, y); 
    glTexCoord2i(0, this->GetHeight(idx)); 
    glVertex2i(x, y+this->GetHeight(idx)); 
    glTexCoord2i(this->GetWidth(idx), this->GetHeight(idx)); 
    glVertex2i(x+this->GetWidth(idx), y+this->GetHeight(idx)); 
    glTexCoord2i(this->GetWidth(idx), 0); 
    glVertex2i(x+this->GetWidth(idx), y); 
glEnd(); 
glActiveTexture(GL_TEXTURE1); 
glUnbindTexture(GL_TEXTURE_RECTANGLE_ARB); // custom macro 
glActiveTexture(GL_TEXTURE0); 
glUnbindTexture(GL_TEXTURE_RECTANGLE_ARB); 
glUseProgram(0); 
glPopAttrib(); 

Shader-Code:

#extension GL_ARB_texture_rectangle : enable 

uniform sampler2DRect rec; 
uniform sampler2DRect rec_colors; 

void main(void) 
{ 
    vec4 oldcol = texture2DRect(rec, gl_TexCoord[0].st); 
    vec4 newcol = texture2DRect(rec_colors, vec2(oldcol.r*255.0, 0.0)); // palette index should be*255 bcs rectangle coordinates aren't normalized 
    gl_FragColor.rgb = newcol.rgb; 
    gl_FragColor.a = oldcol.g; // alpha from green part 
} 

Viel gegoogelt, alle ähnlichen Posts, die ich gefunden habe, wurden gelöst, indem Textureinheits-IDs im glUriform1i-Aufruf korrigiert wurden, aber für mich sieht das völlig normal aus (zumindest lädt TEXTURE0 korrekt in rec).

+0

Sie binden Ihre Textur-Sampler nicht ein. – kaoD

+0

@kaoD Ich bin verbindlich Textur Sampler: /GLuint texloc = glGetUniformLocation (aShader_palette, "rec"); glUniform1i (Texloc, 0); texloc = glGetUniformLocation (aShader_palette, "rec_colors"); glUniform1i (Texloc, 1);/ – ZZYZX

+0

Sie müssen glUniform auch einmal pro Frame aufrufen. Wahrscheinlich wird Ihr Status zurückgesetzt, sobald Sie glUseProgram aufrufen. – kaoD

Antwort

5

Suchen Sie überall nach Fehlern mit glGetError? Ich glaube, du machst etwas falsch. glGetUniformLocation soll gegen ein verknüpftes Programm ausgeführt werden, kein Shader. Sie rufen glGetUniformLocation, bevor Ihr Programm verknüpft ist.

Siehe entsprechenden Text aus Manpage: http://www.opengl.org/wiki/GLAPI/glGetUniformLocation

The actual locations assigned to uniform variables are not known until the program object is linked successfully. After linking has occurred, the command glGetUniformLocation can be used to obtain the location of a uniform variable. Uniform variable locations and values can only be queried after a link if the link was successful.

Sie sollten immer zumindest prüfen opengl Fehler mit glGetError einmal pro Rahmen während der Entwicklung. Sie werden auf diese Probleme hingewiesen, bevor Sie online gehen müssen, um Hilfe zu erhalten.

+0

Das hat geholfen, danke. – ZZYZX

Verwandte Themen