C++ 着色器存储缓冲区对象的长度为零,glMapBufferRange不工作

C++ 着色器存储缓冲区对象的长度为零,glMapBufferRange不工作,c++,opengl,glsl,shader,C++,Opengl,Glsl,Shader,我一直在尝试实现平铺延迟着色,但一段时间以来我一直在解决一个问题。我试图存储一个由点光源组成的结构数组,我想初始化它并将其发送到一个计算着色器,在那里我可以进一步处理它。我正在为此使用着色器存储缓冲区对象,并尝试使用glMapBufferRange提供值。我添加了一些检查,以便如果数组大小为0,我将把屏幕涂成红色,如果大于0,则将屏幕涂成黄色,到目前为止,我似乎无法让它工作 以下是计算着色器: #version 430 #define MAX_WORK_GROUP_SIZE 16 #define

我一直在尝试实现平铺延迟着色,但一段时间以来我一直在解决一个问题。我试图存储一个由点光源组成的结构数组,我想初始化它并将其发送到一个计算着色器,在那里我可以进一步处理它。我正在为此使用着色器存储缓冲区对象,并尝试使用glMapBufferRange提供值。我添加了一些检查,以便如果数组大小为0,我将把屏幕涂成红色,如果大于0,则将屏幕涂成黄色,到目前为止,我似乎无法让它工作

以下是计算着色器:

#version 430
#define MAX_WORK_GROUP_SIZE 16
#define SCREEN_WIDTH 1280.0f
#define SCREEN_HEIGHT 720.0f


uniform sampler2D positionMap;
uniform sampler2D colorMap;
uniform sampler2D normalMap;
uniform sampler2D depthMap;

layout(binding = 4, rgba32f) uniform writeonly image2D finalImage;
layout(binding = 5, rgba32f) uniform writeonly image2D otherImage;

struct PointLight
{
    vec3 position; //4,8,12
    vec3 color; // 16,20, 24
    float radius; //28
    float diffuseIntensity; //32
    float ambientIntensity; //36
    float Constant; //40
    float Linear; //44
    float Exp; //48
};

layout(std430, binding = 6) buffer BufferObject
{
    PointLight pointLights[];
};

shared uint minDepth;
shared uint maxDepth;

layout(local_size_x = MAX_WORK_GROUP_SIZE, local_size_y = MAX_WORK_GROUP_SIZE)in;

void main()
{

    if(gl_LocalInvocationIndex == 0){
        minDepth = 0xFFFFFFFF;
        maxDepth = 0;
    }
    ivec2 pixelPos = ivec2(gl_GlobalInvocationID.xy);
    vec2 uv = vec2(pixelPos.x / SCREEN_WIDTH, pixelPos.y / SCREEN_HEIGHT);


    float d = texture(depthMap,uv).z;

    uint depth = uint(d * 0xFFFFFFFF);

    //compares the content of minDepth to depth and writes the minimum value to minDepth
    atomicMin(minDepth, depth);
//  barrier();
//compares the content of maxDepth to depth and writes the maximum value to the      maxDepth
    atomicMax(maxDepth, depth);



    ///Write a single texel into an image
/*  barrier();
    imageStore(finalImage, pixelPos, vec4(float(float(maxDepth) / float(0xFFFFFFFF))));

    barrier();
    imageStore(otherImage, pixelPos, vec4(float(float(minDepth) / float(0xFFFFFFFF))));
    */

    PointLight p = pointLights[0];
    PointLight p2 = pointLights[1];
    if(pointLights.length() == 0)
    {
        barrier();
        imageStore(finalImage, pixelPos, vec4(1.0,0.0,0.0,1.0));

        barrier();
        imageStore(otherImage, pixelPos, vec4(1.0,0.0,0.0,1.0));
    }
    if(pointLights.length() > 0)
    {
        barrier();
        imageStore(finalImage, pixelPos, vec4(1.0,1.0,0.0,1.0));

        barrier();
        imageStore(otherImage, pixelPos, vec4(1.0,1.0,0.0,1.0));
    }

}
下面是我如何尝试使用一些测试值初始化缓冲区:

My3dVector currentColor(1.0f,1.0f,1.0f);
    glGenBuffers(1,&m_pointLightBuffer);
glBindBuffer(GL_SHADER_STORAGE_BUFFER,m_pointLightBuffer);
glBufferData(GL_SHADER_STORAGE_BUFFER,NUM_OF_LIGHTS*sizeof(struct TDPointLight), NULL, GL_STATIC_DRAW);

