Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capture area of a monitor #119

Open
michiproep opened this issue Apr 2, 2023 · 4 comments
Open

Capture area of a monitor #119

michiproep opened this issue Apr 2, 2023 · 4 comments

Comments

@michiproep
Copy link

Is there a way to capture only an area of the desktop or monitor by a given Rectangle?

@robmikh
Copy link
Member

robmikh commented Apr 2, 2023

No, right now you need to capture the entire monitor and copy out the portion you're interested in using CopySubresourceRegion.

@michiproep
Copy link
Author

do you have a short code snippet for this?

@robmikh
Copy link
Member

robmikh commented Apr 2, 2023

I don't have a self-contained snippet to share with you, but the idea is straight forward. Let's say that you have two textures, texture A comes from the capture API and texture B is the texture that will receive the pixels you're interested in. You would call CopySubresourceRegion on the ID3D11DeviceContext and supply the area of interest from texture A and specify that it will be copied into texture B.

robmikh/GifSnip does this very thing to copy a portion of the screen to an output texture used to encode a gif.

@MartinClementson
Copy link

Here are some snippets of the relevant code I used. It's just the relevant lines of my code, It won't run.

Member variable:
D3D11_BOX m_roiWindow; //Region of interest rect
ID3D11Texture2D* m_stagingTexture= NULL;
//Set Function
SetROIWindow(float x, float y, float width, float height) {
    m_roiWindow.left   = max(0.0f,x);
    m_roiWindow.top    = max(0.0f,y);
    m_roiWindow.right  = m_roiWindow.left + width;
    m_roiWindow.bottom = m_roiWindow.top + height;
    }
    
//Inside OnFrameArrived:
 auto frame = sender.TryGetNextFrame();
 auto swapChainResizedToFrame = TryResizeSwapChain(frame);
 auto surfaceTexture = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
 m_d3dContext->CopySubresourceRegion(m_stagingTexture, 0, 0, 0, 0, surfaceTexture.get(), 0, &m_roiWindow);
 D3D11_MAPPED_SUBRESOURCE mappedSubResource;
 auto hr = m_d3dContext->Map(m_stagingTexture, 0, D3D11_MAP_READ, 0, &mappedSubResource);


<Use mappedSubResource.pData for something>

//Unmap
m_d3dContext->Unmap(m_stagingTexture, 0);
frame.Close();

An issue I had is that I had to make sure the width and height of the region is 32bit aligned, but that is probably because I use the data in an openGL texture. You might not have that issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants