Search code examples
c++directxdirect3dmingw-w64dxgi

mingw-w64 gcc does not recognize DXGI_FORMAT from dxgiformat.h


i just wanted to make sure i don't lose my mind here. I wanted to build a simple Direct3D 11 application and had a basic window running. I now wanted to add some actual rendering but unfortunately my compiler won't recognize the DXGI_FORMAT enum type from dxgiformat.h. I tried many thinks of one was to literally copy the content of the header manually but no luck. Also i checked the output of the preprocessor and confirmed that gcc actually draws its resources from the right places and that the content of the header was in there correctly. Furthermore this is the only dxgiformat.h header on this machine. I'm aware of the unused variable since this is what i was going to use before this problem occured. I now just wanted to be save this is not a user problem before trying to report any bugs. As i stated i'm using the MinGW-w64 toolchain from the installer. These are my Error messages:

$ make
[BUILD] D3D11App.o
In file included from D3D11App.cpp:4:
D3D11App.hpp:11:2: error: 'DXGI_FORMAT_R32G32B32_FLOAT' does not name a type
  DXGI_FORMAT_R32G32B32_FLOAT position;
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~
D3D11App.hpp:12:2: error: 'DXGI_FORMAT_R8G8B8_UNORM' does not name a type; did you mean 'DXGI_FORMAT_R8G8_UNORM'?
  DXGI_FORMAT_R8G8B8_UNORM color;
  ^~~~~~~~~~~~~~~~~~~~~~~~
  DXGI_FORMAT_R8G8_UNORM
D3D11App.cpp: In constructor 'D3D11App::D3D11App(HWND)':
D3D11App.cpp:103:20: warning: unused variable 'bufferDesc' [-Wunused-variable]
  D3D11_BUFFER_DESC bufferDesc = {
                    ^~~~~~~~~~
make: *** [makefile:15: D3D11App.o] Fehler 1

and my code:

main.cpp

#include <iostream>
#include <d3d11.h>
#include <windows.h>
#include <windowsx.h>
#include "D3D11App.hpp"


using namespace std;
HWND init(HINSTANCE hInstance, const int x, const int y, const int w, const int h);
LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
D3D11App *d3d11;


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR cmdLine, int cmdShow) {
    cout << "Reslution: " << GetSystemMetrics(SM_CXSCREEN) << "x" << GetSystemMetrics(SM_CYSCREEN) << endl;
    HWND window = init(hInstance, 0, 0, 800, 600);
    if (window == NULL) {
        cout << "Error while initializing: " << GetLastError() << endl;
        return GetLastError();
    }
    d3d11 = new D3D11App(window);
    ShowWindow(window, cmdShow);
    UpdateWindow(window);
    MSG msg;
    while (msg.message != WM_QUIT) {
        if ( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        } else {
            d3d11->render();
        }
    }

    return 0;
}


HWND init(HINSTANCE hInstance, const int x, const int y, const int w, const int h) {
    WNDCLASSEX windowClass = {
        sizeof(WNDCLASSEX),
        CS_HREDRAW | CS_VREDRAW,
        windowProc,
        0,
        0,
        hInstance,
        NULL,
        NULL,
        (HBRUSH)COLOR_WINDOW,
        "Window",
        "windowClass",
        NULL
    };
    if(RegisterClassEx(&windowClass) == 0) {
        cout << "Error while registering class: " << GetLastError() << endl;
        return NULL;
    }

    return CreateWindowEx (
        WS_EX_TOPMOST,
        "windowClass",
        "D3D11",
        WS_POPUP,
        x, y,
        w, h,
        NULL,
        NULL,
        hInstance,
        NULL
    );
}


LRESULT CALLBACK windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch(msg) {
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        case WM_KEYDOWN:
            switch(wParam) {
                case VK_ESCAPE:
                    PostQuitMessage(0);
                    return 0;
            }
        case WM_MOUSEMOVE:
            cout << "x :" << GET_X_LPARAM(lParam) << ", y: " << GET_Y_LPARAM(lParam) << endl;
        return 0;
    }

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

D3DApp11.hpp

#ifndef D3D11APP_HPP
#define D3D11APP_HPP


#include <d3d11.h>
#include <dxgiformat.h>
#include <vector>


struct customVertex {
    DXGI_FORMAT_R32G32B32_FLOAT position;
    DXGI_FORMAT_R8G8B8_UNORM color;
};


class D3D11App {
    ID3D11Device *device;
    ID3D11DeviceContext *devcon;
    IDXGISwapChain *swapChain;
    ID3D11RenderTargetView *backbuffer;
    ID3D11Buffer *vertexBuffer;
public:
    D3D11App(HWND hWnd);
    ~D3D11App();
    void render();
};



