在学习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. Android实战:手把手实现“捧腹网”APP(三)-----UI实现,逻辑实现

    Android实战:手把手实现"捧腹网"APP(一)-–捧腹网网页分析.数据获取 Android实战:手把手实现"捧腹网"APP(二)-–捧腹APP原型设计.实 ...

  2. pycahrm安装说明

    从官网下载http://www.jetbrains.com/pycharm/download/other.html(PS:现在需要翻墙可以直接用文件夹里的那个) 下载完成后双击文件 第二步:双击已下载 ...

  3. phpcms url路由规则、多站点、PC手机切换

    解决一个分站点pc手机共存的问题 首先需要有PC手机两套模板.通过修改url路由规则,在同一目录下生成PC手机两套静态网站,PC使用默认url路由规则,手机端使用文件名追加“_m”的路由规则. 然后通 ...

  4. Spark in action on Kubernetes - 存储篇(一)

    前言 在上篇文章中,我们分析了Spark Operator内部的机制,今天我们会讨论一个在大数据领域中最重要的话题 - 存储.大数据已经无声无息的融入了每个人的生活中.大到旅游买房,小到外卖打车,都可 ...

  5. LeetCode113 Path Sum II

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...

  6. Git 的两种忽略文件方式 gitignore 和 exclude

    Git 的两种忽略文件方式 gitignore 和 exclude .gitignore 不用说了,大家都知道. 有一个 exclude 可能接触比较少. 知道这个功能后发现,用在服务器上非常方便,因 ...

  7. 2019-8-31-dotnet-使用-MessagePack-序列化对象

    title author date CreateTime categories dotnet 使用 MessagePack 序列化对象 lindexi 2019-08-31 16:55:58 +080 ...

  8. Python语言的特点

  9. epoll简介(一)

    一:概述   1:简介 EPOLL类似于POLL,是Linux特有的一种IO多路复用的机制.它在2.5.44内核中引入. 对于大量的描述符处理,EPOLL更有优势,它提供了三个系统调用来创建管理epo ...

  10. Getting started with the basics of programming exercises_4

    1.编写一个删除C语言程序中所有的注释语句的程序.要正确处理带引号的字符串与字符串常量,C语言中程序注释不允许嵌套. #include<stdio.h> void rcomment(int ...