为什么 glm::mat3 和 glm::value_ptr 创造了一个穿越时间和宇宙的黑洞,并正在摧毁我脑海中任何可能的逻辑?
Why does glm::mat3 and glm::value_ptr creates a black hole through time and universe and is destroying any possible logic in my mind?
我正在使用著名的 OpenGL 框架创建一个漂亮的图形引擎,但后来出现了一个意想不到的问题(就像所有问题一样)。
我必须创建一个函数来修改 glm::mat3 中的特定值。为此,我创建了一个简单的函数,return 我是对 glm::mat3 中特定浮点数的简单引用,但似乎没有任何效果,我不知道是什么原因。
这是我的函数:
float& mat3ValueAt(glm::mat3& m, int l, int c) {
// l is the line index and c is the column index...
return glm::value_ptr(m)[3 * l + c];
}
为了查看它是否有效,我必须使用能够显示我的矩阵的函数:
std::ostream& operator<<(std::ostream& stream, glm::mat3 m) {
for (int i = 0; i < 9; i++) {
stream << GLS::mat3ValueAt(m, i / 3, i % 3) << ((i + 1) % 3 ? ' ' : '\n');
}
return stream;
}
所有这些都不起作用...但是没关系...一定是我的问题...所以我将我看起来不错的无效代码减少到我能找到的最小代码异常...
这就是我最终完全生气并让我发疯的原因:
int main() {
glm::mat3 m;
std::cout << "display uninitialised value..." << std::endl;
std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display an uninitialised value
*(glm::value_ptr(m) + 5) = 42;
std::cout << "display the initialised value" << std::endl;
std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display 42
}
这段小代码的结果是...
display uninitialised value...
42
display the initialised value
42
所以我之前的两个函数不起作用这一事实是可以的,也许我只是不知道 value_ptr 是如何工作的......但我很确定一件事......
一个值不能有我们要分配给它之前分配给它的值!
我输入的值而不是 42 并不重要,它总是在我赋值之前赋值!
这怎么可能?
这个:
glm::mat3 m;
创建一个未初始化的对象;此对象的内容具有不确定的值。任何尝试读取具有不确定值的对象的值都会导致未定义的行为。
因此,编译器可以随意 re-order 您的代码看起来像这样:
int main() {
glm::mat3 m;
*(glm::value_ptr(m) + 5) = 42;
std::cout << "display uninitialised value..." << std::endl;
std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display an uninitialised value
std::cout << "display the initialised value" << std::endl;
std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display 42
}
这是完全有效的,因为如果您在初始化之前尝试读取该值,您将处于未定义行为领域,并且已经初始化该值并不比任何其他未定义行为更正确。
我正在使用著名的 OpenGL 框架创建一个漂亮的图形引擎,但后来出现了一个意想不到的问题(就像所有问题一样)。
我必须创建一个函数来修改 glm::mat3 中的特定值。为此,我创建了一个简单的函数,return 我是对 glm::mat3 中特定浮点数的简单引用,但似乎没有任何效果,我不知道是什么原因。
这是我的函数:
float& mat3ValueAt(glm::mat3& m, int l, int c) {
// l is the line index and c is the column index...
return glm::value_ptr(m)[3 * l + c];
}
为了查看它是否有效,我必须使用能够显示我的矩阵的函数:
std::ostream& operator<<(std::ostream& stream, glm::mat3 m) {
for (int i = 0; i < 9; i++) {
stream << GLS::mat3ValueAt(m, i / 3, i % 3) << ((i + 1) % 3 ? ' ' : '\n');
}
return stream;
}
所有这些都不起作用...但是没关系...一定是我的问题...所以我将我看起来不错的无效代码减少到我能找到的最小代码异常...
这就是我最终完全生气并让我发疯的原因:
int main() {
glm::mat3 m;
std::cout << "display uninitialised value..." << std::endl;
std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display an uninitialised value
*(glm::value_ptr(m) + 5) = 42;
std::cout << "display the initialised value" << std::endl;
std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display 42
}
这段小代码的结果是...
display uninitialised value...
42
display the initialised value
42
所以我之前的两个函数不起作用这一事实是可以的,也许我只是不知道 value_ptr 是如何工作的......但我很确定一件事...... 一个值不能有我们要分配给它之前分配给它的值!
我输入的值而不是 42 并不重要,它总是在我赋值之前赋值!
这怎么可能?
这个:
glm::mat3 m;
创建一个未初始化的对象;此对象的内容具有不确定的值。任何尝试读取具有不确定值的对象的值都会导致未定义的行为。
因此,编译器可以随意 re-order 您的代码看起来像这样:
int main() {
glm::mat3 m;
*(glm::value_ptr(m) + 5) = 42;
std::cout << "display uninitialised value..." << std::endl;
std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display an uninitialised value
std::cout << "display the initialised value" << std::endl;
std::cout << *(glm::value_ptr(m) + 5) << std::endl; // should display 42
}
这是完全有效的,因为如果您在初始化之前尝试读取该值,您将处于未定义行为领域,并且已经初始化该值并不比任何其他未定义行为更正确。