显示每个监视器不同的图像directX 10 [英] Display Different images per monitor directX 10

查看:226
本文介绍了显示每个监视器不同的图像directX 10的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是DirectX 10编程的新手,我一直在努力用我有限的技能(虽然我有一个强大的背景与OpenGL)。



我试图显示2不同纹理的四边形,每个显示器1。要这样做,我明白我需要一个D3D10设备,多(2)交换链和单个VertexBuffer



虽然我想我可以创建所有的那些,我还是很不确定如何处理所有的。我需要多个ID3D10RenderTargetView吗?如何和在哪里使用OMSetRenderTargets(...)?



除了MSDN,这些概念的文档或解释是相当有限的,所以任何帮助将是非常欢迎。这是一些代码我有:



这是渲染代码

  for(int i = 0; i  // clear scene 
pD3DDevice-> ClearRenderTargetView(pRenderTargetView,D3DXCOLOR(0,1,0,0));

//用顶点填充顶点缓冲区
UINT numVertices = 4;
vertex * v = NULL;

//为CPU使用锁顶点缓冲区
pVertexBuffer-> Map(D3D10_MAP_WRITE_DISCARD,0,(void **)& v);

v [0] = vertex(D3DXVECTOR3(-1,-1,0),D3DXVECTOR4(1,0,0,1),D3DXVECTOR2(0.0f,1.0f));
v [1] = vertex(D3DXVECTOR3(-1,1,0),D3DXVECTOR4(0,1,0,1),D3DXVECTOR2(0.0f,0.0f));
v [2] = vertex(D3DXVECTOR3(1,-1,0),D3DXVECTOR4(0,0,1,1),D3DXVECTOR2(1.0f,1.0f));
v [3] = vertex(D3DXVECTOR3(1,1,0),D3DXVECTOR4(1,1,0,1),D3DXVECTOR2(1.0f,0.0f));

pVertexBuffer-> Unmap();

//设置原始拓扑
pD3DDevice-> IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

//设置纹理
pTextureSR-> SetResource(textureSRV [textureIndex]);

//获取技术desc
D3D10_TECHNIQUE_DESC techDesc;
pBasicTechnique-> GetDesc(& techDesc);


//这是你实际使用着色器代码
(UINT p = 0; p< techDesc.Passes; ++ p)
{
// apply technique
pBasicTechnique-> GetPassByIndex(p) - > Apply(0);

// draw
pD3DDevice-> Draw(numVertices,0);
}

// flip buffers
pSwapChain [i] - > Present(0,0);
}

这里是创建渲染目标的代码,我不确定是好

  for(int i = 0; i< screenNumber; ++ i){

/ /尝试获取后台缓冲区
ID3D10Texture2D * pBackBuffer;
if(FAILED(pSwapChain [1] - > GetBuffer(0,__uuidof(ID3D10Texture2D),(LPVOID *)& pBackBuffer)))return fatalError(Could not get back buffer);

//尝试创建渲染目标视图
if(FAILED(pD3DDevice-> CreateRenderTargetView(pBackBuffer,NULL,& pRenderTargetView)))return fatalError(Could not create render target view );

pBackBuffer-> Release();
pD3DDevice-> OMSetRenderTargets(1,& pRenderTargetView,NULL);
}

return true;

}

解决方案

我希望我得到你想做的主旨 - 在两个不同的显示器上渲染不同的内容,同时使用单个显卡(图形适配器)将其输出映射到这些显示器。为此,你将需要一个设备(对于单个显卡/适配器),并枚举用户机器上有多少输出。



因此,总计 - 这意味着一个设备,两个输出,两个窗口,因此 - 两个交换链。



这是我的小实验的快速结果:





一点简介



使用DirectX 10+,这属于DXGI基础设施),它管理涉及DirectX 10+开发的常见低级物流,您可能知道,它倾销了枚举功能集等的旧要求 - 要求每个支持DX10 +的卡共享所定义的所有功能API。唯一不同的是卡的范围和能力(换句话说,糟糕的性能比应用程序崩溃和燃烧更可取)。这是所有在DirectX 9过去,但微软的人决定把它拉出来,称之为DXGI。现在,我们可以使用DXGI功能设置多监视器环境。


我需要多个ID3D10RenderTargetView吗?


