2012-03-26 183 views
0

我需要顯示一些索引圖形文件,它還具有每個像素的alpha通道。另外,我需要確保隨時可以更改調色板,並且生成的圖像也會更改。爲此,我首先使用了軟件像素預計算,但實時渲染速度太慢,所以我決定編寫一個着色器來處理GPU端的索引紋理。問題在於第二個紋理(rec_colors)沒有加載(至少看起來像這樣 - 從採樣器讀取的每個紋理都看起來完全是空的)。多個紋理單元,片段着色器不工作

從零紋理數據正確讀出,導致黑色圖像與右阿爾法:)

着色器初始化相關的代碼:

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); 

和渲染相關:

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(); 

着色器代碼:

#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 
} 

谷歌搜索了很多,我發現任何類似的帖子都通過glUniform1i調用固定紋理單元ID解決,但對於我看起來絕對正常(至少,TEXTURE0正確加載到rec)。

+0

你沒有約束你的紋理採樣器。 – kaoD 2012-03-26 21:00:57

+0

@kaoD我綁定紋理採樣器: /GLuint texloc = glGetUniformLocation(aShader_palette,「rec」); glUniform1i(texloc,0); texloc = glGetUniformLocation(aShader_palette,「rec_colors」); glUniform1i(texloc,1);/ – ZZYZX 2012-03-26 21:05:37

+0

你也需要每幀調用glUniform一次。一旦你打電話給glUseProgram,你的狀態可能會重置。 – kaoD 2012-03-26 21:14:40

回答

5

您是否使用glGetError檢查是否有錯誤?我相信你做錯了一些事情。 glGetUniformLocation應該針對鏈接的程序執行,而不是着色器。您的程序已鏈接之前,您正在呼叫glGetUniformLocation

請參閱從手冊頁相關的文字:在開發過程中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.

你應該總是至少是檢查每幀一次與glGetError OpenGL的錯誤。在您必須上網尋求幫助之前,它會提醒您這些問題。

+0

這有幫助,謝謝。 – ZZYZX 2012-03-27 07:57:52