【问题标题】:gl_FragDepth breaks colorgl_FragDepth 破坏颜色
【发布时间】:2015-09-21 14:13:09
【问题描述】:

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

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

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

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.\n");
        return (-1);
    }

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

//  For Windows.
    if (glewInit() != GLEW_OK)
    {
        fprintf(stderr, "Failed to initialize GLEW\n");
        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 的一些规范:

    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

【问题讨论】:

  • 是否可以在您的应用中使用 OpenGL 3.2 或更高版本,而不是 OpenGL 2.1?
  • 你不用在事件循环里面画图吗?
  • 我的电脑不支持 OpenGL 3.2,我认为 gl_FragDepth 从 glsl 1.1 开始可用。好吧,我不需要循环,没有动画。
  • @Procrade 你们有什么集成显卡芯片组?我有一台较旧的戴尔笔记本电脑,在使用多个渲染目标时遇到了类似的问题。原来驱动程序有问题,所以我无法使用该功能。如果您向我们提供芯片组信息,那么我们可以搜索您的问题是否为已知问题。
  • @MattFichman 这是英特尔 GMA 4500M。

标签: windows opengl glsl depth-buffer


【解决方案1】:

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

glfwWindowHint(GLFW_DEPTH_BITS, 64);

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

【讨论】:

  • 当我阅读 GLFW 文档时,这是一个提示,而不是硬约束。它应该获得尽可能多的深度位。
  • 是的,没错。但是,这假设如果您尝试使用错误的深度缓冲区设置,驱动程序会向 GLFW 返回错误。不幸的是,驱动程序(尤其是集成显卡的 Windows OpenGL 驱动程序)并不总是很擅长遵循规范。无论如何,认为这可能值得一试,所以我发布了答案:)
  • @JWWalker 我同意马特的观点,大多数卡只正确支持最多 24 位/深度缓冲区,一些更好的最多 32 位(但通常仅当其他缓冲区具有较小的位宽或分辨率或两者兼有时)我较新的看到更好。一些糟糕的 gfx 驱动程序将允许您使用更大的深度缓冲区,即使硬件不支持它(上次我看到这是在集成的 SiS gfx 卡上)请参阅 What is the proper OpenGL initialisation on Intel HD 3000? 我如何初始化像素格式...
  • 用 glfwWindowHint(GLFW_DEPTH_BITS, 24) 测试它,或者删除调用:没有改变:(
猜你喜欢
  • 2021-01-09
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多