2011-09-07 8 views
1

매우 간단한 쉐이더가 있습니다. (배경 사각형이 녹색으로 설정 됨) 완벽하게 작동합니다.
최근 텍스처가 적용된 쿼드가 일부 추가되었습니다. 나는 그것을 호출이 사용하므로이 질감 일부 알파 값이 있습니다glBlendFunc 쉐이더를 사용하지 않음

glEnable (GL_BLEND); 
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glEnable(GL_TEXTURE_2D); 
    glBindTexture(GL_TEXTURE_2D, textureID); 

    //draw quad 

    glDisable(GL_TEXTURE_2D); 
    glBlendFunc (GL_ONE, GL_ZERO); 
    glDisable (GL_BLEND); 
    glBindTexture(GL_TEXTURE_2D, 0); //remove texture 

쿼드는 투명성 잘 표시 -하지만 백그라운드에서 쉐이더는 이제 사라졌다. 아직 그려져 있지만 표시되지 않습니다.

이제 glBlendFunc (...) 행을 모두 제거하고 셰이더가 다시 나타납니다 (그러나 알파 블렌딩은 손실됩니다). 그러나 그 함수를 호출 할 때마다 셰이더가 작동을 멈추는 것처럼 보입니다.

왜 이런 일이 벌어 질 수 있는지에 대한 아이디어가 있습니까? glBlendFunc와

이미지 제거 : glBlendFunc와
glBlendFunc

이미지 사용 :
glBlendFunc removed

쉐이더 코드를로드 :

//create shaders 
    vertexShader = glCreateShader(GL_VERTEX_SHADER); 
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 

    //grab the char so we can send it to gfx card 
    const char* vShadData = loadFile(vertexShaderFile); 
    const char* fShadData = loadFile(fragShaderFile); 

    //send data to gfx card 
    glShaderSource(vertexShader, 1, (const GLchar **)&vShadData, NULL); 
    glShaderSource(fragmentShader, 1, (const GLchar **)&fShadData, NULL); 

    //check if compiled 
    GLint compiled; 

    glCompileShader(vertexShader); 
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compiled); 
    if(compiled==FALSE) 
    { 
     //doesn't get here 
    } 
    glCompileShader(fragmentShader); 
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compiled); 
    if(compiled==FALSE) 
    { 
     //doesn't get here 
    } 

    //finally, create shader program 
    shaderProgram = glCreateProgram(); 

    //attach shaders to program 
    glAttachShader(shaderProgram, vertexShader); 
    glAttachShader(shaderProgram, fragmentShader); 

    glLinkProgram(shaderProgram); 

    GLint linkStatus; 
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, (GLint *)&linkStatus); 
    if(linkStatus==FALSE) 
    { 
     //doesn't get here 
    } 

수직 쉐이더 (매우 간단) :

void main(void) 
{ 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
} 

파편 쉐이더 : 당신의 조각 쉐이더에서

void main(void) 
{ 
    gl_FragColor = vec4(0.0, 0.3, 0.0, 0.0); 
} 
+0

일부 이미지가 어떻게 생겼는지 보여 줄 수 있습니까? 심도있는 순서 문제처럼 들리지만 잘 모르겠습니다. –

+0

이미지가 추가되었습니다. 드로잉 함수의 순서를 재정렬 했으므로 (배경이 처음부터 마지막으로 렌더링되도록) 그래도 차이는 없다. 또한, 그것이 의미하는 바가 있다면 : 쉐이더는 사실 전혀 다른 색으로 단색 대신 약간의 노이즈를 그립니다. 나는 그것이 표시되지 않을 때 정적 녹색 색상을 그리기 위해 그것을 변경했습니다. (glBlendFunc가 사용되지 않으면 노이즈 이미지를 계속 표시 할 수 있습니다.) – Andrew

+0

glBlendFunc가 사용되는 버전에서 배경을 그릴 때 여전히 쉐이더가 활성화되어 있습니까? – neodelphi

답변

2

당신은 색상을 설정 (0, 0.3, 0, 0)입니다 짙은 초록색이며 알파는 0입니다. 블렌딩이 활성화되어 있고 표준 인 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)은 알파는 기본적으로 색상의 불투명도를 나타내며 불투명도 0은 음영, 완벽하게 투명한 배경을 의미합니다.

배경의 알파를 1로 변경하면 다시 볼 수 있습니다.

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

배경에 올바르게 혼합되도록 다른 모양보다 먼저 배경을 먼저 렌더링하는 것이 좋습니다. 배경을 렌더링 할 때 블렌딩을 비활성화하고 텍스처가 적용된 오브젝트에만 사용할 수도 있습니다. 그러나 어쨌든 1의 알파를 사용하는 것은 배경이 완전히 불투명하다고 말하는 개념적으로 올바른 방법입니다.

+0

오우. 바로 내 앞에. 이런 작은 것들이 ... 완벽하게 작동했습니다. 그러나 GL_BLENDing을 끄고 glBlendFunc를 원래의 셰이더를 그리기 전에 되돌려 놓으십시오. 그래서 투명도가 중요하지 않아야합니까? 그럴까요? (그리고 내 배경을 우선 드로잉합니다.) – Andrew

0

쿼드을 그리기위한 코드는 다음과 같다 :

glEnable (GL_BLEND); 
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D, textureID); 

glBegin(GL_TRIANGLE_FAN); 
    glTexCoord2f(0.0f, 0.0f); 
    glVertex2f(-1.0f, 1.0f);  
    glTexCoord2f(1.0f, 0.0f); 
    glVertex2f(1.0f, 1.0f); 
    glTexCoord2f(1.0f, 1.0f); 
    glVertex2f(1.0f,-1.0f); 
    glTexCoord2f(0.0f, 1.0f); 
    glVertex2f(-1.0f,-1.0f); 
glEnd(); 
glDisable(GL_TEXTURE_2D); 
glBlendFunc (GL_ONE, GL_ZERO); 
glDisable (GL_BLEND); 
glBindTexture(GL_TEXTURE_2D, 0); //remove texture 

지금 쉐이더 쿼드와 질감 쿼드 모두 내가 동일한 코드를 사용합니다. 그러나 쉐이더 쿼드의 텍스처를로드하지 않기 때문에 opengl에 보내는 textureID는 -1입니다.
== -1로이 코드를 NOT bind textureID로 변경하면 쉐이더가 정상적으로 작동하고 텍스쳐 쿼드에 투명성이 유지됩니다.

그러나 Christian Rau의 대답이 내 코드에서 버그를 발견했습니다. 이것이 아마도 실패한 주된 이유 일 것입니다.

+1

텍스처에서 읽지 않는 셰이더를 사용하는 경우, 텍스처가 바운드되어 있는지 또는 사용 가능한지는 중요하지 않습니다. 마찬가지로 텍스처링을 위해 셰이더를 사용한다면'glEnable (GL_TEXTURE_2D)'가 필요하지 않습니다. –

관련 문제