Full working example to capture screen using DirectX

Started by
10 comments, last by Brain 8 years, 11 months ago

Capturing screen using GDI is very slow (it barely captures 10 fps).

I have read that DirectX screen capture provides the best speed. I want to test some code to see if it is really fast before start to learn DirectX (I don't want to waste my time learning DirectX and then find out that it is not that fast laugh.png).

I have been searching for like 2 hours for a working example of a screen capture code. All I have found is incomplete code (the kind that assumes that you know DirectX and expects you to complete it yourself). For example: http://stackoverflow.com/questions/5069104/fastest-method-of-screen-capturing

Can anyone post a complete working example that will compile without a problem.

I am using Visual C++ 2012 Express on Windows 7 Ultimate x64 and I have installed DirectX 10.

Advertisement


I have read that DirectX screen capture provides the best speed.

from inside a d3d program, not from a separate stand alone screen capture app.

if you're writing a d3d app, you do it like this from inside your code:

void screendump()
{
char s[100],s2[100];
int i;
IDirect3DSurface9 *p;
HRESULT h;
h=Zd3d_device_ptr->CreateOffscreenPlainSurface((UINT)screen_width,(UINT)screen_height,D3DFMT_A8R8G8B8,D3DPOOL_SCRATCH,&p,NULL);
if (h != D3D_OK) 
    {
    msg("Error creating offscreen plain surface!");
    return;
    }
h=Zd3d_device_ptr->GetFrontBufferData(0,p);
if (h != D3D_OK) 
    {
    msg("Error getting front buffer data!");
    switch(h)
        {
        case D3DERR_DRIVERINTERNALERROR: msg("Driver internal error"); break;
        case D3DERR_DEVICELOST:          msg("Device lost"); break;
        case D3DERR_INVALIDCALL:         msg("Invalid call"); break;
        default:   msg("Undefined error"); break;
        }
    p->Release(); 
    return;
    }
//getstring("Screendump filename (1-8 letters)...",s);
//strcat_s(s,100,".bmp");
i=0;
do
    {
    i++;
    strcpy_s(s,100,"scrndmp");
    i2s(i,s2);
    strcat_s(s,100,s2);
    strcat_s(s,100,".bmp");
    }
    while (filefound(s));
D3DXSaveSurfaceToFile(s,D3DXIFF_BMP,p,NULL,NULL);
p->Release();
strcpy_s(s2,100,"Screendump ");
strcat_s(s2,100,s);
strcat_s(s2,100," saved.");
msg(s2);
}
 

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

continued from previous post, code blocks not working as usual!

if you're not writing your own d3d app, i don't think you can use directx to get a screendump. the screendump comes from d3d's internal front buffer data structure - which only exists in - and is only accessible from inside of - a d3d app.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

I doubt that the OP wants to save a screenshot, but wants to "record" images like for a video or animation (based on the remark of 10fps).

If so, I don't know how to do that from inside your application.
You might consider using graphics driver tools that do if for you, directly through the driver (like somethingplay from nvidia for example).

But.. If you want to record gameplay to be able to play it later (animations), I suggest storing/ saving just data, and render it realtime when you want to repeat/ play it).

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me


I have read that DirectX screen capture provides the best speed.

from inside a d3d program, not from a separate stand alone screen capture app.

if you're writing a d3d app, you do it like this from inside your code:


void screendump()
{
char s[100],s2[100];
int i;
IDirect3DSurface9 *p;
HRESULT h;
h=Zd3d_device_ptr->CreateOffscreenPlainSurface((UINT)screen_width,(UINT)screen_height,D3DFMT_A8R8G8B8,D3DPOOL_SCRATCH,&p,NULL);
if (h != D3D_OK) 
    {
    msg("Error creating offscreen plain surface!");
    return;
    }
h=Zd3d_device_ptr->GetFrontBufferData(0,p);
if (h != D3D_OK) 
    {
    msg("Error getting front buffer data!");
    switch(h)
        {
        case D3DERR_DRIVERINTERNALERROR: msg("Driver internal error"); break;
        case D3DERR_DEVICELOST:          msg("Device lost"); break;
        case D3DERR_INVALIDCALL:         msg("Invalid call"); break;
        default:   msg("Undefined error"); break;
        }
    p->Release(); 
    return;
    }
//getstring("Screendump filename (1-8 letters)...",s);
//strcat_s(s,100,".bmp");
i=0;
do
    {
    i++;
    strcpy_s(s,100,"scrndmp");
    i2s(i,s2);
    strcat_s(s,100,s2);
    strcat_s(s,100,".bmp");
    }
    while (filefound(s));
D3DXSaveSurfaceToFile(s,D3DXIFF_BMP,p,NULL,NULL);
p->Release();
strcpy_s(s2,100,"Screendump ");
strcat_s(s2,100,s);
strcat_s(s2,100," saved.");
msg(s2);
}
 

Just to make sure I understood you correctly. The following will not execute in 1 second?


char str[16];
for (int i = 1; i <= 30; i++)
{
    sprintf(str, "D:\\%d.bmp", i);
    CaptureScreenUsingDirectX(str);
}

If this will not work, then I guess I will not learn DirectX (I was only going to learn it to do a screenshot function). Do you know of a (not too complicated) way to capture 30 screenshots in 1 second?


learn it to do a screenshot function

Do you understand that the code posted will save images only drawn by the DirectX app to its own buffer? That is, it does not "capture" the desktop, or anything drawn by anything other than the DirectX app itself.

Can you be specific about what you're trying to capture?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.


learn it to do a screenshot function

Do you understand that the code posted will save images only drawn by the DirectX app to its own buffer? That is, it does not "capture" the desktop, or anything drawn by anything other than the DirectX app itself.

Can you be specific about what you're trying to capture?

I don't really know anything about DirectX, I just read that DirectX can be used to do a screenshot (and it is fast at doing it).

I am trying to capture the entire desktop (i.e. Print Screen).

Dxgi provides a way to capture the desktop buffer. You may want to look into the dxgi screen capture api on MSDN.

Hope this doesn't sound stupid, but what's your exact goal?

If you just want a screen capture of your desktop, press (ALT+)PRT SCRN and paste it in any image editor.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Hope this doesn't sound stupid, but what's your exact goal?

If you just want a screen capture of your desktop, press (ALT+)PRT SCRN and paste it in any image editor.

I am trying to write a simple screen recorder. And so I want to be able to capture a lot of screenshots in 1 second (24 fps or 30 fps).

This topic is closed to new replies.

Advertisement