有人认为这个很难做,其实在DirectX中是很方便做到的,就是利用视图转换技术(Viewport Transform)
视图其实就可以想象成一个镜头口,对着什么地方,就能显示什么地方的东西。而3D图形里面可以说是后台缓冲(back buffer)的所见的内容。一般游戏都是把视图窗口布满整个back buffer的,但是我们可以把back buffer分隔开,以前的三国无双是可以分上下屏,让两个玩家可以共用一台电脑来玩的。
Direct3D的viewport的数据结构表示为:
typedef struct _D3DVIEWPORT9 { DWORD X;//右上角坐标 DWORD Y; DWORD Width;//窗口长宽 DWORD Height; DWORD MinZ;//最小深度一般为0 DWORD MaxZ;//最大深度一般为1 } D3DVIEWPORT9;
应用:
D3DVIEWPORT9 vp = { 0, 0, 800, 600, 0, 1 }; Device->SetViewport(&vp);
西面例子是把平面平均分为4个小窗口并显示:
D3DVIEWPORT9 q1 = {w/2, 0, w/2, h/2, 0.0f, 1.0f}; D3DVIEWPORT9 q2 = {0, 0, w/2, h/2, 0.0f, 1.0f}; D3DVIEWPORT9 q3 = {0, h/2, w/2, h/2, 0.0f, 1.0f}; D3DVIEWPORT9 q4 = {w/2, h/2, w/2, h/2, 0.0f, 1.0f}; D3DVIEWPORT9 vps[4] = {q1, q2, q3, q4};
通过循环把这些窗口都显示出来:
gd3dDevice->BeginScene();//开始画图循环画4个屏幕,这是如何调用函数的地方 for(int i = 0; i < 4; ++i) { // The Clear function clears the currently set viewport. gd3dDevice->SetViewport(&vps[i]); gd3dDevice->Clear(0L, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffcccccc, 1.0f, 0L); mTeapot->DrawSubset(0); } gd3dDevice->EndScene();
Direct3D自动帮我们计算如何放置这些viewports了, 不过其底层原理就是用viewport矩阵来转换viewports的,这个矩阵也是用数学的公式计算出来的,矩阵非常复杂,一般记不住,不过要推导过,知道什么回事。
下面是程序画面: