小编Wat*_*ter的帖子

了解 glm::ortho() 的参数如何影响投影后的顶点位置

在搜索了许多页面、glm 文档、教程...等之后,我仍然对某些事情感到困惑。

我试图理解为什么我需要应用以下转换来获得我的 800x600(全屏正方形,假设用户的屏幕在这个最小示例中为 800x600)图像来绘制所有内容。假设我只绘制逆时针三角形。在我的代码中一切都很好,但我必须执行以下操作:

// Vertex data (x/y/z), using EBOs
  0.0f, 600.0f, 1.0f,
800.0f,   0.0f, 1.0f,
  0.0f,   0.0f, 1.0f,
800.0f, 600.0f, 1.0f

// Later on...
glm::mat4 m, v, p;
m = scale(m, glm::vec3(-1.0, 1.0, 1.0));
v = rotate(v, glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f));
p = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, 0.5f, 1.5f);
Run Code Online (Sandbox Code Playgroud)

(请注意,仅仅因为我使用了变量名称m, vp并不意味着它们实际上是该名称的正确转换,以上只是我想要的)

我对以下内容感到困惑:

  • 正交边界在哪里?我假设它指向负 z 轴,但是左/右边界在哪里?这是否意味着 x 轴上的 [-400, 400] 映射到 [-1.0, 1.0] NDC,或者 [0, 800] 映射到它?(我假设这里的任何答案都适用于 y 轴)。然后文档只是说Creates a matrix for an …

c++ opengl rendering orthographic glm-math

4
推荐指数
1
解决办法
3650
查看次数

有什么方法可以对成员变量执行 std::upper_bound 吗?

我想用std::upper_bound查找某个容器中小于或等于提供值的对象的跨度。这使它成为一个很好的简单单行!

问题是我只对与类的特定原始成员进行比较感兴趣。对容器进行排序是没有问题的,但是当我想使用时std::upper_bound,我需要提供一个对象来进行比较才能使函数正常工作。

对于 MCVE,假设我有一群人,我想找到一个迭代器来:

struct Person {
    int age;
    double height;

    Person(int age, double height) : age(age), height(height) { }
};

