Results 1 to 7 of 7

Thread: How do I get DC on different graphics card?

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    How do I get DC on different graphics card?

    I have 2 graphics cards in my laptop; the default Intel one, and the NVidea 3D gaming one. I want to screencapture a game I'm playing, so I want to make a screencap program in VB6, using Windows API. Problem is, the game itself uses the 3D graphics hardware, and VB6 uses the default graphics hardware. While both physically display on the same monitor, the game's graphics are rendered on different hardware internally. So when I have the game's window sitting next to my VB6 program's window, and I use GetDC and BitBlt to try to capture the game's window, the resulting capture is black. The problem is that GetDC is getting the DC for the game's window on the same graphics hardware that my VB6 program is running on, but the game's graphics are actually running on a different device (different graphics hardware in the laptop). Is there some kind of cross-device technique I can use to allow my VB6 program to screencap the game I'm playing? Is there like some kind of GetDC_Ex that I can use to specify that the desired DC I'm trying to capture from is running on the second graphics card (not primary graphics card) in my laptop?

  2. #2
    PowerPoster Zvoni's Avatar
    Join Date
    Sep 2012
    Location
    To the moon and then left
    Posts
    4,440

    Re: How do I get DC on different graphics card?

    Any function that returns a display device context (DC) normally returns a DC for the primary monitor. To obtain the DC for another monitor, use the EnumDisplayMonitors function.
    --> https://docs.microsoft.com/en-us/win...device-context
    Last edited by Zvoni; Tomorrow at 31:69 PM.
    ----------------------------------------------------------------------------------------

    One System to rule them all, One Code to find them,
    One IDE to bring them all, and to the Framework bind them,
    in the Land of Redmond, where the Windows lie
    ---------------------------------------------------------------------------------
    People call me crazy because i'm jumping out of perfectly fine airplanes.
    ---------------------------------------------------------------------------------
    Code is like a joke: If you have to explain it, it's bad

  3. #3

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    Re: How do I get DC on different graphics card?

    That's not the problem. I have only one monitor, but 2 GPUs in my laptop. The default GPU is the "integrated graphics" one. The second one is used mainly for games, and is an NVidia GPU. When the game I'm running uses the NVidia GPU, but the program I'm running uses the "integrated graphics" GPU, I can't get use GetDC or GetWindowDC to get the true hDC associated with the game window, only a fake hDC that is a black rectangle (as seen when I BitBlt from that hDC). I need a way to cause my program to get the true hDC for the game's Window, so that I can BitBlt the actual game's graphics to my program for making a screencap. I don't need to enum my monitors, because I only have one monitor.

  4. #4
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: How do I get DC on different graphics card?

    I assume you're not using Windows 10?

  5. #5

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    Re: How do I get DC on different graphics card?

    Quote Originally Posted by passel View Post
    I assume you're not using Windows 10?
    I am using Windows 10. My PC has 2 GPUs. One is "integrated graphics" which is default, and the other is NVidia which is for games. My Visual Basic screencap program runs using the default GPU for displaying its window, and the game I want to screencap is running using the NVidia GPU. It seems that functions liked GetDC and GetWindowDC only work for getting an hDC for a window that us using the same GPU as the program that is calling the GetDC or GetWindowDC function. If I try to use one of these functions to get an hDC and then BitBlt the image from the remote window to my program, I just get a black image, when the window I'm trying to screencap is on one GPU and the screencap program is on a different GPU. I need a way to capture a game Window running on a different GPU, or find a way to somehow run my program using the same GPU as the game I'm trying to screencap.

  6. #6
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: How do I get DC on different graphics card?

    I guess I'm just not sure if what you're describing is what the problem is.
    For many years now, since at least win95, you couldn't capture a game image by using the desktop hDC if the game was in a direct screen access mode, because the game was not using the windows desktop for displaying its window. It was in a direct screen mode and that bypassed windows. If you tried to capture the screen when a game was in a direct screen mode, you would just get an empty black rectangle. There was usually and option that you could select to run the game in windowed mode, and then you could capture the window then.

    If you wanted to capture the screen while it was in direct screen mode, then you would have to use a graphics library, like directx and capture the frame buffer using that API.

    I thought with Windows 10, because of the way the desktop is a composited managed collection of buffers, that you could capture the games windows now, without having to use the particular 3D api to capture the frame buffer, but it looks like I may be wrong.

  7. #7

    Thread Starter
    Frenzied Member
    Join Date
    Oct 2008
    Posts
    1,181

    Re: How do I get DC on different graphics card?

    Quote Originally Posted by passel View Post
    I guess I'm just not sure if what you're describing is what the problem is.
    For many years now, since at least win95, you couldn't capture a game image by using the desktop hDC if the game was in a direct screen access mode, because the game was not using the windows desktop for displaying its window. It was in a direct screen mode and that bypassed windows. If you tried to capture the screen when a game was in a direct screen mode, you would just get an empty black rectangle. There was usually and option that you could select to run the game in windowed mode, and then you could capture the window then.

    If you wanted to capture the screen while it was in direct screen mode, then you would have to use a graphics library, like directx and capture the frame buffer using that API.

    I thought with Windows 10, because of the way the desktop is a composited managed collection of buffers, that you could capture the games windows now, without having to use the particular 3D api to capture the frame buffer, but it looks like I may be wrong.
    I'm using the game in Windowed mode. But it still shows just a black rectangle. Yes, the game window does have a valid hDC, but the image that you get from the BitBlt operation is a black rectangle the size of the game's window. None of it is direct to screen type mode (aka fullscreen mode). But it still just shows a black rectangle in BitBlt operation. Now there is one trick, but it slows down the operation. That trick is to use GetDC(0) to get the hDC for the entire screen, and then use the use the coordinates of the upper-left corner of the window to be captured in the BitBlt operation itself. However this is very slow compared to directly BitBlting the hDC for the desired window (and setting the upper-left cooridinates for BitBlt operation to 0,0). This is why I'm trying to figure out how get the hDC of the game in the GPU that is running the game. There are 2 sets of hDCs on a computer that has 2 GPUs. One set is for the defualt GPU. The other set is for the game GPU. If you use hDC for the wrong GPU you will just capture a blank rectangle in the shape of the window. However, if I can find some way to capture the hDC for the desired window on the CORRECT GPU that would mean I SHOULD be able to capture the game screen. Alternatively, if I can somehow force my own program to run using the same GPU as the game, then my program should be able to just use the hDC for the game's window directly (without having to use any special cross-gpu-GetDC type of trick, assuming such a trick even exists). Any help doing either of these would be GREATLY appreciated.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width