Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8012821
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T19:27:00+00:00 2026-06-04T19:27:00+00:00

I am fairly new to DirectX 10 programming, and I have been trying to

  • 0

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;

}

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T19:27:02+00:00Added an answer on June 4, 2026 at 7:27 pm

    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:

    The result

    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.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm fairly new to C++ standard library and have been using standard library lists
Fairly new to socket programming, but I've been assigned with a whopper of project.
I'm fairly new to directx so this may sound really basic. I have started
Fairly new to Jquery here.... but one thing I have been told and being
Fairly new to asp.net Mvc and jquery. Have the following code working fine, but
Fairly new to programming. I just can't wrap my head around how to get
Fairly new to Objective C and trying to work within Storyboards given it's the
Being fairly new to programming, I am having trouble understanding exactly what Homebrew does...
I fairly new to JQuery and perhaps trying to achieve something that might be
I am new to fairly new to AS3 and I have found myself needing

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.