#endif /* D3D11APP_HPP */

D3D11App.cpp

#include <iostream>
#include <dxgiformat.h>
#include <memory>
#include "D3D11App.hpp"


using namespace std;


D3D11App::D3D11App(HWND hWnd) {
    HRESULT status;
    WINDOWINFO windowInfo;
    IDXGIAdapter * pAdapter;
    IDXGIFactory * pFactory;
    status = CreateDXGIFactory(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&pFactory));
    for(int i = 0; pFactory->EnumAdapters(i, &pAdapter) != DXGI_ERROR_NOT_FOUND; i++) {
        DXGI_ADAPTER_DESC adapterDesc;
        pAdapter->GetDesc(&adapterDesc);
        cout << "Video Adapter " << i << ":" << endl
             << "Description: " << adapterDesc.Description << endl
             << "VendorId: 0x" << hex << adapterDesc.VendorId << endl
             << "DeviceID: 0x" << adapterDesc.DeviceId << endl
             << "SubSysId: 0x" << adapterDesc.SubSysId << endl
             << "Revision: " << adapterDesc.Revision << endl
             << dec << endl;

    }
    if(status != S_OK) {
        cout << "Error while creating factory Error(0x" << hex << status << dec << ")" << endl;
    }

    if( ! GetWindowInfo(hWnd, &windowInfo) ) {
        cout << "Error while retreiving window informattion" << endl;
    }
    cout << "client width: " << windowInfo.rcClient.right << " client height: " << windowInfo.rcClient.bottom << endl;
    DXGI_SWAP_CHAIN_DESC scd = {
        /* BufferDesc */
        {
            static_cast<UINT>(windowInfo.rcClient.right),
            static_cast<UINT>(windowInfo.rcClient.bottom),
            60,
            DXGI_MODE_SCALING_UNSPECIFIED,
            DXGI_FORMAT_R8G8B8A8_UNORM,
            DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE
        },
        /* SampleDesc */
        {
            8,
            0
        },
        DXGI_USAGE_RENDER_TARGET_OUTPUT,
        1,
        hWnd,
        true,
        DXGI_SWAP_EFFECT_DISCARD
    };

    status = D3D11CreateDeviceAndSwapChain(
        NULL,
        D3D_DRIVER_TYPE_HARDWARE,
        NULL,
        D3D11_CREATE_DEVICE_SINGLETHREADED,
        NULL,
        0,
        D3D11_SDK_VERSION,
        &scd,
        &(this->swapChain),
        &(this->device),
        NULL,
        &(this->devcon)
    );
    if(status != S_OK) {
        cout << "Error while creating device and swap chain Error(0x" << hex << status << dec << ")" << endl;
        return;
    }

    ID3D11Texture2D *pBackBuffer;
    status = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
    if (status != S_OK) {
        cout << "Error while getting backbuffer adress Error(0x" << hex << status << dec << ")" << endl;
        return;
    }

    status = device->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
    if (status != S_OK) {
        cout << "Error while creating render target view Error(0x" << hex << status << dec << ")" << endl;
        return;
    }
    pBackBuffer->Release();

    devcon->OMSetRenderTargets(1, &backbuffer, NULL);

    D3D11_VIEWPORT viewPort;
    ZeroMemory(&viewPort, sizeof(D3D11_VIEWPORT));

    viewPort.TopLeftX = (FLOAT)0.0;
    viewPort.TopLeftY = (FLOAT)0.0;
    viewPort.Width = static_cast<FLOAT>(windowInfo.rcClient.right);
    viewPort.Height = static_cast<FLOAT>(windowInfo.rcClient.bottom);

    devcon->RSSetViewports(1, &viewPort);

    D3D11_BUFFER_DESC bufferDesc = {
        3 * sizeof(customVertex),
        D3D11_USAGE_DYNAMIC,
        D3D11_BIND_VERTEX_BUFFER,
        D3D11_CPU_ACCESS_WRITE,
        0,
        sizeof(customVertex)
    };
}


D3D11App::~D3D11App() {
    this->swapChain->Release();
    this->backbuffer->Release();
    this->device->Release();
    this->devcon->Release();
}


void D3D11App::render() {
    devcon->ClearRenderTargetView(backbuffer, (const FLOAT[]){0.0,0.2,0.5,1.0});
    if(swapChain->Present(0, 0) != S_OK) {
        cout << "Error while presenting" << endl;
    }
}

Solution

  • DXGI_FORMAT_R32G32B32_FLOAT is an enum that describes a particular memory layout, but is not itself a C++ structure you can declare in your vertex type.

    You can use float position[3], but many DirectX C++ programs use the various DirectXMath types such as DirectX::XMFLOAT3 position;. There's a fairly complete list of equivalents here.