2012-03-26 16 views
0

インデックス付きのグラフィックファイルを表示する必要があります。これには、さらにピクセルごとのアルファチャンネルがあります。また、私はいつでもパレットを変更できることを確認する必要があり、その結果のイメージも変化します。このため、私はまずソフトウェアピクセルの事前計算を使用しましたが、それはリアルタイムレンダリングには遅すぎましたので、GPU側でインデックス付きテクスチャを処理するシェーダを作成することにしました。問題は、2番目のテクスチャ(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

+0

@kaoDテクスチャサンプラーをバインドしています: /GLuint texloc = glGetUniformLocation(aShader_palette、 "rec"); glUniform1i(texloc、0); texloc = glGetUniformLocation(aShader_palette、 "rec_colors"); glUniform1i(texloc、1);/ – ZZYZX

+0

フレームごとにglUniformを1回呼び出す必要があります。 glUseProgramを呼び出すと、状態はリセットされている可能性があります。 – kaoD

答えて

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.

あなたは常に最低でも1フレームに1回glGetErrorとOpenGLのエラーをチェックする必要があり、開発中:

は、manページから関連テキストを参照してください。オンラインで質問をする前に、これらの問題を警告します。

+0

これは、おかげです。 – ZZYZX

関連する問題