SSBO同步写入

时间:2017-01-28 22:35:37

标签: opengl

我有一个OpenGL程序,显示(巨大的)缺乏可重复性。在片段着色器中,我查找特定条件。如果满足该条件,我会向SSBO写入与该片段相关联的世界空间坐标,这是我从顶点着色器中保留的。

我的问题是,从一个程序的重复到下一个程序,SSBO的写入操作的数量确实变化很大。可能是这样,如果多个着色器想要同时写入SSBO,那么它不会总是这样做吗?

我没有从其他着色器读取SSBO。因此,这不是写/读同步的问题。我只有在回到CPU应用程序时才读取SSBO。

我在NVIDIA GTX645显卡上使用OpenGL 4.3。

2 个答案:

答案 0 :(得分:0)

在CPU应用程序中:

//Create one Shader Storage Buffer Object for vertices of detected points

            GLuint Detected_Vertices_SSBO;
            glGenBuffers(1,&Detected_Vertices_SSBO);
            glBindBuffer(GL_SHADER_STORAGE_BUFFER,Detected_Vertices_SSBO);
            glBufferData(GL_SHADER_STORAGE_BUFFER,(sizeN-NbTotalreflectionPoints.at(i))*sizeof(glm::vec4),NULL,GL_DYNAMIC_DRAW);
            sprintf(OpenGLErrorMessage,"%s\n","Error on Vertices SSBO at creation time.");
            QueryForOpenGLErrors(OpenGLErrorMessage);
            glBindBufferBase(GL_SHADER_STORAGE_BUFFER,0,Detected_Vertices_SSBO);
            sprintf(OpenGLErrorMessage,"%s\n","Error on Vertices SSBO at binding time.");
            QueryForOpenGLErrors(OpenGLErrorMessage);

            //Create one Shader Storage Buffer Object for colors of detected points
            GLuint Detected_Vertices_Colors_SSBO;
            glGenBuffers(1,&Detected_Vertices_Colors_SSBO);
            glBindBuffer(GL_SHADER_STORAGE_BUFFER,Detected_Vertices_Colors_SSBO);
            glBufferData(GL_SHADER_STORAGE_BUFFER,(sizeN-NbTotalreflectionPoints.at(i))*sizeof(glm::vec4),NULL,GL_DYNAMIC_DRAW);
            sprintf(OpenGLErrorMessage,"%s\n","Error on Colors of Vertices SSBO at creation time.");
            QueryForOpenGLErrors(OpenGLErrorMessage);
            glBindBufferBase(GL_SHADER_STORAGE_BUFFER,1,Detected_Vertices_Colors_SSBO);
            sprintf(OpenGLErrorMessage,"%s\n","Error on Vertices Colors SSBO at binding time.");
            QueryForOpenGLErrors(OpenGLErrorMessage);

….
glDrawArrays(GL_POINTS, 2*3+NbTargets1*12*3, NbPoints); //
                glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
                glFinish();
…
glBindBuffer(GL_SHADER_STORAGE_BUFFER, Detected_Vertices_SSBO);
                glm::vec4 * SSBO_Position_ptr = (glm::vec4*)glMapBuffer(GL_SHADER_STORAGE_BUFFER,GL_READ_ONLY);
                sprintf(OpenGLErrorMessage,"%s\n","Error on Vertices SSBO at mapping time.");
                QueryForOpenGLErrors(OpenGLErrorMessage);
                glFinish();
                glBindBuffer(GL_SHADER_STORAGE_BUFFER, Detected_Vertices_Colors_SSBO);
                glm::vec4 * SSBO_Color_ptr = (glm::vec4*)glMapBuffer(GL_SHADER_STORAGE_BUFFER,GL_READ_ONLY);
                sprintf(OpenGLErrorMessage,"%s\n","Error on Vertices Colors SSBO at mapping time.");
                QueryForOpenGLErrors(OpenGLErrorMessage);
                glFinish();

然后,在片段着色器中:

#version 430 core

布局(early_fragment_tests);

// Interpolated values from the vertex shaders
in vec4 fragmentColor;
in vec4 worldspace;

//SSBO's for detected points and their colors
layout (binding=0, std430) coherent buffer detected_vertices_storage 
{
vec4 detected_vertices[];
}Positions;
layout (binding=1, std430) coherent buffer detected_vertices_colors_storage 
{
vec4 detected_vertices_colors[];
}Colors;



...




 Positions.detected_vertices[int(round(Condition * ((gl_FragCoord.y-0.5)*1024.0+(gl_FragCoord.x-0.5))/(1024.0*1024.0)*NbOfCosines))] = worldspace;
        Colors.detected_vertices_colors[int(round(Condition * ((gl_FragCoord.y-0.5)*1024.0+(gl_FragCoord.x-0.5))/(1024.0*1024.0)*NbOfCosines))] = color;

其中Condition = 0或1。

我希望这会有所帮助。我很遗憾地告诉我,在stackoverflow中我仍然遇到这种格式化问题。我一定太老了!

答案 1 :(得分:0)

是。我修好了。
在网上浏览了很长时间后,我发现使用glDeleteBuffers(1, &_SSBO);仅仅可能不足以删除缓冲区:它的名称也必须删除。您会认为SSBO已被删除,您可以使用glBindBuffer(GL_SHADER_STORAGE_BUFFER, Detected_Vertices_SSBO);绑定一个新的但是,从我学到的(并且它起作用),可能会发生新的绑定将使用相同的SSBO名称(或处理)。为了防止这种情况,请在绑定新版本之前使用glBindBuffer(GL_SHADER_STORAGE_BUFFER,0);确保SSBO unbinded 。命令中的参数0将确保SSBO真正解除绑定。祝你好运!