0

I am compiling a simple code to capture screenshot using GetBackBufer() method and here is my complete code for reference:

// include the basic windows header files and the Direct3D header files
#include <windows.h>
#include <windowsx.h>
#include <d3d11.h>
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\d3dx11.h>
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\d3dx10.h>
#include <d3d9.h>
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\d3dx9tex.h>

// include the Direct3D Library file
#pragma comment (lib, "d3d11.lib")
#pragma comment (lib, "d3dx11.lib")
#pragma comment (lib, "d3dx10.lib")
#pragma comment (lib, "d3dx9.lib")

// global declarations
IDXGISwapChain *swapchain;             // the pointer to the swap chain interface
ID3D11Device *dev;                     // the pointer to our Direct3D device interface
ID3D11DeviceContext *devcon;           // the pointer to our Direct3D device context

// function prototypes
void InitD3D(HWND hWnd);    // sets up and initializes Direct3D
void CleanD3D(void);        // closes Direct3D and releases memory

// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    HWND hWnd;
    WNDCLASSEX wc;

    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszClassName = L"WindowClass";

    RegisterClassEx(&wc);

    RECT wr = { 0, 0, 800, 600 };
    AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);

    hWnd = CreateWindowEx(NULL,
        L"WindowClass",
        L"Our First Direct3D Program",
        WS_OVERLAPPEDWINDOW,
        300,
        300,
        wr.right - wr.left,
        wr.bottom - wr.top,
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(hWnd, nCmdShow);

    // set up and initialize Direct3D
    InitD3D(hWnd);

    // enter the main loop:

    MSG msg;

    while (TRUE)
    {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);

            if (msg.message == WM_QUIT)
                break;
        }
        else
        {
            LPDIRECT3DDEVICE9 d3dDevice = NULL;

            D3DPRESENT_PARAMETERS d3dpp;

            ZeroMemory(&d3dpp, sizeof(d3dpp));
            d3dpp.Windowed = TRUE;
            d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;



            IDirect3DSurface9 *offscreenSurface = 0;
            d3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &offscreenSurface);
            D3DXSaveSurfaceToFileA("E:\\filename.bmp", D3DXIFF_BMP, offscreenSurface, 0, 0);

            // Run game code here
            // ...
            // ...
        }
    }

    // clean up DirectX and COM
    CleanD3D();

    return msg.wParam;
}


// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    } break;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}


// this function initializes and prepares Direct3D for use
void InitD3D(HWND hWnd)
{
    // create a struct to hold information about the swap chain
    DXGI_SWAP_CHAIN_DESC scd;

    // clear out the struct for use
    ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));

    // fill the swap chain description struct
    scd.BufferCount = 1;                                    // one back buffer
    scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;     // use 32-bit color
    scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;      // how swap chain is to be used
    scd.OutputWindow = hWnd;                                // the window to be used
    scd.SampleDesc.Count = 4;                               // how many multisamples
    scd.Windowed = TRUE;                                    // windowed/full-screen mode

    // create a device, device context and swap chain using the information in the scd struct
    D3D11CreateDeviceAndSwapChain(NULL,
        D3D_DRIVER_TYPE_HARDWARE,
        NULL,
        NULL,
        NULL,
        NULL,
        D3D11_SDK_VERSION,
        &scd,
        &swapchain,
        &dev,
        NULL,
        &devcon);
}


// this is the function that cleans up Direct3D and COM
void CleanD3D(void)
{
    // close and release all existing COM objects
    swapchain->Release();
    dev->Release();
    devcon->Release();
}

I am getting this error for the D3DXSaveSurfaceToFile function:

1>Source.obj : error LNK2019: unresolved external symbol _D3DXSaveSurfaceToFileA@20 referenced in function _WinMain@16

1>c:\users\vrushali\documents\visual studio 2013\Projects\DirectXBackBufferTryTWO\Debug\DirectXBackBufferTryTWO.exe : fatal error LNK1120: 1 unresolved externals

I refered to a lot of SO threads regarding resolving this error and followed almost all the the procedures suggested here,MSDN documentation: Linker Tools Error LNK2019, here by changing the function to SaveSurfacetoFileW and using L"E:\\filename.bmp". I also added the path to all library files and also copy pasted those library files in the project directory.

However after reading through a lot of threads I am not able to resolve this error. What am I doing wrong here? What else should I do in order to get rid of the unresolved external error?

Community
  • 1
  • 1
newbie2015
  • 581
  • 5
  • 29
  • 1
    Did you change the settings to instruct the linker to link to the appropriate library or did you just tell it where more libraries are? – Captain Obvlious Sep 28 '15 at 20:21
  • Shouldn't these `#pragma comment (lib, "d3d11.lib")` rather `#import` statements? – πάντα ῥεῖ Sep 28 '15 at 20:23
  • I think its the A at the end. Try changing it to D3DXSaveSurfaceToFile. Often, your project choice of character size make the determination whether to use the function ending with A or W (for ASCII or WIDE). When you hard code A and your program is compiled as WIDE, you will have linker errors. – Les Sep 28 '15 at 20:26
  • Yes I tried with `D3DXSaveSurfaceToFile` as well. Still I got the same error. @Les – newbie2015 Sep 28 '15 at 20:37
  • @CaptainObvlious I specifically typed `d3dx9.lib` in _Properties->Linker->Input->Additional Dependencies_ and also added the appropriate paths in _Properties->VC++ Directories-> Include and Library Directories_ Any other setting that I must change? – newbie2015 Sep 28 '15 at 20:59
  • The fact that you are using ``C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\`` for your include statements implies to me that you have failed to add the legacy DirectX SDK to your include & lib paths, which means it cannot find any of the ``d3dx*.lib`` files at link time either. – Chuck Walbourn Sep 28 '15 at 21:30
  • If your application uses only Direct3D 11 (which is what it appears from the ``InitD3D`` code), you shouldn't need to use the legacy DirectX SDK or the deprecated D3DX library. See [DirectX Tool Kit](https://github.com/Microsoft/DirectXTK)'s ScreenGrab module. – Chuck Walbourn Sep 28 '15 at 21:33

0 Answers0