要彻底理解好如何旋转一个物体原来也不是很容易的事情
这里有一个比较难理解的问题:
为什么有些书本上说:利用transformation操作,重复绘制同一个物体(比如要画很多球),比直接在不同位置直接画球要节省很多计算时间了。其中的本质原理是什么呢?
一个简单场景的选择有三个选择的方法:
1 旋转世界坐标
2 旋转物体在世界坐标中的位置
3 旋转镜头位置
方法1
可以不断更新世界矩阵,比如原来的世界矩阵是个单位矩阵,那么不断更新这个矩阵,就可以改变物体的显示位置了
代码:
void UpdateScene(float dt)
{
//无关代码……
static double t = dt;
t += dt;
XMStoreFloat4x4(&world, XMMatrixRotationY(t));
//无关代码……
}
dt为每帧刷新需要的时间,利用变量t记录总更新时间,不断使得世界矩阵world围绕y轴更新,呈现出来的效果就是物体不断旋转。
方法2
不过其实上面的做法也不过是人为理解的问题罢了,为什么这么说呢?
因为我们一般设置世界矩阵world为单位矩阵(为什么?这个是世界中心了,习惯是这样,也为了计算和理解方便),
那么我们也可以这么理解:
我们的世界矩阵乘以任何矩阵都等于任何矩阵,所以我们可以保留世界矩阵,增加一个额外矩阵,比如是rotate_M,
因为渲染任何物体都需要把物体放置到世界坐标中,那么就需要把这个物体的坐标乘以世界矩阵,然后我们在乘以rotate_M,那么就相当于把改变了物体在世界坐标中的位置了。
代码如下:
auto rotate_M = XMMatrixIdentity();
void UpdateScene(float dt)
{
//无关代码……
static double t = dt;
t += dt;
//XMStoreFloat4x4(&world, XMMatrixRotationY(t));
rotate_M = XMMatrixRotationY(t);
//无关代码……
}
这样不断更新rotate_M矩阵,然后在渲染之前乘以这个矩阵,代码如下:
void DrawScene()
{
//无关代码……
XMMATRIX w = XMLoadFloat4x4(&world);
XMMATRIX v = XMLoadFloat4x4(&view);
XMMATRIX p = XMLoadFloat4x4(&proj);
XMMATRIX wvp = rotate_M*w*v*p;
fx_world_view_proj->SetMatrix(reinterpret_cast<float*>(&wvp));
D3DX11_TECHNIQUE_DESC tech_desc;
tech->GetDesc( &tech_desc );
for(UINT i = 0; i < tech_desc.Passes; ++i)
{
tech->GetPassByIndex(i)->Apply(0, md3dImmediateContext);
md3dImmediateContext->DrawIndexed(36, 0, 0);
}
HR(mSwapChain->Present(0, 0));
}
方法1 和方法2 其实也是人为理解的区别,其实质并没什么区别。
对于方法2,我之前一直有一个误解,就是认为,如果旋转或移动一个模型,是需要把这个模型的所有顶点都乘以一个旋转矩阵的。
实际上是不需要这么操作的,如上面的代码旋转一个物体,就是多乘以一个rotate_M矩阵,并没有增加时间复杂度。
这也是为什么有些书本上说:利用transformation操作,重复绘制同一个物体(比如要画很多球),比直接在不同位置直接画球要节省很多计算时间了。
方法3
这就相当于第一人称视觉的改变了,具体方法可以参考我另一篇博客:http://blog.youkuaiyun.com/kenden23/article/details/14051187