int main() {
    vector<Person> people = { 
        Person(5, 12.3), 
        Person(42, 9.6), 
        Person(38, 18.4), 
        Person(31, 8.5)
    };

    auto sorter = [](const Person& a, const Person& b) {
        return a.height < b.height;
    };

    std::sort(people.begin(), people.end(), sorter);

    // All I care about is comparing against this number
    // Instead... I have to create a whole new struct
    //double …
Run Code Online (Sandbox Code Playgroud)

c++ c++17

4
推荐指数
1
解决办法
417
查看次数

模板模板参数的替换失败

我想要一个辅助函数来为我实例化一个类。目前它不能在 clang 中编译(尽管它可以在 gcc 中编译工作),但我也需要它在 clang 中工作。目前我正在使用clang version 6.0.0-1ubuntu2.

我不确定它为什么会失败,因为 gcc 能够检测到类型。我尝试从这篇文章中做一些事情并玩了一段时间,但我一直在撞墙。MCVE 可用,或者您可以在此处coliru试用

#include <vector>

using namespace std;

template <typename T, template <typename> typename Container>
struct SomeClass {
    SomeClass(const Container<T>& c) {
    }
};

template <typename T, template <typename> typename C>
inline auto make_some_class(const C<T>& container) {
    return SomeClass<T, C>(container);
}

int main() {
    vector<int> ints;

    auto stuff = make_some_class(ints);  
}
Run Code Online (Sandbox Code Playgroud)

main.cpp:19:18: 错误:没有匹配的函数来调用“make_some_class”

   auto stuff = make_some_class(ints);  

                ^~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

main.cpp:12:13: 注意: …

c++ templates variadic-templates template-argument-deduction c++17

4
推荐指数
2
解决办法
827
查看次数

glm::perspective 的 fov 参数是否定义为视场角的一半?

我正处于用 OpenGL 编写的渲染器的优化阶段,我的下一步是剔除我看不到的所有内容。在阅读本文和其他资源时,我看到了视锥体的视觉描述,例如:

平截头体

图片来自:https : //www.scratchapixel.com/images/upload/perspective-matrix/camsetup1.png

因此认为我们通过了类似的东西glm::radians(90.0f)。然而,我开始遇到我的算法的剔除问题,因为我认为我会沿着左右各 45 度的飞机……但后来我开始得到误报剔除。一旦我将其更改为使用fov传递给的角度,glm::perspective则剔除开始工作正常。

但是有两件事我不确定:

  1. 我说的对吗?在 fov 值应该是上面张贴的图像中绿色角度的一半?
  2. 如果 (1) 为真,那么为什么 90 的 fov 不能显示我左右两侧的所有内容?

这些对我来说很重要,因为我想让我的剔除算法在没有误报的情况下尽可能多地剔除。正如您可能猜到的那样,我得到了误报剔除,因为我认为“我需要将我glm::perspective()再次使用的第一个参数除以二以获得角度的一半”,这导致更紧密的截锥体将剔除更多它应该有。

我目前剔除的方式是计算平截头体的左右边缘,并通过点积剔除左侧或右侧边缘无法看到的任何二维线(就像它们是线段)。这就是为什么更窄的角度让我感到悲伤。顺便说一句,如果有更好的方法可以让我知道,尽管我认为两个点积可能是我必须检查的线的计算效率方面最便宜的。

c++ opengl rendering perspectivecamera glm-math

3
推荐指数
1
解决办法
1828
查看次数

编译后sizeof是否转换为常数?

这些速度是否相等?

return someNumber / sizeof(myStruct); // Pretend sizeof returns 88 always.
Run Code Online (Sandbox Code Playgroud)

return someNumber / 88;
Run Code Online (Sandbox Code Playgroud)

我不确定编译器是否每次都计算sizeof或写一个常量(因此我可以安全地包含sizeof()而不是常量).

c++ compilation sizeof

1
推荐指数
1
解决办法
84
查看次数

JavaFX - 当主阶段关闭时关闭任何其他阶段,但允许它们隐藏在主阶段后面

假设我正在创建的第二个窗口有以下代码:

    stage.initModality(Modality.NONE);
    stage.initOwner(coreController.getStage());
Run Code Online (Sandbox Code Playgroud)

如果我这样做,它会在我的主窗口关闭时关闭。

如果我注释掉stage.initOwner(coreController.getStage());,那么它将能够隐藏在主面板后面,但它不会关闭。

当我杀死主舞台时,有什么方法可以让它关闭...而无需编写代码来跟踪创建的每个新窗口?到目前为止,我似乎唯一的选择是将每个新窗口注册到列表中,当主窗口触发“关闭事件”时,我也会为所有其他窗口触发此事件。有没有一种方法可以做到这一点,而无需我像这样将所有东西连接在一起?

编辑:我使用 Modality.NONE ,这样窗口就不会阻止任何事件,但我不知道这是否与问题相关。

编辑2:我希望在退出主窗口时关闭所有窗口(如果我可以拦截关闭事件并进行清理,那就太好了)。

java javafx window

1
推荐指数
1
解决办法
7007
查看次数

是否有可能在C中总是在数组大小的1处产生段错误?

假设你分配一些数组arr size n,如下所示:

int arr[n]; // Allocated fine
printf("%d", arr[n]); // Segfault if possible
Run Code Online (Sandbox Code Playgroud)

是否存在这样的数字n,我总是可以在printf线上触发段错误?这可能是某些操作系统特有的.

我知道它的未定义行为,我知道当访问它并将其更改为超出范围将影响另一个内存区域(可能)会导致我以后出现重大问题.

我的教授说它并不总是会出现段错误,而且我很好奇是否在任何情况下都会创建一个某种尺寸的数组,某些类型的操作系统或计算机每次都会可靠地进行段错误.

这是可能的还是没有?是否存在一些我可以创建的条件,这将导致单个越界访问始终触发段错误.

它是理论上可能是永远正确的?但是在实践中不会一直发生这种情况吗?

c arrays segmentation-fault

1
推荐指数
1
解决办法
179
查看次数

了解 OpenGL 中的绑定/激活纹理性能损失

我不确定我所做的是否是最佳的。

我有三个纹理(其中两个是堆叠有大量信息的数组纹理)并且我执行了三个渲染通道:

  • 具有纹理 1 的关卡几何体

  • 具有纹理 2 的世界实体

  • 带有纹理 3 的 HUD 东西

因此,我的代码通常会执行类似以下伪代码的操作:

bindTexture(tex1);
drawLevel();
unbindTexture(tex1);  // Is this necessary if I just bind after anyways?

bindTexture(tex2);
drawEntities();
unbindTexture(tex2);

bindTexture(tex3);
drawHUD();
unbindTexture(tex3);
Run Code Online (Sandbox Code Playgroud)

因为我记得在 GL_TEXTURE0、GL_TEXTURE1 等上看到最多允许 16 个(或更多)单独的纹理,这是否意味着我可以将我的世界纹理写入 GL_TEXTURE0,将实体写入 GL_TEXTURE1,将 HUD 写入 GL_TEXTURE2 并且没有性能罚款,还是很少?或者甚至改变活动纹理是否会带来明显的惩罚?

我问是因为我记得看到纹理交换是一项繁重的操作。这是否意味着即使我改变了我的活动纹理,它仍然很费力?或者,如果您有超过 16 个左右的纹理并不断将它们推送到 GPU,它是否只是繁重?

这是错误的还是缓慢的?

我只需要 3 个纹理,所以如果有最优化的方法来做这件事,我会很高兴学习它。

假设我使用的是核心 3.3 而不是 4.5(但如果在 4.2 或更高版本中有更好的方法,我也很乐意听到这些)。它也应该适用于 nvidia 和 AMD 或过去 4-5 年发布的任何 GPU。

编辑:如果你注意到我说的任何奇怪的概念是错误的,请纠正我,因为我是新手。由于这个原因,我更希望有人在他们的回答中冗长。

c++ opengl

1
推荐指数
1
解决办法
1415
查看次数

将整数模板参数值映射到基元类型

我想将数字映射到一个类型.对于这个例子,我将创建一个将sizeof()结果映射到有符号基元类型的函数.

我想知道是否有更好的方法来完成我在现代C++中所做的事情,即采用模板化值并将其转换为类型.现在这适用于将大小转换为已知类型,但我似乎无法在标准库中找到满足我想要的任何内容.我错过了什么吗?

如果没有,是否有更好的方法来执行此操作或清理此代码?例如,如果将来我们最终有128位类型,这将不支持.

#include <iostream>
#include <type_traits>

template <size_t S>
static constexpr auto sizeToType() {
    static_assert(S == 1 or S == 2 or S == 4 or S == 8, "Bad type size");

    if constexpr (S == 1)
        return int8_t{};
    else if constexpr (S == 2)
        return int16_t{};
    else if constexpr (S == 4)
        return int32_t{}; 
    else
        return int64_t{};
}

int main() {
    using MY_TYPE = decltype(sizeToType<2>());

    MY_TYPE myType = MY_TYPE(0xFFFFFFFFFFFFFFFEUL);

    std::cout << sizeof(MY_TYPE) << " bytes" << std::endl;
    std::cout …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++17

1
推荐指数
1
解决办法
147
查看次数

您可以通过扩展方法使一个可枚举的类吗?特别是System.Range

我现在正在使用最新的C#8,我在玩弄新的System.Range,想看看是否有类似的东西

foreach (int i in 5..8)
{ 
}
Run Code Online (Sandbox Code Playgroud)

可能,但是在撰写本文时(使用绝对前沿的预览)给我一个错误。

然后,我想知道是否可以通过在静态类中执行以下操作来使它可枚举,因为也许foreach循环实际上并不在乎,只希望存在某种可用的方法,所以我尝试了:

public static IEnumerator GetEnumerator(this Range range) 
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

但是编译器对此不满意。

这可能吗?还是我只是实现了无数错误?IDE中的错误消息告诉我GetEnumerator()需要可以foreach运行,但是由于我无法访问该类并且不能简单地执行: IEnumerable<int>该操作,然后从该类生成方法并执行所需的操作,因此我不这样做不知道这是否表示我被卡住或编码是否错误。

我的错误:

    foreach (int i in 1..5)
    {
        Console.WriteLine(i);
    }
Run Code Online (Sandbox Code Playgroud)

[CS1579] foreach语句无法对类型为“范围”的变量进行操作,因为“范围”不包含“ GetEnumerator”的公共实例定义

$ dotnet-版本

3.0.100-preview8-013656

以项目定位netcoreapp3.0并且C#语言级别是preview

c# c#-8.0

0
推荐指数
1
解决办法
139
查看次数