为什么我在发送一个结构体到着色器存储缓冲区时得到了垃圾数据?

问题描述 投票:0回答:1

我正在用C++编写一个基于opengl的光线跟踪器应用程序。我想从cpu端发送数据到片段着色器。不幸的是,当我试图用gl_fragcolor将坐标写成颜色时,在shader端我得到了垃圾数据。我不知道为什么。感谢任何帮助。

我在CPU端有这个结构。

struct FlatBvhNode {

        glm::vec4 min;   
        glm::vec4 max;
        int order;
        bool isLeaf;
        bool createdEmpty;
        vector<glm::vec4> indices;

        FlatBvhNode() { }

        FlatBvhNode(glm::vec3 min, glm::vec3 max, int ind, bool isLeaf, bool createdEmpty, vector<glm::vec3> indices) {
            this->min=glm::vec4(min.x, min.y, min.z, 1.0f);
            this->max=glm::vec4(max.x, max.y, max.z, 1.0f);
            this->order=ind;
            this->isLeaf=isLeaf;
            this->createdEmpty=createdEmpty;

            indices.reserve(2);
            for (int i = 0; i < indices.size(); i++) {
                this->indices.push_back(glm::vec4(indices.at(i).x, indices.at(i).y, indices.at(i).z, 1));
            }
        }
    };

我想在片段着色器中接收上述结构:

struct FlatBvhNode{     //base aligment     aligned offset
    vec3 min;           // 16 byte          0
    vec3 max;           // 16 byte          16
    int order;          // 4 byte           20
    bool isLeaf;        // 4 byte           24
    bool createdEmpty;  // 4 byte           28
    vec3 indices[2];    // 32 byte          32
};

我不确定对齐的偏移量是否正确。我读到vec3s被视为16个字节,booleans和整数被视为4个字节。其次,对齐后的偏移量必须等于或多于基数偏移量。

我将上述结构与这些代码一起发送。

    vector<BvhNode::FlatBvhNode>* nodeArrays=bvhNode.putNodeIntoArray();
    unsigned int nodesArraytoSendtoShader;
    glGenBuffers(1, &nodesArraytoSendtoShader);
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, nodesArraytoSendtoShader);

    glBufferData(GL_SHADER_STORAGE_BUFFER, nodeArrays->size() * sizeof(BvhNode::FlatBvhNode),  nodeArrays, GL_STATIC_DRAW);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 2, nodesArraytoSendtoShader, 0, nodeArrays->size() * sizeof(BvhNode::FlatBvhNode));
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
c++ opengl glsl shader memory-alignment
1个回答
1
投票

当你指定了 着色器存储缓冲区对象,然后你必须使用 std430 定语。见 OpenGL 4.6 API Core Profile Specification; 7.6.2.2 标准统一块布局.

如果你想在shader中使用以下数据结构。

struct FlatBvhNode
{     
                        // base aligment    aligned offset
    vec4 min;           // 16 byte          0
    vec4 max;           // 16 byte          16
    int  order;         // 4 byte           32
    int  isLeaf;        // 4 byte           36
    int  createdEmpty;  // 4 byte           40
    vec4 indices[2];    // 32 byte          48
};

layout(std430) buffer TNodes
{
    FlatBvhNode nodes[];
}

那么你必须考虑 indices 是一个类型为 vec4. 因此 indices 被对齐为16个字节。

这对应于下面的数据结构,在c ++中为

struct FlatBvhNode {

        glm::vec4 min;   
        glm::vec4 max;
        int order;
        int isLeaf;
        int createdEmpty;
        int dummy; // alignment
        std::array<glm::vec4, 2> indices;
}

注意,虽然 std::vector 封装了动态大小的数组。std::array 封装了固定大小的数组。std::array<glm::vec4, 2> 对应于 glm::vec4[2]std::vector<glm::vec4> 更像是 glm::vec4* 和一些额外的尺寸信息。

© www.soinside.com 2019 - 2024. All rights reserved.