与两个片段着色器同时碰撞

时间:2018-07-20 18:39:27

标签: c++ opengl shader

我的意图是,物体在屏幕上占据的空间越少,物体应出现的亮度就越低。

这是片段着色器fs_1

        #version 450 core                                          
        layout (binding = 3, offset = 0) uniform atomic_uint area; 

        void main(void) {                                          
            atomicCounterIncrement(area);                         
        } 

这是第二个片段着色器fs_2

        #version 450 core                           
        layout (binding = 3) uniform area_block { 
            uint counter_value; 
        };                                         
        out vec4 color;                             
        layout(location = 4) uniform float max_area; 

        void main(void){                             
            float brightness = clamp(float(counter_value) / max_area, 0.0, 1.0);
            color = vec4(brightness, brightness, brightness, 1.0);        
        } 

然后将着色器附加到程序对象。现在,有问题的部分来了。我不知道这是可以接受的还是一团糟。我创建了一个命名缓冲区,然后将其绑定到GL_ATOMIC_COUNTER_BUFFER绑定点。然后,将其绑定到绑定数字3。将计数器重置为零。之后,我的意图是在第二个片段着色器中重用原子计数器缓冲区,因此我将其绑定到GL_UNIFORM_BUFFER目标。最后,我将最大预期面积传递给第二个着色器,以计算亮度。

    glUseProgram(program);
    GLuint buf;
    glGenBuffers(1, &buf);
    glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, buf);        
    glBufferData(GL_ATOMIC_COUNTER_BUFFER, 16 * sizeof(GLuint), NULL, GL_DYNAMIC_COPY);
    glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 3, buf);

    const GLuint zero = 0;
    glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 2 * sizeof(GLuint), sizeof(GLuint), &zero);

    glBindBufferBase(GL_UNIFORM_BUFFER, 3, buf);

    glUniform1f(4, info.windowHeight * info.windowWidth);//max_area   

就像这样,它似乎不起作用。我想我还需要在某处插入glColorMask。这是为了关闭第一个片段着色器的输出。此外,我认为我必须对glMemoryBarrier做些事情。还是没有必要?我是否以错误的顺序调用了函数?

我在互联网上找不到真正的参考,也没有关于如何实现此目标的示例代码。谢谢您的回答。

编辑:

此外,我还收到一些错误消息,使问题很明显:

glLinkProgram failed to link a GLSL program with the following program info log: 'Fragment shader(s) failed to link.
Fragment link error: INVALID_OPERATION.
ERROR: 0:8: error(#248) Function already has a body: main
ERROR: error(#273) 1 compilation errors.  No code generated

我很快指出这可能是问题所在,两个片段着色器具有main主体。那么我该如何解决呢?我可以同时离开两个main实体,而是创建另一个程序对象吗?

1 个答案:

答案 0 :(得分:0)

最终我让设计工作了!

我已遵循评论中的重要建议。总结一下:我创建了两个程序对象,并在它们上附加了相同的顶点着色器。之后,我如下调用program(带有片段着色器fs_1

glUseProgram(program);      
glDrawArrays(GL_TRIANGLES, 0, 3);

由于某种原因,我不必致电glMemoryBarrierglColorMask

然后我在渲染循环中进行了以下调用:

virtual void render(double currentTime) {   
    glUseProgram(program1);     
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

在那里,我使用了第二个程序对象program1(带有片段着色器fs_2)。我想它能工作,因为每个程序对象中都需要有一个顶点着色器,而不仅仅是一个。然后,我第一次绘制三角形,没有任何颜色输出,只是为了计算面积。然后,我第二次使用“计数区域”绘制它,以计算三角形的亮度。

我还意识到,着色器仅在发出绘制调用时才执行。