- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我对矩阵定义感到非常困惑。我有一个矩阵类,它包含一个 float[16]
,我认为它是行主要的,基于以下观察:
float matrixA[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
float matrixB[4][4] = { { 0, 1, 2, 3 }, { 4, 5, 6, 7 }, { 8, 9, 10, 11 }, { 12, 13, 14, 15 } };
matrixA
和 matrixB
在内存中都具有相同的线性布局(即所有数字都按顺序排列)。根据http://en.wikipedia.org/wiki/Row-major_order这表示以行为主的布局。
matrixA[0] == matrixB[0][0];
matrixA[3] == matrixB[0][3];
matrixA[4] == matrixB[1][0];
matrixA[7] == matrixB[1][3];
因此,matrixB[0]
= 第 0 行,matrixB[1]
= 第 1 行,等等。同样,这表示行优先布局。
当我创建一个如下所示的翻译矩阵时,我的问题/困惑出现了:
1, 0, 0, transX
0, 1, 0, transY
0, 0, 1, transZ
0, 0, 0, 1
在内存中的布局为,{ 1, 0, 0, transX, 0, 1, 0, transY, 0, 0, 1, transZ, 0, 0, 0, 1 }
.
然后当我调用 glUniformMatrix4fv ,我需要将转置标志设置为 GL_FALSE,表明它是列优先的,否则无法正确应用诸如平移/缩放等转换:
If transpose is GL_FALSE, each matrix is assumed to be supplied in column major order. If transpose is GL_TRUE, each matrix is assumed to be supplied in row major order.
为什么我的矩阵(看起来是行优先的)需要作为列优先传递给 OpenGL?
最佳答案
opengl 文档中使用的矩阵表示法没有描述 OpenGL 矩阵的内存布局
如果您认为放弃/忘记整个“行/列主要”的事情会更容易。这是因为除了行/列专业之外,程序员还可以决定他希望如何在内存中布置矩阵(相邻元素是形成行还是列),除了符号,这会增加困惑。
OpenGL 矩阵有 same memory layout as directx matrices .
x.x x.y x.z 0
y.x y.y y.z 0
z.x z.y z.z 0
p.x p.y p.z 1
或
{ x.x x.y x.z 0 y.x y.y y.z 0 z.x z.y z.z 0 p.x p.y p.z 1 }
x、y、z 是描述矩阵坐标系(相对于全局坐标系内的局部坐标系)的三分量 vector 。
p 是描述矩阵坐标系原点的三分量 vector 。
这意味着翻译矩阵应该像这样在内存中布局:
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, transX, transY, transZ, 1 }.
就这样吧,剩下的应该很容易了。
---来自旧的opengl faq的引用--
9.005 Are OpenGL matrices column-major or row-major?
For programming purposes, OpenGL matrices are 16-value arrays with base vectors laid out contiguously in memory. The translation components occupy the 13th, 14th, and 15th elements of the 16-element matrix, where indices are numbered from 1 to 16 as described in section 2.11.2 of the OpenGL 2.1 Specification.
Column-major versus row-major is purely a notational convention. Note that post-multiplying with column-major matrices produces the same result as pre-multiplying with row-major matrices. The OpenGL Specification and the OpenGL Reference Manual both use column-major notation. You can use any notation, as long as it's clearly stated.
Sadly, the use of column-major format in the spec and blue book has resulted in endless confusion in the OpenGL programming community. Column-major notation suggests that matrices are not laid out in memory as a programmer would expect.
我要更新这个 9 年前的答案。
一个数学矩阵被定义为m x n
矩阵。其中m
是行 的数量,n
是列 的数量。为了完整起见,行是水平的,列是垂直的。当用数学符号 Mij
表示矩阵元素时,第一个元素 (i
) 是行索引,第二个元素 (j
) 是列索引。当两个矩阵相乘时,即 A(m x n) * B(m1 x n1)
,得到的矩阵具有来自第一个参数的行数 (A
),并且 number第二个参数 (B
) 的列数,第一个参数 (A
) 的列数必须与第二个参数 (B
) 的行数匹配>)。所以 n == m1
。到此为止,是吗?
现在,关于内存布局。您可以通过两种方式存储矩阵。行优先和列优先。 Row-major 意味着有效地你有一个又一个线性排列的行。所以,元素从左到右,一行接一行。有点像英文文本。 Column-major 意味着你有列一个接一个地线性排列。所以元素从左上角开始,从上到下。
例子:
//matrix
|a11 a12 a13|
|a21 a22 a23|
|a31 a32 a33|
//row-major
[a11 a12 a13 a21 a22 a23 a31 a32 a33]
//column-major
[a11 a21 a31 a12 a22 a32 a13 a23 a33]
现在,有趣的部分来了!
有两种方法可以将 3d 变换存储在矩阵中。正如我之前提到的,3d 中的矩阵本质上存储坐标系基 vector 和位置。因此,您可以将这些 vector 存储在矩阵的行或列中。当它们存储为列时,您将矩阵与列 vector 相乘。像这样。
//convention #1
|vx.x vy.x vz.x pos.x| |p.x| |res.x|
|vx.y vy.y vz.y pos.y| |p.y| |res.y|
|vx.z vy.z vz.z pos.z| x |p.z| = |res.z|
| 0 0 0 1| | 1| |res.w|
但是,您也可以将这些 vector 存储为行,然后将行 vector 与矩阵相乘:
//convention #2 (uncommon)
| vx.x vx.y vx.z 0|
| vy.x vy.y vy.z 0|
|p.x p.y p.z 1| x | vz.x vz.y vz.z 0| = |res.x res.y res.z res.w|
|pos.x pos.y pos.z 1|
所以。约定#1 经常出现在数学课本中。约定 #2 在某个时候出现在 DirectX sdk 中。两者都有效。
关于这个问题,如果您使用约定 #1,那么您的矩阵是列优先的。如果您使用约定 #2,那么它们是行专业的。但是,两种情况下的内存布局是一样的
[vx.x vx.y vx.z 0 vy.x vy.y vy.z 0 vz.x vz.y vz.z 0 pos.x pos.y pos.z 1]
这就是为什么我说 9 年前更容易记住哪个元素是哪个。
关于c++ - C++ 和 OpenGL 矩阵顺序之间的混淆(行优先 vs 列优先),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17717600/
我是 Mercurial 的新手,并且不知何故仍处于评估过程中,所以这四个概念对我来说有点困惑。有些被提到等同于 Git 的 Staging/Index 概念,有些甚至比 Git 的 Staging
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 6 个月前关闭。 Improve this ques
任何人都可以给我详细信息吗? 例如? #ID 是属性、特性、选择器还是 anchor ? 默认属性和默认属性是不同的东西吗? 这些都是标签还是元素? 我们将对此说些什么 这个 ..... 还有这些
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 8 年前。 Improve this qu
我有一个由 Javascript 填充的下拉列表。 在决定加载时显示的默认值时,我意识到以下属性显示的值完全相同: innerText innerHTML label text textContent
我可以知道每个 Exec 之间有什么区别吗? , ExecWait , ExecShell , nsExec::Exec , nsExec::ExecToLog, nsExec::ExecToStac
当您处于版本 1 和版本 2 之间时,您会如何维护您的软件? 从我的角度来看,“补丁”、“修补程序”、“维护版本”、“服务包”等术语都很模糊,根据与您交谈的对象不同,定义也不同。 您如何称呼版本之间的
我刚刚发现在 ES6 中有一个新的数学方法:Math.trunc . 我在 MDN article 中阅读了它的描述。 , 听起来像使用 |0 . 此外,>0 , &-1 , ^0也做类似的事情(感谢
我想知道我的 StackPanel 所有项目的高度。 有什么区别: Height - 获取或设置元素的建议高度。 ActualHeight - 获取该元素的渲染高度。 (只读) ExtentHeigh
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
我对所有声称以某种方式阻止计算的内置 Mathematica 函数感到困惑:Unevaluated、Defer、Hold ,以及超过 6 个 Hold* 形式。 Mathematica 文档只是单独解
我什至不确定正确的术语,所以让我从我的目标开始:拥有一个简单的应用程序(“Data Doler”),它只会将大量数据从文件读取到内存中,然后提供服务将该数据切片到名为“Data Lapper”的单个多
我刚刚开始在我的项目中使用 Elasticsearch,我想像 sql 关键字一样搜索 '喜欢%' 做。 谁能解释一下 之间的区别通配符 , 前缀 , 查询字符串和 正则表达式 ? 哪个可以搜索最好性
由于我对任何主流浏览器(Firefox、Chrome、Opera)都不太满意,而且我尝试过的不太受欢迎的浏览器(近十几种)都没有,所以我决定 DIY 并制作一个网页我想要最好的浏览器。 主要目标是让它
我知道如何使用 Python 解析页面。我的问题是哪种方法是所有解析技术中最快的,其他方法的速度有多快? 我知道的解析技术有Xpath、DOM、BeautifulSoup,还有使用Python的fin
我试图从正在解析的命令行中找出哪个函数最适合将十进制、十六进制或八进制数转换为 int 最好——在不知道输入的情况下事先。 目标是使用一个函数来识别不同类型的输入并将其分配给它的整数 (int) 值,
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我们需要在我们的网站上显示酒吧、餐馆和剧院等各种场所的元信息(例如,地址、姓名)。 理想情况下,用户会输入地点名称以及邮政编码,我们会提供最接近的匹配项。 人们将哪些 API 用于类似的地理定位目的?
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在创建我的第一个 Web 应用程序,我真的很困惑应该使用什么技术。 我的应用程序需要看起来很严肃(像一个应用程序),它不需要很多色彩缤纷的图形界面。它只需要一个工具栏、一个标签栏、一个拆分面板(最
我是一名优秀的程序员,十分优秀!