Thread: Take screenshot with directX?

  1. #16
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You are specifying the HAL yet you then say you want software T&L. This is a big mistake and will seriously impact your performance.

    Incidentally in regards to GetFrontBufferData()
    This method is the only way to capture an antialiased screen shot.
    There are other ways to get to the front buffer pixel data if you don't require the data to appear exactly as you see it on screen.

  2. #17
    Registered User
    Join Date
    Sep 2007
    Posts
    18
    The code look like this now:
    Code:
    HRESULT	InitD3D(HWND hwnd)
    {
        g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
    
        if( g_pD3D == NULL ) {
            MessageBox(NULL, "failure of Direct3DCreate9", "Error", MB_OK | MB_ICONEXCLAMATION);// TO DO: Respond to failure of Direct3DCreate8
            return E_FAIL;
        }
        
        int nMode = 0;
        D3DDISPLAYMODE d3ddm;
        bool bDesiredAdaptorModeFound = false;
        int nMaxAdaptorModes = g_pD3D->GetAdapterModeCount( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8 );
    
        for( nMode = 0; nMode < nMaxAdaptorModes; ++nMode ) {
            if( FAILED( g_pD3D->EnumAdapterModes( D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, nMode, &d3ddm ) ) ) {
                MessageBox(NULL, "Respond to failure of EnumAdapterModes", "Error", MB_OK | MB_ICONEXCLAMATION);
                return E_FAIL;
            }
            if( d3ddm.Width != 640 || d3ddm.Height != 480 ) { continue; }// Does this adaptor mode support a mode of 640 x 480?
            if( d3ddm.Format != D3DFMT_X8R8G8B8 ) { continue; }// Does this adaptor mode support a 32-bit RGB pixel format?
            if( d3ddm.RefreshRate != 75 ) { continue; }// Does this adaptor mode support a refresh rate of 75 Hz?
            bDesiredAdaptorModeFound = true; // We found a match...
            break;
        }
    
        if( bDesiredAdaptorModeFound == false ) {
            MessageBox(NULL, "lack of support for desired adaptor mode", "Error", MB_OK | MB_ICONEXCLAMATION);
            return E_FAIL;
        }
        
        if( FAILED( g_pD3D->CheckDeviceType( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, FALSE ) ) ) {
            MessageBox(NULL, "lack of support for a 32-bit back buffer", "Error", MB_OK | MB_ICONEXCLAMATION);
            return E_FAIL;
        }
    
        if( FAILED( g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8,  D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) ) {
            MessageBox(NULL, "lack of support for a 16-bit z-buffer", "Error", MB_OK | MB_ICONEXCLAMATION);
            return E_FAIL;
        }
    
        D3DCAPS9 d3dCaps;
        if( FAILED( g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps ) ) ) {
            MessageBox(NULL, "Respond to failure of GetDeviceCaps", "Error", MB_OK | MB_ICONEXCLAMATION);
            return E_FAIL;
        }
    
        DWORD dwBehaviorFlags = 0;
        if( d3dCaps.VertexProcessingCaps != 0 ) {dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; }
        else { dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; }
    
        D3DPRESENT_PARAMETERS d3dpp;
        memset(&d3dpp, 0, sizeof(d3dpp));
    
        d3dpp.Windowed                     = TRUE;
        d3dpp.EnableAutoDepthStencil       = TRUE;
        d3dpp.AutoDepthStencilFormat       = D3DFMT_D32;
        d3dpp.SwapEffect                   = D3DSWAPEFFECT_COPY;
        d3dpp.BackBufferWidth              = 1024;
        d3dpp.BackBufferHeight             = 768;
        d3dpp.BackBufferFormat             = D3DFMT_X8R8G8B8;
    	d3dpp.BackBufferCount              = 1;
        d3dpp.Flags                        = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
    	d3dpp.PresentationInterval         = D3DPRESENT_INTERVAL_DEFAULT;
    	d3dpp.FullScreen_RefreshRateInHz   = D3DPRESENT_RATE_DEFAULT;
        
        if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, dwBehaviorFlags, &d3dpp, &g_pd3dDevice ) ) ) {
            MessageBox(NULL, "Respond to failure of CreateDevice", "Error", MB_OK | MB_ICONEXCLAMATION);
            return E_FAIL;
        }
        return S_OK;
    }
    
    void Cleanup()
    {
        if( g_pd3dDevice != NULL ) g_pd3dDevice->Release();
        if( g_pD3D != NULL ) g_pD3D->Release();
        if( g_buffer!= NULL ) g_buffer->Release();
    }
    
    bool SaveScreenShot( char *fileName, _D3DXIMAGE_FILEFORMAT ImgFormat)
    {
        if( g_buffer!= NULL ) g_buffer->Release();
    	HRESULT hr;	
    		
    	if( FAILED( hr = g_pd3dDevice->CreateOffscreenPlainSurface(1024,768,D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &g_buffer, NULL ) ) ) {
    		MessageBox(NULL, "asd", "Error", MB_OK | MB_ICONEXCLAMATION);
            return false;
        }	
    	
    	if( FAILED( hr = g_pd3dDevice->GetFrontBufferData( 0, g_buffer ) ) ) {		
    		MessageBox(NULL, "asd2", "Error", MB_OK | MB_ICONEXCLAMATION);
            return false;		
    	}
    	
    	D3DXSaveSurfaceToFile( fileName, ImgFormat, g_buffer, NULL, NULL );
        return true;
    }

    The starting problem is fixed now.

    But I still have the problem that the screens gets messed up if something is moving on the screen, for example a game (coping is to slow).
    Can you tell me some other way to do that I want? Or maybe how to speedup getfrontbufferdata?

    I read something about getbackbuffer and swapchain/effect? But I didn’t find anyone that explains how to use them correctly, I tried some ways but I dinīt get it to work, only gets black screens.

  3. #18
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Aside from using a mix of tabs and spaces for indentation, I don't see anything immediately to improve - but I will be the first to say that I don't know much about D3D either. Oh, and try to cut down those really long lines into two or more lines - that stops the posts themselves being "out of whack" too.

    Certainly, I can't really see how you would improve the saving of the frame-buffer- GetFrontBufferData is the way you do that, and once it's been saved, the time it takes to store the file is irrelevant.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #19
    Registered User
    Join Date
    Sep 2007
    Posts
    18
    Thanks for the tip =P

    So, I can&#180;t take a whole “one frame” of a running game using dx?

    The only way to do that is to “lock” the game, and then screen it?
    And that is not possible on a game that I don’t control?
    But even if it&#180;s possible it&#180;s not a nice thing to do for the player that is playing.

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Dampy View Post
    Thanks for the tip =P

    So, I canīt take a whole “one frame” of a running game using dx?

    The only way to do that is to “lock” the game, and then screen it?
    And that is not possible on a game that I don’t control?
    But even if itīs possible itīs not a nice thing to do for the player that is playing.
    Which brings the question of what you are actually trying to achieve.

    One idea is that if you raise the priority of your task, it will steal enough CPU time to make your task finish first without much notice to the other task.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    Registered User
    Join Date
    Sep 2007
    Posts
    18
    It&#180;s very straight forward, I am trying to take a screenshot of a running game using DX :P

    Yes, I have already achieved that, but the problem is that the functions are to slow so the screens get all messed up.
    My new goal is the same but I want a whole frame, a complete frame of the running game, like using print screen.

    A picture of a game running (halflife), as you see the copping is to slow.
    H-L PIC, DX PRINT

    Is that possible whit DX?
    If not, is there any other method than GDI (bitblt) or OpenGL to take the a screenshot?
    I tried to raise the priority but it didn’t work

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. DirectX screenshot via C (app crashes)
    By Delusionz in forum C Programming
    Replies: 6
    Last Post: 01-11-2009, 09:55 AM
  2. Isometric Tile Engine using DirectX
    By Wraithan in forum Game Programming
    Replies: 3
    Last Post: 07-17-2006, 12:16 PM
  3. DirectSound header issues
    By dxfoo in forum C++ Programming
    Replies: 0
    Last Post: 03-19-2006, 07:16 PM
  4. DirectX - Starting Guide?
    By Zeusbwr in forum Game Programming
    Replies: 13
    Last Post: 11-25-2004, 12:49 AM
  5. Directx SDK Documentation
    By Zoalord in forum Game Programming
    Replies: 4
    Last Post: 05-08-2003, 06:07 AM