2012-10-22 124 views
2

我正在使用OpenGL 2.1,並在gl_FragColor上產生了一些alpha值的問題。OpenGL着色器編譯優化?

整個代碼:

uniform sampler2D texture_0; 
uniform vec3 uColor; 
varying vec2 varTexCoords; 

void main(void) 
{ 
    //vec4 col = texture2D(texture_0, varTexCoords); 
    vec4 col = vec4(0.0, 0.0, 0.0, 0.5); 
    gl_FragColor = col; 
} 

能有人向我解釋了原因:

作品:

vec4 col = texture2D(texture_0, varTexCoords); 
//vec4 col = vec4(0.0, 0.0, 0.0, 0.5); 
gl_FragColor = col; 

不起作用:

//vec4 col = texture2D(texture_0, varTexCoords); 
vec4 col = vec4(0.0, 0.0, 0.0, 0.5); 
gl_FragColor = col; 

作品:

vec4 col = texture2D(texture_0, varTexCoords); 
col.rgb = uColor; 
//col.a = 0.5; 
gl_FragColor = col; 

也可以工作:

vec4 col = texture2D(texture_0, varTexCoords); 
col.rgb = uColor; 
col.a *= 0.5; 
gl_FragColor = col; 

不起作用:

vec4 col = texture2D(texture_0, varTexCoords); 
col.rgb = uColor; 
col.a = 0.5; 
gl_FragColor = col; 

這一個這麼想的工作,儘管許多例子似乎使用它:

gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0); 

代碼錯誤發生在這裏:

glEnableVertexAttribArray(textureCoords); 
     CHECK_GL_ERROR("glEnableVertexAttribArrayCheck"); 

相關的着色器的所有代碼:

inline void Renderer::renderText(float x, float y, string msg) { 
    mat4 proj; 
    Matrix::projection2D(proj, 
     (float) nScreenWidth_, (float) nScreenHeight_, 0.0f); 
    mat4 res, restmp; 
    mat4 pos; 
    mat4 rot; 
    mat4 scale; 
    //Vector3D p(72.0f, 88.0f, 1.0f); 
    //Vector3D p(20.0f, 20, 1.0f); 
    Vector3D r(0.0f, 0.0f, 0.0f); 
    Vector3D s(1.0f, nScreenWidth_/nScreenHeight_, 1.0f); 
    //Matrix::translate(pos, p.getX(), p.getY(), p.getZ()); 
    //Matrix::rotateZ(rot, r.getZ()); 

    float widthMod = nScreenWidth_/100.0f; 
    float heightMod = nScreenHeight_/100.0f; 

    Matrix::translate(pos, x * widthMod, y * heightMod, 1.0f); 
    Matrix::rotateZ(rot, r.getZ()); 
    //Matrix::scale(scale, s.getX() * widthMod, s.getY() * heightMod, 1.0f); 
    Matrix::scale(scale, 16.0f, 16.0f, 1.0f); 

    Matrix::multiply(proj, pos, res); 
    Matrix::multiply(res, rot, restmp); 
    Matrix::multiply(restmp, scale, res); 

    // Select shader program to use. 
    int shaderId = features_->getText()->getShaderId(); 
    glUseProgram(shaderId); 
    CHECK_GL_ERROR("glUseProgram"); 

    int matrix = glGetUniformLocation(shaderId, "uWVP"); 
    int color = glGetUniformLocation(shaderId, "uColor"); 
    int texture = glGetUniformLocation(shaderId, "texture_0"); 
    CHECK_GL_ERROR("glGetUniformLocation"); 
    int textureCoords = glGetAttribLocation(shaderId, "attrTexCoords"); 
    int vertices = glGetAttribLocation(shaderId, "attrPos"); 
    CHECK_GL_ERROR("glGetAttribLocation"); 

    // Specify WVP matrix. 
    glUniformMatrix4fv(matrix, 1, false, res); 
    CHECK_GL_ERROR("glUniformMatrix4fv"); 

    // Bind the texture. 
    glActiveTexture(GL_TEXTURE0); 
    CHECK_GL_ERROR("glActiveTexture"); 
    glBindTexture(GL_TEXTURE_2D, features_->getText()->getFontMapId()); 
    CHECK_GL_ERROR("glBindTexture"); 
    glUniform1i(texture, 0); 
    CHECK_GL_ERROR("glUniform1i"); 


    glEnableVertexAttribArray(vertices); 
    CHECK_GL_ERROR("glEnableVertexAttribArray"); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    CHECK_GL_ERROR("glBindBuffer"); 

    glEnable(GL_BLEND); 
    CHECK_GL_ERROR("glEnable"); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    CHECK_GL_ERROR("glBlendFunc"); 

    //string text = output_; 
    for (unsigned int i = 0; i < msg.length(); i++) { 
     unsigned short l = static_cast<unsigned short>(msg[i]) - 32; 
     mat4 delta, resmove; 
     Matrix::translate(delta, 1.6f, 0.0f, 0.0f); 
     Matrix::multiply(res, delta, resmove); 
     Matrix::copy(resmove, res); 
     glUniformMatrix4fv(matrix, 1, false, res); 
     CHECK_GL_ERROR("glUniformMatrix4fv"); 
     float col[] = {0.0f, 1.0f, 0.0f}; 
     glUniform3fv(color, 1, col); 
     CHECK_GL_ERROR("glUniform3fv"); 
     glVertexAttribPointer(vertices, 3, GL_FLOAT, GL_FALSE, 0, 
      features_->getText()->vertices_); 
     CHECK_GL_ERROR("glVertexAttribPointer"); 
     glEnableVertexAttribArray(textureCoords); 
     CHECK_GL_ERROR("glEnableVertexAttribArrayCheck"); 
     glVertexAttribPointer(textureCoords, 2, GL_FLOAT, GL_FALSE, 0, 
      features_->getText()->getSymbol(l)); 
     CHECK_GL_ERROR("glVertexAttribPointer"); 
     glDrawArrays(GL_TRIANGLES, 0, 18/3); 
     CHECK_GL_ERROR("glDrawArrays"); 
    } 

    glDisable(GL_BLEND); 
    CHECK_GL_ERROR("glDisable"); 
} 

