在学习D3D11的时候遇到一个问题,事情是这样的:


D3D11引入了常量缓存(const buffer)用来实现

B0%E6%8D%AE">数据的高速传输,这块儿buffer是CPU Only Write,GPU Only Read这样的特点,其他还是D3D9的惯例。在我调用完g_pD3DImmediateContext->Map的时候,出现了没有任何图像的问题,后经过改造后,显示终于正常了,先上代码:

 // 传入shader前,确保矩阵转置,这是D3D11的要求
 pMatrix->m_mxWorld  	= XMMatrixTranspose(pMatrix->m_mxWorld);
 pMatrix->m_mxPorjection = XMMatrixTranspose(pMatrix->m_mxPorjection);
 pMatrix->m_mxView   = XMMatrixTranspose(pMatrix->m_mxView);
 //把基本的3个3D变换矩阵放进显存去,当然对于GPU来说它是只读的,而CPU是只写的
 D3D11_MAPPED_SUBRESOURCE MappedResource = {};
 // 将矩阵缓冲的显存映射进来,设置矩阵数据先
 HRESULT hr = g_pD3DImmediateContext->Map(g_pMatrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource);

 CopyMemory(MappedResource.pData,pMatrix,sizeof(ST_MATRIXBUFFER));
 g_pD3DImmediateContext->Unmap(g_pMatrixBuffer, 0);
 g_pD3DImmediateContext->VSSetConstantBuffers(0, 1, &g_pMatrixBuffer);

可以看到,pMatrix->m_mxWorld  ,pMatrix->m_mxPorjection ,pMatrix->m_mxView  三个矩阵都是在进行了转置之后才传入常量缓存的,之后画面显示正常了。为何要转置呢?经过一番打探原来事情是这个样子的:


首先我们要知道,矩阵分为行主序和列主序两种矩阵,比如:内存中使用一个二维数组m存储矩阵,第i行第j列的表示方法分别为:


行主序:m[i][j]


列主序:m[j][i]


线性代数意义的同一个矩阵,在D3D 和OpenGL 中的存储顺序:


线代:a11,a12,a13,a14


a21,a22,a23,a24


a31,a32,a33,a34


a41,a42,a43,a44


D3D :  a11,a12,a13,a14


a21,a22,a23,a24


a31,a32,a33,a34


a41,a42,a43,a44


OpenGL: a11,a21,a31,a41


a12,a22,a32,a42


a13,a23,a33,a43


a14,a24,a34,a44


D3D是左手定则,OpenGL是右手定则,另外提一句,OGRE用的也是列主序,我们发现只要把行主序和列主序的行列对调就可以了,也就是转置一下就一样了,也就是说D3D和OpenGL如果想转换的话只需要转置一下就ok,那D3D11这里为什么要转置呢,因为D3D11的constant buffer里面shader读取是列主序的读取,所以想在const buffer使用的话还是要转换成列主序,或者也可以编译shader的时候调用D3D10_SHADER_PACK_MATRIX_ROW_MAJOR这个来编译,其实效果是一样的,只不过转换做在了内部,其实早在D3D11之前GPU也是一直读取列主序的矩阵的,只不过转换在D3D驱动内部进行了而已。


或者还有一种方法就是声明这个矩阵的时候直接声明为列主序的矩阵:row_major。


还有一个方法就是在shader里面mul矩阵的时候用矩阵在前,向量在后的方法也可以:


float4 transformedPosition = somePosition * someMatrix;
        float4 transformedPosition = someMatrix * somePosition;


另外还要注意const buffer的desc权限 是 cpu only write &gpu only read。

