在C++ 17中,是否可以声明这样的东西,使其编译:
struct Foo;
using Var = std::variant<Type1, Type2, Foo>; // uses Foo
struct Foo {
std::vector<Var> member; // uses Var
}
Run Code Online (Sandbox Code Playgroud)
这是一个简化的例子,但我需要一个像这样的递归数据结构.
当派生类没有覆盖它时,编译器是否足够聪明来优化对 Foo() 的调用?
struct Base {
virtual void Foo(int x) {}
};
struct DerivedA : Base {};
struct DerivedB : Base {
void Foo(int x) override { Bar(x); }
};
void Call(Base* b) {
b->Foo(42); // Is this optimized out for DerivedA?
}
int main() {
Base* a = new DerivedA();
Base* b = new DerivedB();
Call(a);
Call(b);
return 0;
}
Run Code Online (Sandbox Code Playgroud) MSVC 2019 允许我定义这样的 lambda,其中模板参数未在参数列表中使用:
auto foo = []<bool B>() {
return B;
};
Run Code Online (Sandbox Code Playgroud)
但是,当尝试像这样调用它时,它会给出语法错误?
foo<false>();
Run Code Online (Sandbox Code Playgroud)
使用非参数模板参数调用 lambda 的正确方法是什么?
在下面的示例中,Type具有虚拟方法,因此具有vtable。但是,Type :: Bar()不是虚拟的。调用Bar()时,该调用是否还会通过vtable机制执行,还是仅适用于Foo()?
struct Base {
virtual void Foo() {}
}
struct Type : Base {
void Foo() override {}
void Bar() {}
}
Base* b = new Type();
Type* t = static_cast<Type*>(b);
t->Bar(); // Does this use a vtable?
Run Code Online (Sandbox Code Playgroud) 在 Vulkan 中,建议将 API 调用分解为单独的线程以获得更好的吞吐量。我不确定哪一类调用是计算成本高的调用,会导致线程阻塞,因此应该异步使用。
在我看来,这些是可能需要很长时间才能执行的潜在调用/调用系列。
但是,我对它们的思考越多,似乎打电话给大多数人的费用就越便宜。我会解释我的理性,这可能是有缺陷的。
vkAcquireImageKHR()
如果您选择超时,这可能会阻塞。但是,经过充分优化的应用程序很可能会在超时为 0 的情况下调用此函数,如果图像尚不可用,则仅执行其他工作。所以,这个功能可以即时完成。如果应用程序足够智能,则无需等待。
vkQueueSubmit()
这个函数需要一个栅栏,当 GPU 完成执行命令缓冲区时会发出信号。因此,它实际上并没有在 GPU 执行工作时等待。我假设这个函数是开始将命令缓冲区数据物理移动到 GPU 的函数,但我假设它告诉硬件从某个内存位置读取,然后函数尽快返回。因此,当命令缓冲区被发送到 GPU 时,它不会等待。
vkQueuePresentKHR()
向 GPU 发送信号以将一些图像发送到窗口/监视器。它不必等待太多,不是吗?
memcpy 进入映射内存
这可能很慢。
vkCmd* 调用
这一系列电话是我最不确定的。当我读到线程和 Vulkan 时,通常是这些调用被放到线程上。但是,这些电话到底在做什么?他们是否正在构建一些操作码缓冲区,由一些整数和指针组成,以发送到 GPU?如果是这样,那应该是非常快的。实际工作是执行这些操作码所描述的操作。
我正在尝试绘制一些精灵,其中考虑了图像的 Alpha 通道。
以下结构在片段着色器中支持纹理 Alpha 通道的正确值集是什么?
vk::PipelineColorBlendAttachmentState colorBlendAttachment;
colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA;
colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = vk::BlendFactor::eOne;
colorBlendAttachment.dstColorBlendFactor = vk::BlendFactor::eZero;
colorBlendAttachment.colorBlendOp = vk::BlendOp::eAdd;
colorBlendAttachment.srcAlphaBlendFactor = vk::BlendFactor::eOne;
colorBlendAttachment.dstAlphaBlendFactor = vk::BlendFactor::eZero;
colorBlendAttachment.alphaBlendOp = vk::BlendOp::eSubtract;
vk::PipelineColorBlendStateCreateInfo colorBlending;
colorBlending.logicOpEnable = VK_FALSE;
colorBlending.logicOp = vk::LogicOp::eCopy;
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment;
colorBlending.blendConstants[0] = 0.0f;
colorBlending.blendConstants[1] = 0.0f;
colorBlending.blendConstants[2] = 0.0f;
colorBlending.blendConstants[3] = 0.0f;
Run Code Online (Sandbox Code Playgroud) 我正在通过开发玩具渲染器来研究 Vulkan 坐标系统。我对顶点位置的坐标感到困惑。在线 Vulkan 信息,例如: https://matthewwellings.com/blog/the-new-vulkan-cooperative-system/
...提及 +X 是正确的,+Y 是向下的,+Z 是回来的。
在我的渲染器中,+Z 指向前方,我不明白为什么。我有一个这样定义的三角形:
// CCW is facing forward
std::vector<PosColorVertex> vertexBuffer = {
{{ 0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f}},
{{-1.0f, 1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}},
{{ 1.0f, 1.0f, -5.0f}, {0.0f, 0.0f, 1.0f}},
};
Run Code Online (Sandbox Code Playgroud)
-5(Z) 将顶点移回屏幕中。应该是 +5 才能做到这一点。
如果我将相机放在原点,它看起来像这样:
另一张镜头,相机远离三角形(Z 轴上的视图由 -4 转换)。
一些相关代码。模型和视图矩阵都是恒等的。
对比:
outColor = inColor;
gl_Position = ubo.projectionMatrix * ubo.viewMatrix * ubo.modelMatrix * vec4(inPos.xyz, 1.0);
Run Code Online (Sandbox Code Playgroud)
FS:
outFragColor = vec4(inColor, 1.0);
Run Code Online (Sandbox Code Playgroud)
投影为:
glm::perspective(glm::radians(60.0f), w/h, 0.1, 256.0);
Run Code Online (Sandbox Code Playgroud)