是的,你需要多个渲染目标视图,计数取决于你拥有的监视器数量(如交换链和窗口)。但是,为了节省你从喷吐的话,让我们尽可能简单和需要的额外信息写:




  • 枚举所有适配器

  • 对于每个适配器,枚举所有可用(和活动)输出并创建一个设备。

  • 存储在合适的结构中(考虑可以快速释放大小信息的数组),使用它来创建n个窗口,交换链,渲染目标视图,深度/模板纹理和它们各自的视图,其中n等于输出的数量。 li>
  • 创建的所有内容,对于要渲染到的每个窗口,您可以定义特殊例程,使用可用的几何(和其他)数据输出结果 - 这将解析为每个监视器获取的内容全屏(不要忘记相应地调整每个窗口的视口)。

  • 使用Present()迭代连接到其相应窗口和交换缓冲区的每个交换链,显示您的数据



现在,虽然这是丰富的字数,一些代码值得更多。这是为了给你一个粗略的想法,实现一个简单的multimonitor应用程序。所以,假设是只有一个适配器(现在一个相当粗糙的语句)和多个输出 - 没有故障堆。我会把有趣的部分给你。 第二个问题的答案是楼下...



请注意,没有涉及内存管理。我们假设一切神奇地获得清理,当它不需要为说明的目的。