struct TDPointLight* pointlights = (struct TDPointLight*) glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, NUM_OF_LIGHTS*sizeof(struct TDPointLight), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT );

int shit = ARRAY_SIZE_IN_ELEMENTS(pointlights);
for(int i = 0; i < NUM_OF_LIGHTS; ++i)
{
    float Max  = 80.0f;
    float Min = -80.0f;

    float MaxZ = 80.0f;
    float MinZ = -80.0f;

    float ranx = ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;
    float ranz = ((float(rand()) / float(RAND_MAX)) * (Max - Min)) + Min;

    int maxCol = 8;
    int minCol = 1;
    //int ranCol = ((rand() / RAND_MAX) * (maxCol - minCol)) + minCol;
    int ranCol = (rand()%(maxCol-minCol))+minCol;

    if(ranCol == 0)
        printf("error, color 8 doesnt exist");
    if(ranCol == 1)
        currentColor = COLOR_WHITE;
    if(ranCol == 2)
        currentColor = COLOR_RED;
    if(ranCol == 3)
        currentColor = COLOR_GREEN;
    if(ranCol == 4)
        currentColor = COLOR_CYAN;
    if(ranCol == 5)
        currentColor = COLOR_BLUE;
    if(ranCol == 6)
        currentColor = COLOR_PURPLE;
    if(ranCol == 7)
        currentColor = COLOR_ORANGE;
    if(ranCol == 8)
        printf("error, color 8 doesnt exist");

    pointlights[i].position = My3dVector(1.0f,1.0f,1.0f);
    pointlights[i].color = My3dVector(1.0f,0.0f,0.0f);
    pointlights[i].radius = 10.0f;
    pointlights[i].diffuseIntensity = 10.0f;
    pointlights[i].ambientIntensity = 0.1f;
    //pointlights[i].color = currentColor;
    //pointlights[i].position = My3dVector(ranx,3.0f,ranz);
    //m_pointLight[i].m_Position = My3dVector(0.0f,2.0f,0.0f);
    pointlights[i].Constant = 0.0f;
    pointlights[i].Linear = 0.0f;
    pointlights[i].Exp = 0.6f;
}
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

它在代码中的任何地方都不能使用任何内存障碍,但由于我没有在任何地方修改内容,这应该不是问题,因为它只初始化一次,然后永远保持不变。

看来我犯了一个愚蠢的错误。在重新排列结构以匹配VEC4的大小后,我可以使用

PointLight p = pointLights[3];
PointLight p2 = pointLights[55];

//vec3 test = vec3(p.posX,p.posY,p.posZ);
//vec3 test2 = vec3(p2.posX,p2.posY,p2.posZ);
vec4 test = p.color;
vec4 test2 = p2.color;

barrier();
imageStore(finalImage, pixelPos, test);

barrier();
imageStore(otherImage, pixelPos, test2);

我仍然从长度中得到零大小,但我相信这是因为着色器不知道数组的大小已更新

您对
点光源
结构的对齐是错误的。两个
vec3
s没有紧密地组合在一起,它们与
vec4
边界对齐。您应该稍微重新安排您的数据结构,并将一个
float
s放在两个
vec3
s之间。另外,为什么要标记此OpenGL ES?ES没有计算着色器。谢谢你的回复,我会修复标记,肯定错过了这一点。我尝试重新安排所有内容,因此在向量3之间有一个浮点数,然后将我的TDPointlight结构更改为具有相同的顺序,但它产生了相同的结果。不幸的是,我认为这不会解决您的问题,但它肯定违反了
std140
/
std430
对齐规则。430唯一改变的是,结构数组中每个元素的大小不必如此严格,因此结尾填充(在本例中这不是问题,因为整个元素是4N的倍数)不必添加。我一直在关注这个演示,我尝试初始化数据,然后只使用glBufferData,而不是添加NULL,我添加了数组,但也不起作用。我只是不确定该去哪里看,在我尝试绑定缓冲区之前,我激活了计算着色器程序,真的不知道为什么缓冲区的长度为零
glDispatchCompute((window_width/MAX_WORK_GROUP_SIZE), (window_height/MAX_WORK_GROUP_SIZE), 1);
glFinish();
PointLight p = pointLights[3];
PointLight p2 = pointLights[55];

//vec3 test = vec3(p.posX,p.posY,p.posZ);
//vec3 test2 = vec3(p2.posX,p2.posY,p2.posZ);
vec4 test = p.color;
vec4 test2 = p2.color;

barrier();
imageStore(finalImage, pixelPos, test);

barrier();
imageStore(otherImage, pixelPos, test2);