为何D3D11的几个矩阵需要转置?的更多相关文章

  1. C语言 矩阵的转置及矩阵的乘法

    C语言 矩阵的转置及矩阵的乘法 //凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 1.矩阵的转置 #include<stdio.h> #defi ...

  2. C语言两种方式实现矩阵的转置

    #include"stdio.h" typedef struct{ int i,j; int v; }Triple; typedef struct{ Triple date[]; ...

  3. 关于python中矩阵的实现和矩阵的转置

    python中矩阵的实现是靠序列,,, 序列有很多形式, 其实矩阵是现实生活中的东西,把现实生活中的结构转换到程序中. 就需要有个实现的方法,而这种路径是多种多样的. 下面给出一个把矩阵转换成pyth ...

  4. C++写矩阵的转置

    (2019年2月19日注:这篇文章原先发在自己github那边的博客,时间是2017年2月5日) 对于任意非n阶矩阵的转置,用c++应该怎么写代码,思考了一下,发现并没有那么简单,上网找到了一个比较好 ...

  5. C语言-实现矩阵的转置-随机函数产生随机数并赋予数组中-190222

    //编写程序,实现矩阵的转置(行列互换). #include <stdio.h> #include <conio.h> #include <stdlib.h> ][ ...

  6. c++数组-矩阵的转置

    #include <iostream> using namespace std; int main(){ ][]={{,,},{,,}}; ][]; ;j<;j++){ ;i< ...

  7. <矩阵的基本操作:矩阵相加,矩阵相乘,矩阵转置>

    //矩阵的基本操作:矩阵相加,矩阵相乘,矩阵转置 #include<stdio.h> #include<stdlib.h> #define M 2 #define N 3 #d ...

  8. [置顶] [MATLAB技术贴]漫谈MATLAB矩阵转置

    矩阵转置是matlab最基本的操作了,但这个基本操作,也是很多初学者容易出现问题的地方.本帖通过几个实例演示matlab矩阵转置的操作. 方法一:'  运算符与  .'  运算符 >>a ...

  9. 矩阵转置 O(1)空间

    题目:用O(1)的空间实现矩阵的转置 为了方便,使用一维数组来分析.所谓矩阵转置,行变列,列变行.在转置的过程中,有的元素位置是不变的:对于变化位置的元素,要求O(1)空间完成,那么这些位置的变化一定 ...

随机推荐

  1. 用var 变量=函数名 方式调用函数时如何传值的问题

    通过:xmlhttp.onreadystatechange= function(){FuncName(param)};orxmlhttp.onreadystatechange= new Functio ...

  2. laravel 项目本地版本为5.5,线上mysql 为5.7.21版本,执行严格模式

    看到网上很多说修改 但是在mysql 5.7中没有这个参数设置,故放弃: 结合本项目sina_id 10位超过int的最大范围4294967295,所以报错,修改为bigint  即可.

  3. 【Leetcode链表】分隔链表(86)

    题目 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的初始相对位置. 示例: 输入: head = 1->4 ...

  4. bzoj4152 The Captain

    Description 给定平面上的n个点,定义(x1,y1)到(x2,y2)的费用为min(|x1-x2|,|y1-y2|),求从1号点走到n号点的最小费用. Input 第一行包含一个正整数n(2 ...

  5. SharpDX初学者教程第2部分:创建窗口

    原文 http://www.johanfalk.eu/blog/sharpdx-tutorial-part-2-creating-a-window 在第二篇教程中,我们将介绍如何创建一个稍后将呈现的简 ...

  6. SDUT-3340_数据结构实验之二叉树一:树的同构

    数据结构实验之二叉树一:树的同构 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给定两棵树T1和T2.如果T1可以通过 ...

  7. jquery attr()和prop()方法的区别

    $('').attr()返回的是html对象 $('').prop()返回的是DOM对象 attr(): attr() 方法设置或返回被选元素的属性和值. 当该方法用于返回属性值,则返回第一个匹配元素 ...

  8. oracle函数 end

    [功能]当:<表达式>=<表达式条件值1……n> 时,返回对应 <满足条件时返回值1……n> 当<表达式条件值1……n>不为条件表达式时,与函数deco ...

  9. Python深入:stevedore简介

    stevedore是用来实现动态加载代码的开源模块.它是在OpenStack中用来加载插件的公共模块.可以独立于OpenStack而安装使用:https://pypi.python.org/pypi/ ...

  10. @codeforces - 618G@ Combining Slimes

    目录 @description@ @solution@ @part - 0@ @part - 1@ @part - 2@ @part - 3@ @accepted code@ @details@ @d ...