2

私は非常に単純なシェーダー (背景の正方形を緑に設定するだけ) を持っていますが、これは完全に機能します。
最近、テクスチャが適用されたクワッドをいくつか追加しました。このテクスチャにはいくつかのアルファ値があるため、これを使用して呼び出します。

    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 が削除されました

シェーダー読み込みコード:

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

Vert シェーダー (非常にシンプル):

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

フラグ シェーダー:

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

2 に答える 2

3

フラグメント シェーダーで、色 (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 を使用することは、背景が完全に不透明であると言う概念的に正しい方法です。

于 2011-09-09T00:15:01.323 に答える
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 です。
== の場合に textureID を -1 にバインドしないようにこのコードを変更した後、シェーダーは正常に動作し、テクスチャ化されたクワッドで透明度が得られます。

ただし、Christian Rau の回答により、私のコードにバグが見つかりました。これがおそらく、これが失敗した主な理由です。

于 2011-09-09T00:28:24.627 に答える