首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >矢量Push_Back与Emplace_Back

矢量Push_Back与Emplace_Back
EN

Stack Overflow用户
提问于 2019-11-23 16:14:11
回答 1查看 185关注 0票数 1

我有两种不同的方法来向向量中添加元素。

代码语言:javascript
复制
GUI_Vertices.emplace_back();

GUI_Vertices.back().pos.x = ((float)x / 400) - 1.f;
GUI_Vertices.back().pos.y = ((float)y / 300) - 1.f;
GUI_Vertices.back().texCoord.x = u;
GUI_Vertices.back().texCoord.y = v;
GUI_Vertices.back().color.r = m_Color.r / 128;
GUI_Vertices.back().color.g = m_Color.g / 128;
GUI_Vertices.back().color.b = m_Color.b / 128;
GUI_Vertices.back().color.a = m_Color.a / 128;

上面的代码可以工作,但是我不得不向GUI_Vertices向量中添加一个新元素。

代码语言:javascript
复制
Vertex NewVertex;

NewVertex.pos.x = ((float)x / 400) - 1.f;
NewVertex.pos.y = ((float)y / 300) - 1.f;
NewVertex.texCoord.x = u;
NewVertex.texCoord.y = v;
NewVertex.color.r = m_Color.r / 128;
NewVertex.color.g = m_Color.g / 128;
NewVertex.color.b = m_Color.b / 128;
NewVertex.color.a = m_Color.a / 128;

GUI_Vertices.emplace_back(NewVertex);

上面的代码有时可以工作,如果需要,我可以有条件地将NewVertex添加到GUI_Vertices向量中。

以下是Vertex的定义

代码语言:javascript
复制
struct Vertex {
    glm::vec3 pos;
    glm::vec4 color;
    glm::vec2 texCoord;

    static VkVertexInputBindingDescription getBindingDescription() {
        VkVertexInputBindingDescription bindingDescription = {};
        bindingDescription.binding = 0;
        bindingDescription.stride = sizeof(Vertex);
        bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;

        return bindingDescription;
    }

    static std::array<VkVertexInputAttributeDescription, 3> getAttributeDescriptions() {
        std::array<VkVertexInputAttributeDescription, 3> attributeDescriptions = {};

        attributeDescriptions[0].binding = 0;
        attributeDescriptions[0].location = 0;
        attributeDescriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT;
        attributeDescriptions[0].offset = offsetof(Vertex, pos);

        attributeDescriptions[1].binding = 0;
        attributeDescriptions[1].location = 1;
        attributeDescriptions[1].format = VK_FORMAT_R32G32B32A32_SFLOAT;
        attributeDescriptions[1].offset = offsetof(Vertex, color);

        attributeDescriptions[2].binding = 0;
        attributeDescriptions[2].location = 2;
        attributeDescriptions[2].format = VK_FORMAT_R32G32_SFLOAT;
        attributeDescriptions[2].offset = offsetof(Vertex, texCoord);

        return attributeDescriptions;
    }

    bool operator==(const Vertex& other) const {
        return pos == other.pos && color == other.color && texCoord == other.texCoord;
    }
};

namespace std {
    template<> struct hash<Vertex> {
        size_t operator()(Vertex const& vertex) const {
            return ((hash<glm::vec3>()(vertex.pos) ^
                (hash<glm::vec4>()(vertex.color) << 1)) >> 1) ^
                (hash<glm::vec2>()(vertex.texCoord) << 1);
        }
    };
}

在以后的程序执行中,在将所有Vertex元素添加到GUI_Vertex向量之后,我将在GUI_Vertex上执行以下操作

代码语言:javascript
复制
memcpy(GUI_VertexAllocation->GetMappedData(), GUI_Vertices.data(), sizeof(Vertex) * GUI_Vertices.size());

我正在将内存从GUI_Vertices复制到预先分配的缓冲区中,Vulkan将使用该缓冲区来呈现我们的顶点。

现在,我试图弄清楚为什么第一种将Vertex对象添加到GUI_Vertices中的方法总是有效的,而第二种方法只是有时起作用。

下面是指向整个项目https://github.com/kklouzal/WorldEngine/blob/GUI_Indirect_Draw/Vulkan/VulkanGWEN.hpp的链接

在重新编译项目之后,第二个方法偶尔会起作用,所以我在这里得到了一些未定义的行为。我已经检查了GUI_Vertices的有效性,直到我们做了memcpy,并且数据看起来是有效的,所以我不确定发生了什么。

我希望第二个方法能够正常工作,这样我就可以有条件地向缓冲区中添加新的顶点。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-23 16:21:57

NewVertex.pos.x = ((float)x / 400) - 1.f;NewVertex.pos.y = ((float)y / 300) - 1.f;glm::向量3 pos;

emplace_back将始终对它创建的对象执行值初始化,该对象初始化所有数据成员。相反,Vertex NewVertex;将默认初始化对象,这将使其成员未初始化(因为GLM类型具有简单的默认构造函数)。

所以pos.z是未初始化的。而且你的代码不是自己初始化的。所以你要把未初始化的垃圾发送到GPU。

如果使用Vertex NewVertex{};创建对象,那么它将像emplace_back一样被值初始化。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59009614

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档