【问题标题】:glBlendFunc Disables ShaderglBlendFunc 禁用着色器
【发布时间】:2011-09-07 14:17:43
【问题描述】:

我有一个非常简单的着色器(只是将背景方块设置为绿色),效果很好。
我最近添加了一些应用了纹理的四边形。这个纹理有一些 alpha 值,所以我用它来称呼它:

    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(...) 行,着色器再次出现(但我失去了 alpha 混合)。 但是,每当我调用该函数时,着色器似乎只是停止工作。

关于为什么会发生这种情况的任何想法?

删除了 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
    }

垂直着色器(非常简单):

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

片段着色器:

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

【问题讨论】:

  • 您能否展示一些图像它的外观和外观。这听起来像是一个深度排序问题,但我不确定。
  • 图片已添加。我重新排列了绘图函数的顺序(以便背景最后而不是第一个呈现),但仍然没有区别。此外,如果这意味着什么:着色器实际上完全不同,它绘制了一些噪点而不是纯色。当我发现它没有显示时,我将其更改为仅绘制静态绿色。 (如果不使用 glBlendFunc 仍然可以显示噪声图像)
  • 在使用glBlendFunc的版本中,你确定你的shader在绘制背景的时候还是开启了吗?
  • 是的,着色器仍在编译、启用(使用有效的 GLuint id)并正在绘制。但不显示。
  • 你能发布更多代码吗?还有着色器

标签: opengl glsl glblendfunc


【解决方案1】:

在片段着色器中,您设置颜色 (0, 0.3, 0, 0),这是一种深绿色,alpha 为 0。启用混合和标准glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 后,alpha 基本上代表颜色的不透明度,不透明度为 0 意味着完全透明的背景。

所以只需将背景的 alpha 更改为 1,您应该会再次看到它。

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

但请记住,先渲染背景,然后再将其他形状正确融合到背景中。您也可以在渲染背景时禁用混合,只为纹理对象启用它。但无论如何,使用 1 的 alpha 在概念上是正确的说法,即您的背景是完全不透明的。

【讨论】:

  • 哦,现在。就在我面前。该死的这些小东西......效果很好 - 但是我在绘制着色器之前关闭了 GL_BLENDing 并将 glBlendFunc 设置回原来的 - 所以透明度不应该重要吗?应该是? (是的,我先画我的背景)
【解决方案2】:

绘制四边形的代码如下:

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。
将此代码更改为 NOT bind textureID if it is == to -1 后,着色器按应有的方式工作,并且我的纹理四边形仍然具有透明度。

然而,Christian Rau 的回答在我的代码中发现了一个错误——这可能是失败的主要原因。

【讨论】:

  • 如果您使用不从纹理读取的着色器,则绑定或启用纹理无关紧要。同样,如果您使用着色器进行纹理处理,则不需要glEnable(GL_TEXTURE_2D)
猜你喜欢
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多