glBlendFunc отключает шейдер - PullRequest
       27

glBlendFunc отключает шейдер

1 голос
/ 07 сентября 2011

У меня очень простой шейдер (просто устанавливает фоновый квадрат на зеленый), и это прекрасно работает.
Недавно я добавил несколько квадов, к которым применена текстура. Эта текстура имеет некоторые альфа-значения, поэтому я использую ее для вызова:

    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
    }

Vert Shader (очень просто):

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

Frag Shader:

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

Ответы [ 2 ]

3 голосов
/ 09 сентября 2011

В вашем фрагментном шейдере вы устанавливаете цвет (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 голосов
/ 09 сентября 2011

Код для рисования четырехугольника выглядит так:

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

Теперь для шейдерного и текстурированного квадратов я использую один и тот же код. Тем не менее, я никогда не загружаю текстуру для четырехугольника шейдера, поэтому textureID, который я посылаю opengl, равен -1.
После изменения этого кода на NOT bind textureID, если он равен от == до -1, шейдер работает так, как должен, и я по-прежнему получаю прозрачность на моих текстурированных квадрах

Однако ответ Кристиана Рау нашел ошибку в моем коде - что, вероятно, является основной причиной, почему это не удалось.

...