的錯誤是GL_INVALID_VALUE,只有執行的代碼,而不是編譯和鏈接着色器後後發生。

+3

「有效」和「不起作用」是什麼意思?你如何確定這一點? – Grimmy

+0

不起作用意味着我在glEnableVertexAttribArray調用後出現opengl錯誤。我用GLint error = glGetError()拾取錯誤。 – SMart

+0

之前僅頂點座標傳遞發生錯誤,頂點數組看起來像這樣:\t GLfloat頂點[] = { \t \t \t -1.0F,-1.0F,0.0F, \t \t \t 1.0F,-1.0F,0.0女, \t \t \t 1.0F,1.0F,0.0F, \t \t \t 1.0F,1.0F,0.0F, \t \t \t -1.0F,1.0F,0.0F, \t \t \t -1.0F, -1.0f,0.0f \t}; – SMart

回答

4

這可能是發生了什麼事: (我說「編譯」在這裏,但它可能是不實際的清除鏈接)

着色器compliler下降這一個:

varying vec2 varTexCoords; 

如果編譯器確定一個變量沒有被使用,它將被丟棄。

最後一個例子是好的:

vec4 col = texture2D(texture_0, varTexCoords); 
col.rgb = uColor; 
col.a = 0.5; 
gl_FragColor = col; 

編譯器瞭解到,山口原始值由uColor均勻和0.5恆定覆蓋。紋理讀取被丟棄,所以變化也被丟棄。

那麼您的attrTexCoords也很可能會被丟棄,所以包含attrib位置的textureCoords變量爲-1。

另一方面,編譯器不能刪除紋理讀取,因爲col.bg將包含來自紋理的值。

vec4 col = texture2D(texture_0, varTexCoords); 
col.r = uColor.r; 
col.a = 0.5; 
gl_FragColor = col; 
+0

是的,只是想通了,顯然它將textureCoords更改爲-1,當它不被使用時,這會導致我的代碼在傳遞-1時拋出一個錯誤。這有點奇怪,因爲當第一次測試值時,我可以發誓我在textureCoords上得到了1。檢查時可能會搞砸別的東西。最後一個例子不好,因爲顯然編譯器會再次優化varTexCoords,但將第二行更改爲col.r = uColor.r;作品。將來我會更加小心謹慎,並且記住一些未使用的值可能會被刪除。謝謝。 – SMart

+0

最後一個例子其實很好,應該解釋爲什麼當你將第二行改爲:col.r = uColor.r – Grimmy

+1

我的意思不是很好,代碼會拋出錯誤,但是作爲一個例子確實非常好,並顯示問題:) – SMart