$ p> IDXGIAdapter * adaptor = NULL;
void GetAdapter()//适用于多个不太费力
{
//记住,我们假设只有一个适配器(示例)
for(int i = 0 ; DXGI_ERROR_NOT_FOUND!= factory-> EnumAdapters(i,& adapter); ++ i)
{

//获取适配器的描述,假设没有失败
DXGI_ADAPTER_DESC adapterDesc;
HRESULT hr = adapter-> GetDesc(& adapterDesc);

//使输出在我们的适配器上有效
EnumOutputsOnAdapter();

}

获取适配器上的输出

  std :: vector< IDXGIOutput *>输出数组//包含每个适配器的输出
void EnumOutputsOnAdapter()
{
IDXGIOutput * output = NULL;
for(int i = 0; DXGI_ERROR_NOT_FOUND!= adapter-> EnumOutputs(i,& output); ++ i)
{

//获取描述
DXGI_OUTPUT_DESC outputDesc;
HRESULT hr = output-> GetDesc(& outputDesc);

outputArray.push_back(output);
}

}

现在, 至少知道Win32 API的注意事项,创建窗口类,注册系统,创建窗口等等。因此,我不会限定其创建,只详细说明它是如何涉及多个窗口。此外,我将只考虑全屏的情况下,但在窗口模式下创建是可能的,而是微不足道。



为我们的输出创建实际的窗口

一个适配器,我们只考虑链接到该特定适配器的枚举输出。最好是在整洁的小结构中组织所有窗口数据,但是为了这个答案的目的,我们只是将它们推入一个简单的结构体,然后进入另一个std :: vector对象,相应的窗口(HWND)和它们的大小(虽然对于我们的例子它是常量)。



但是,我们必须解决这样的事实,我们有一个交换链目标视图,每个窗口一个深度/模板视图。所以,为什么不把所有这些描述每个窗口的小结构中?有意义吗?

  struct WindowDataContainer 
{
// Direct3D每窗口数据10项$ b IDXGISwapChain * swapChain;
ID3D10RenderTargetView * renderTargetView;
ID3D10DepthStencilView * depthStencilView;

//窗口好的东西
HWND hWnd;
int width;
int height;
}

尼斯。嗯,不是真的。但仍然...继续!现在为输出创建窗口:

  std :: vector< WindowDataContainer *> windowsArray; 
void CreateWindowsForOutputs()
{
for(int i = 0; i< outputArray.size(); ++ i)
{

IDXGIOutput * output = outputArray.at(i);
DXGI_OUTPUT_DESC outputDesc;
p_Output-> GetDesc(& outputDesc);
int x = outputDesc.DesktopCoordinate.left;
int y = outputDesc.DesktopCoordinates.top;
int width = outputDesc.DesktopCoordinates.right - x;
int height = outputDesc.DesktopCoordinates.bottom - y;

//不要忘记清理它。和所有D3D COM对象。
WindowDataContainer * window = new WindowDataContainer;

window-> hWnd = CreateWindow(windowClassName,
windowName,
WS_POPUP,
x,
y,
width,
height,
NULL,
0,
instance,
NULL);

//显示窗口
ShowWindow(window-> hWnd,SW_SHOWDEFAULT);

//设置宽度和高度
window-> width = width;
window-> height = height;

//在std :: vector中$ sho
windowsArray.push_back(window);

//如果第一个窗口,将其与DXGI关联,以便它可以跳转
//当消息队列中有兴趣时
//认为全屏模式切换等。MSDN了解更多信息。
if(i == 0)
factory-> MakeWindowAssociation(window-> hWnd,0);

}
}

可爱,现在已经完成了。由于我们只有一个适配器,因此只有一个设备陪伴它,像往常一样创建它。在我的情况下,它只是一个全局接口指针,可以访问所有的地方。我们不是在这里的代码,所以为什么不是,eh?



创建交换链,视图和深度/模板二维纹理

现在,我们的友好交换链...你可能习惯于通过调用naked函数来创建它们 D3D10CreateDeviceAndSwapChain (...),但正如你所知,我们已经制作了我们的设备。我们只想要一个。和多个互换链。好吧,这是一个泡菜。幸运的是,我们的DXGIFactory接口在其生产线上有交换链,我们可以免费获得补充的朗姆酒桶。然后,为每个窗口创建一个:

  void CreateSwapChainsAndViews()
{
(int i = 0; i {
WindowDataContainer * window = windowsArray.at(i);

//获取dxgi设备
IDXGIDevice * DXGIDevice = NULL;
device-> QueryInterface(IID_IDXGIDevice,(void **)& DXGIDevice); // COM的东西,希望你熟悉

//创建一个交换链
DXGI_SWAP_CHAIN_DESC swapChainDesc;

//填入

HRESULT hr = factory-> CreateSwapChain(DXGIDevice,& swapChainDesc,& p_Window-> swapChain);
DXGIDevice-> Release();
DXGIDevice = NULL;

//获取backbuffer
ID3D10Texture2D * backBuffer = NULL;
hr = window-> swapChain-> GetBuffer(0,IID_ID3D10Texture2D,(void **)& backBuffer);

//获取backbuffer desc
D3D10_TEXTURE2D_DESC backBufferDesc;
backBuffer-> GetDesc(& backBufferDesc);

//创建渲染目标视图
D3D10_RENDER_TARGET_VIEW_DESC RTVDesc;

//填入

device-> CreateRenderTargetView(backBuffer,& RTVDesc,& window-> renderTargetView);
backBuffer-> Release();
backBuffer = NULL;

//创建深度模板纹理
ID3D10Texture2D * depthStencil = NULL;
D3D10_TEXTURE2D_DESC descDepth;

//填入


device-> CreateTexture2D(& descDepth,NULL,& depthStencil);

//创建深度模板视图
D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;

//填入

device-> CreateDepthStencilView(depthStencil,& descDSV,& window-> depthStencilView);

}

}

我们需要的一切。所有你需要做的是定义一个函数,它迭代所有窗口,并适当地绘制不同的东西。


我应该如何使用OMSetRenderTargets (...)?


在刚刚提到的函数中,它遍历所有窗口并使用适当的渲染目标-window data container):

  void MultiRender()
{
//清除所有
for(int i = 0; i {
WindowDataContainer * window = windowsArray.at(i);

//有第二个问题的答案:
device-> OMSetRenderTargets(1,& window-> renderTargetView,window-> depthStencilView);

//不要忘记调整视口,全屏不重要...
D3D10_VIEWPORT Viewport;
Viewport.TopLeftX = 0;
Viewport.TopLeftY = 0;
Viewport.Width = window-> width;
Viewport.Height = window-> height;
Viewport.MinDepth = 0.0f;
Viewport.MaxDepth = 1.0f;
device-> RSSetViewports(1,& Viewport);

// TO DO:AMAZING STUFF PER WINDOW
}
}


b $ b

当然,不要忘记每个窗口基础上运行所有的交换链和交换缓冲区。这里的代码只是为了这个答案的目的,它需要一些更多的工作,错误检查(故障)和沉思得到它的工作方式,你喜欢它 - 换句话说 - 它应该给你一个简化的概述,而不是生产解决方案。



祝你好运和快乐的编程! Sheesh,这是巨大的。


I am fairly new to DirectX 10 programming, and I have been trying to do the following with my limited skills (though I have a strong background with OpenGL)

I am trying to display 2 different textured Quads, 1 per monitor. To do so, I understood that I need a single D3D10 Device, multiple (2) swap chains, and single VertexBuffer

While I think I'm able to create all of those, I'm still pretty unsure how to handle all of them. Do I need multiple ID3D10RenderTargetView(s) ? How and where should I Use OMSetRenderTargets(...) ?

Other than MSDN, documentation or explaination of those concepts are rather limited, so any help would be very welcome. Here is some code I have :

Here's the rendering code

for(int i = 0; i < screenNumber; i++){
    //clear scene
    pD3DDevice->ClearRenderTargetView( pRenderTargetView, D3DXCOLOR(0,1,0,0) );

    //fill vertex buffer with vertices
    UINT numVertices = 4;   
    vertex* v = NULL;   

    //lock vertex buffer for CPU use
    pVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**) &v );

    v[0] = vertex( D3DXVECTOR3(-1,-1,0), D3DXVECTOR4(1,0,0,1), D3DXVECTOR2(0.0f, 1.0f) );
    v[1] = vertex( D3DXVECTOR3(-1,1,0), D3DXVECTOR4(0,1,0,1), D3DXVECTOR2(0.0f, 0.0f) );
    v[2] = vertex( D3DXVECTOR3(1,-1,0), D3DXVECTOR4(0,0,1,1), D3DXVECTOR2(1.0f, 1.0f) );
    v[3] = vertex( D3DXVECTOR3(1,1,0), D3DXVECTOR4(1,1,0,1), D3DXVECTOR2(1.0f, 0.0f) ); 

    pVertexBuffer->Unmap();

    // Set primitive topology 
    pD3DDevice->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP );

    //set texture
    pTextureSR->SetResource( textureSRV[textureIndex] );

    //get technique desc
    D3D10_TECHNIQUE_DESC techDesc;
    pBasicTechnique->GetDesc( &techDesc );


    // This is where you actually use the shader code
    for( UINT p = 0; p < techDesc.Passes; ++p )
    {
        //apply technique
        pBasicTechnique->GetPassByIndex( p )->Apply( 0 );

        //draw
        pD3DDevice->Draw( numVertices, 0 );
    }

    //flip buffers
    pSwapChain[i]->Present(0,0);
}

