关于 windows:gl_FragDepth 断色

gl_FragDepth breaks color

我的计算机上似乎无法使用 gl_FragDepth。否则我的程序运行良好,没有 glsl 错误,glGetError 返回 0,但我无法从片段着色器写入深度缓冲区。

此外,写入 gl_FragDepth 会改变像素颜色的红色分量。

我的程序有简化版。我修剪了所有无用的东西(我猜?),但效果并不好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
int        main(void)
{
//  These are custom structures for handling shader programs.
    t_glprog                prog;
    t_glprog                prog2;

    GLuint                  vbo;
    GLFWwindow              *window;
    static const GLfloat    vertab[] =
    {
        -1.0, -1.0, 1.0,
        1.0, -1.0, 1.0,
        1.0, 1.0, 1.0,
        -1.0, 1.0, 1.0
    };

    char const *vert =
       "attribute vec3 Coord;"
       "void main() {\\
        gl_Position = vec4(Coord, 1.0);\\
        }"
;

    char const *frag1 =
       "void main () {\\
        gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\\
        gl_FragDepth = sin(gl_FragCoord.x * 0.1);\\
        }"
;

    char const *frag2 =
       "void main () {\\
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\\
        gl_FragDepth = cos(gl_FragCoord.x * 0.1);\\
        }"
;

    if (!glfwInit())
    {
        fprintf(stderr,"GLFW failed to init.\
"
);
        return (-1);
    }

    glfwWindowHint(GLFW_DEPTH_BITS, 64);
    window = glfwCreateWindow(640, 480,"TEST", NULL, NULL);
    if (window == NULL)
    {
        fprintf( stderr,"Failed to open GLFW window.\
"
);
        glfwTerminate();
        return (-1);
    }
    glfwMakeContextCurrent(window);

//  For Windows.
    if (glewInit() != GLEW_OK)
    {
        fprintf(stderr,"Failed to initialize GLEW\
"
);
        return (-1);
    }

    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glClearDepth(1.0);
    glViewport(0, 0, 640, 480);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertab), vertab, GL_STATIC_DRAW);

    create_shaders_prog(&prog, vert, frag1);
    create_shaders_prog(&prog2, vert, frag2);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glUseProgram(prog.prog);
    glDrawArrays(GL_QUADS, 0, 4);

    glUseProgram(prog2.prog);
    glDrawArrays(GL_QUADS, 0, 4);

    glFlush();
    glfwSwapBuffers(window);

    while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
            glfwWindowShouldClose(window) == 0)
    {
        glfwPollEvents();
    }
    return (0);
}

它应该画出红色和绿色的条纹,但我得到了模糊的红线。如果我删除第二个drawcall,它是一样的。
在 Windows 上,就是这样。我在 OSX 上对其进行了测试,并按预期工作。

以下是 glGetString 的一些规范:

1
2
3
4
    GL_VENDOR : Intel
    GL_RENDERER : Mobile Intel(R) 4 Series Express Chipset Family
    GL_VERSION : 2.1.0 - Build 8.15.10.1892
    GL_SHADING_LANGUAGE_VERSION : 1.20 - Intel Build 8.15.10.1892


有没有可能是你的集成显卡驱动卡在这条线上了?

1
glfwWindowHint(GLFW_DEPTH_BITS, 64);

64 位对于深度缓冲区来说是非常多的。 24 位是更典型的值。如果不支持 64 位深度缓冲区,上下文创建应该会失败,但是如果深度缓冲区设置不正确,我会看到一些 OpenGL 驱动程序的奇怪行为。