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 驱动程序的奇怪行为。