And here's the code for creating rendering targets, which I am not sure is good

for(int i = 0; i < screenNumber; ++i){

    //try to get the back buffer
    ID3D10Texture2D* pBackBuffer;   
    if ( FAILED( pSwapChain[1]->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*) &pBackBuffer) ) ) return fatalError("Could not get back buffer");

    //try to create render target view
    if ( FAILED( pD3DDevice->CreateRenderTargetView(pBackBuffer, NULL, &pRenderTargetView) ) ) return fatalError("Could not create render target view");

    pBackBuffer->Release();
    pD3DDevice->OMSetRenderTargets(1, &pRenderTargetView, NULL);
}

return true;

}

解决方案

I hope I got the gist of what you wish to do - render different content on two different monitors while using a single graphics card (graphics adapter) which maps its output to those monitors. For that, you're going to need one device (for the single graphics card/adapter) and enumerate just how many outputs there are at the user's machine.

So, in total - that means one device, two outputs, two windows and therefore - two swap chains.

Here's a quick result of my little experiment:

A little introduction

With DirectX 10+, this falls into the DXGI (DirectX Graphics Infrastructure) which manages the common low-level logistics involved with DirectX 10+ development which, as you probably know, dumped the old requirement of enumerating feature sets and the like - requiring every DX10+ capable card to share in on all of the features defined by the API. The only thing that varies is the extent and capability of the card (in other words, lousy performance is preferable to the app crashing and burning). This was all within DirectX 9 in the past, but people at Microsoft decided to pull it out and call it DXGI. Now, we can use DXGI functionality to set up our multi monitor environment.

Do I need multiple ID3D10RenderTargetView(s) ?

