Collision with two fragment shaders at the same time

duckbjarne

My intention was, that the less space an object takes up on the screen, the less bright the object should appear.

This is fragment shader fs_1

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

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

That's the second fragment shader, 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);        
        } 

I then attached the shaders to the program object. Now, the problematic part comes. I wonder if that's even acceptable or a complete mess. I created a named buffer and then bound it to the GL_ATOMIC_COUNTER_BUFFERbinding point. Then, I bound it to binding number 3. I reset the counter with zero. After that, my intention was to reuse the atomic counter buffer in the second fragment shader, so I bound it to the GL_UNIFORM_BUFFER target. Last, I pass the maximum expected area to the second shader, in order to calculate the brightness.

    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   

Like so, it doesn't seem to work. I also somewhere need to insert glColorMask, I suppose. This, in order to turn off the output of the first fragment shader. Furthermore, I think, I have to do something with glMemoryBarrier. Or is that not necessary? Have I called the functions in the wrong order?

I found no real references to it in the internet, no sample code on how to accomplish that. I'd be thankful for any answers.

Edit:

In addition, I have got some error message which makes the problem obvious:

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

I have very soon remarked that that might be the problem, that two fragment shaders have the mainbody. So how could I fix that? Could I leave both main bodies and instead create a second program object?

duckbjarne

I got the design to work, eventually!

I've followed the great advices in the comments. To sum up: I created two program objects with the same vertex shader attached to them. After that, I called program (with fragment shader fs_1) as follows:

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

For some reason, I didn't have to call glMemoryBarrier or glColorMask.

I then made the following calls in my render-loop:

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

There, I used the second program object, program1 (with fragment shader fs_2). I suppose it works, because there needs to be a vertex shader in each program object, not just in one. I then drew the triangle the first time, without any color output, but just to calculate the area. I then drew it the second time, using the "counted area" to calculate the brightness of the triangle.

I also realised, that the shaders are only executed when you issue a draw call.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related