Yes, you do need multiple render target views, count depends (like the swap chains and windows) on the number of monitors you have. But, to save you from spewing words, let's write it out as simple as possible and additional information where it's needed:

  • Enumerate all adapters available on the system.
  • For each adapter, enumerate all outputs available (and active) and create a device to accompany it.
  • With the enumerated data stored in a suitable structure (think arrays which can quickly relinquish size information), use it to create n windows, swap chains, render target views, depth/stencil textures and their respective views where n is equal to the number of outputs.
  • With everything created, for each window you are rendering into, you can define special routines which will use the available geometry (and other) data to output your results - which resolves to what each monitor gets in fullscreen (don't forget to adjust the viewport for every window accordingly).
  • Present your data by iterating over every swap chain which is linked to its respective window and swap buffers with Present()

Now, while this is rich in word count, some code is worth a lot more. This is designed to give you a coarse idea of what goes into implementing a simple multimonitor application. So, assumptions are that there is only one adapter ( a rather bold statement nowadays ) and multiple outputs - and no failsafes. I'll leave the fun part to you. Answer to the second question is downstairs...

Do note there's no memory management involved. We assume everything magically gets cleaned up when it is not needed for illustration purposes. Be a good memory citizen.

Getting the adapter

IDXGIAdapter* adapter = NULL;
void GetAdapter() // applicable for multiple ones with little effort
{
    // remember, we assume there's only one adapter (example purposes)
    for( int i = 0; DXGI_ERROR_NOT_FOUND != factory->EnumAdapters( i, &adapter ); ++i )
    {

        // get the description of the adapter, assuming no failure
        DXGI_ADAPTER_DESC adapterDesc;
        HRESULT hr = adapter->GetDesc( &adapterDesc );

        // Getting the outputs active on our adapter
        EnumOutputsOnAdapter();

}

Acquiring the outputs on our adapter

std::vector<IDXGIOutput*> outputArray; // contains outputs per adapter
void EnumOutputsOnAdapter()
{
    IDXGIOutput* output = NULL;
    for(int i = 0; DXGI_ERROR_NOT_FOUND != adapter->EnumOutputs(i, &output); ++i)
    {

        // get the description
        DXGI_OUTPUT_DESC outputDesc;
        HRESULT hr = output->GetDesc( &outputDesc );

        outputArray.push_back( output );
    }

}

Now, I must assume that you're at least aware of the Win32 API considerations, creating window classes, registering with the system, creating windows, etc... Therefore, I will not qualify its creation, only elaborate how it pertains to multiple windows. Also, I will only consider the fullscreen case here, but creating it in windowed mode is more than possible and rather trivial.

Creating the actual windows for our outputs

Since we assume existence of just one adapter, we only consider the enumerated outputs linked to that particular adapter. It would be preferable to organize all window data in neat little structures, but for the purposes of this answer, we'll just shove them into a simple struct and then into yet another std::vector object, and by them I mean handles to respective windows (HWND) and their size (although for our case it's constant).

But still, we have to address the fact that we have one swap chain, one render target view, one depth/stencil view per window. So, why not feed all of that in that little struct which describes each of our windows? Makes sense, right?

struct WindowDataContainer
{
    //Direct3D 10 stuff per window data
    IDXGISwapChain* swapChain;
    ID3D10RenderTargetView* renderTargetView;
    ID3D10DepthStencilView* depthStencilView;

    // window goodies
    HWND hWnd;
    int width;
    int height;
}

Nice. Well, not really. But still... Moving on! Now to create the windows for outputs:

std::vector<WindowDataContainer*> windowsArray;
void CreateWindowsForOutputs()
{
    for( int i = 0; i < outputArray.size(); ++i )
    {

        IDXGIOutput* output = outputArray.at(i);
        DXGI_OUTPUT_DESC outputDesc;
        p_Output->GetDesc( &outputDesc );
        int x = outputDesc.DesktopCoordinates.left;
        int y = outputDesc.DesktopCoordinates.top;
        int width = outputDesc.DesktopCoordinates.right - x;
        int height = outputDesc.DesktopCoordinates.bottom - y;

        // Don't forget to clean this up. And all D3D COM objects.
        WindowDataContainer* window = new WindowDataContainer;

        window->hWnd = CreateWindow( windowClassName,
                                        windowName,
                                        WS_POPUP,
                                        x,
                                        y,
                                        width,
                                        height,
                                        NULL,
                                        0,
                                        instance,
                                        NULL );

        // show the window
        ShowWindow( window->hWnd, SW_SHOWDEFAULT );

        // set width and height
        window->width = width;
        window->height = height;

        // shove it in the std::vector
        windowsArray.push_back( window );

        //if first window, associate it with DXGI so it can jump in
        // when there is something of interest in the message queue
        // think fullscreen mode switches etc. MSDN for more info.
        if(i == 0)
            factory->MakeWindowAssociation( window->hWnd, 0 );

    }
}

Cute, now that's done. Since we only have one adapter and therefore only one device to accompany it, create it as usual. In my case, it's simply a global interface pointer which can be accessed all over the place. We are not going for code of the year here, so why the hell not, eh?

Creating the swap chains, views and the depth/stencil 2D texture

Now, our friendly swap chains... You might be used to actually creating them by invoking the "naked" function D3D10CreateDeviceAndSwapChain(...), but as you know, we've already made our device. We only want one. And multiple swap chains. Well, that's a pickle. Luckily, our DXGIFactory interface has swap chains on its production line which we can receive for free with complementary kegs of rum. Onto the swap chains then, create for every window one:

void CreateSwapChainsAndViews()
{
    for( int i = 0; i < windowsArray.size(); i++ )
    {
        WindowDataContainer* window = windowsArray.at(i);

        // get the dxgi device
        IDXGIDevice* DXGIDevice = NULL;
        device->QueryInterface( IID_IDXGIDevice, ( void** )&DXGIDevice ); // COM stuff, hopefully you are familiar

        // create a swap chain
        DXGI_SWAP_CHAIN_DESC swapChainDesc;

        // fill it in

        HRESULT hr = factory->CreateSwapChain( DXGIDevice, &swapChainDesc, &p_Window->swapChain );
        DXGIDevice->Release();
        DXGIDevice = NULL;

         // get the backbuffer
        ID3D10Texture2D* backBuffer = NULL;
        hr = window->swapChain->GetBuffer( 0, IID_ID3D10Texture2D, ( void** )&backBuffer );

        // get the backbuffer desc
        D3D10_TEXTURE2D_DESC backBufferDesc;
        backBuffer->GetDesc( &backBufferDesc );

        // create the render target view
        D3D10_RENDER_TARGET_VIEW_DESC RTVDesc;

        // fill it in

        device->CreateRenderTargetView( backBuffer, &RTVDesc, &window->renderTargetView );
        backBuffer->Release();
        backBuffer = NULL;

        // Create depth stencil texture
        ID3D10Texture2D* depthStencil = NULL;
        D3D10_TEXTURE2D_DESC descDepth;

        // fill it in


        device->CreateTexture2D( &descDepth, NULL, &depthStencil );

        // Create the depth stencil view
        D3D10_DEPTH_STENCIL_VIEW_DESC descDSV;

        // fill it in

        device->CreateDepthStencilView( depthStencil, &descDSV, &window->depthStencilView );

    }

}

We now have everything we need. All that you need to do is define a function which iterates over all windows and draws different stuff appropriately.

How and where should I Use OMSetRenderTargets(...) ?

In the just mentioned function which iterates over all windows and uses the appropriate render target (courtesy of our per-window data container):

void MultiRender( )
{
    // Clear them all
    for( int i = 0; i < windowsArray.size(); i++ )
    {
        WindowDataContainer* window = windowsArray.at(i);

        // There is the answer to your second question:
        device->OMSetRenderTargets( 1, &window->renderTargetView, window->depthStencilView );

        // Don't forget to adjust the viewport, in fullscreen it's not important...
        D3D10_VIEWPORT Viewport;
        Viewport.TopLeftX = 0;
        Viewport.TopLeftY = 0;
        Viewport.Width = window->width;
        Viewport.Height = window->height;
        Viewport.MinDepth = 0.0f;
        Viewport.MaxDepth = 1.0f;
        device->RSSetViewports( 1, &Viewport );

        // TO DO: AMAZING STUFF PER WINDOW
    }
}

Of course, don't forget to run through all the swap chains and swap buffers per window basis. The code here is just for the purposes of this answer, it requires a bit more work, error checking (failsafes) and contemplation to get it working just the way you like it - in other words - it should give you a simplified overview, not a production solution.

Good luck and happy coding! Sheesh, this is huge.

这篇关于显示每个监视器不同的图像directX 10的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