Problem mit Window Klasse (DirectX/Windows)



  • Mein Lieblingsprogramm (*hust hust*) macht immernoch Problem, diesmal 2 🙄 :

    1.) Die WndProc([...]) lässt sich nicht, wie im Vorbild-Buch (3D Game Programming with DirectX 11)
    in die Klasse intigrieren:

    Vorbild:

    namespace
    {
    	// This is just used to forward Windows messages from a global window
    	// procedure to our member function window procedure because we cannot
    	// assign a member function to WNDCLASS::lpfnWndProc.
    	D3DApp* gd3dApp = 0;
    }
    
    LRESULT CALLBACK
    MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	// Forward hwnd on because we can get messages (e.g., WM_CREATE)
    	// before CreateWindow returns, and thus before mhMainWnd is valid.
    	return gd3dApp->MsgProc(hwnd, msg, wParam, lParam);
    }
    

    Meins:

    namespace
    {
    	BASIC_WINDOW* m_window = 0;
    }
    
    LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    	return m_window->m_WndProc(hWnd, msg, wParam, lParam);
    }
    

    Unterschiede:
    - Vorbild geht
    - Meind nicht 😞

    (ps: Wenn ihr mehr Code braucht einfach fragen! Aber ich denke ich hab mal wieder( 🙄 ) irgendeinen bescheuerten Fehler gemacht und man kann das ganz einfach erklären...)

    2.) Der D3DContext lässt sich nicht erstellen....
    GetLastError() sagt mit 126. Ich habe schon stundenlang gegoogelt aber keine Lösung gefunden....

    Hier der Code:

    Klasse:

    //----------------------------------------------------------------------------------------------------------//
    // WINDOW.H
    //----------------------------------------------------------------------------------------------------------//
    
    #ifndef WINDOW_H
    #define WINDOW_H
    
    //----------------------------------------------------------------------------------------------------------//
    // Includes
    
    #include "core.h"
    
    //----------------------------------------------------------------------------------------------------------//
    // Klasse
    
    class BASIC_WINDOW
    {
    public:
    	BASIC_WINDOW(HINSTANCE hInst);             // Konstruktor
    	virtual ~BASIC_WINDOW();    // virtueller Destruktor
    
    	HINSTANCE gethInst()const;
    	HWND gethWnd()const;
    
    	virtual bool Init();
    
    	bool CreateDirectXWindow();
    	bool DestroyWindow();
    
    	int Run();
    
    	virtual void Draw(){};      // = 0 für das Erzwingen der Überschreibung
    	virtual void Update(){};    // s.o.
    
    	virtual LRESULT m_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    
    	virtual void Resize();
    
    private:
    
    	HINSTANCE m_hInst;
    	HWND m_hWnd;
    
    	LPCWSTR m_caption; // Überschrift des Fensters
    
    	int m_windowWidth;   // Göße des FENSTERS
    	int m_windowHeight;
    
    	int m_clientWidth;   // Größe der für uns wichtigen client area
    	int m_clientHeight;
    
    	bool m_fullscreen; // Vollbildmodus?
    	bool m_minimized; // minimiert?
    	bool m_maximized; // maximiert?
    	bool m_resizing;  // wird das Fenster im Moment vergrößert bzw. verkleinert?
    
    	bool m_paused;
    
    	ID3D11Device* m_d3dDevice;
    	ID3D11DeviceContext* m_d3dDeviceContext;
    	IDXGISwapChain* m_swapChain;
    	ID3D11RenderTargetView* m_renderTargetView;
    	ID3D11DepthStencilView* m_depthStencilView;
    	ID3D11Texture2D* m_depthStencilBuffer;
    	D3D11_VIEWPORT m_viewport;
    
    	bool m_enable4xMSAA;
    	UINT m_4xMSAAQuality;
    
    };
    
    #endif // WINDOW_H
    

    Und die Funktion mit dem Problem 😡 :

    bool BASIC_WINDOW::CreateDirectXWindow()
    {
    	WNDCLASSEX wc;
    
    	ZeroMemory(&wc, sizeof(WNDCLASSEX));
    
    	wc.cbSize = sizeof(WNDCLASSEX);
    	wc.style         = CS_HREDRAW | CS_VREDRAW;
    	wc.lpfnWndProc   = MainWndProc; 
    	wc.cbClsExtra    = 0;
    	wc.cbWndExtra    = 0;
    	wc.hInstance     = m_hInst;
    	wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
    	wc.hCursor       = LoadCursor(0, IDC_ARROW);
    	wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
    	wc.lpszMenuName  = 0;
    	wc.lpszClassName = L"WindowClass1";
    
    	RegisterClassEx(&wc);
    
    	RECT rc = {0, 0, m_clientWidth, m_clientHeight};
    	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);   // die client bzw. window area berechnen
    	m_windowWidth = rc.right - rc.left;
    	m_windowHeight = rc.bottom - rc.top;
    
    	m_hWnd = CreateWindowEx( NULL, L"WindowClass1", L"DirectX sais: 'Hello world!'", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, m_windowWidth, m_windowHeight, NULL, NULL, m_hInst, NULL );
    
        ShowWindow(m_hWnd, SW_SHOW);
    
    	if(!m_hWnd)
    	{
    		MessageBox(NULL, L"Cannot create the Window!", L"Error", MB_OK | MB_ICONERROR);  // falls es fehlschlägt
    		return false;
    	}
    
    	ShowWindow(m_hWnd, 0);  // Fenster zeigen
    	UpdateWindow(m_hWnd);
    
    	// --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    	UINT createDeviceFlags = 0;
    
    #if defined(DEBUG) | defined(_DEBUG)  // Wenn in debug mode, dann die flag zum erstellen verwenden
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif
    
    	D3D_FEATURE_LEVEL featureLevel;
    
    	HRESULT hr = D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0, createDeviceFlags, 0, 0, D3D11_SDK_VERSION, &m_d3dDevice, &featureLevel, &m_d3dDeviceContext); // d3dDevice erstellen
    
    	DWORD x = GetLastError();
    
    	if(FAILED(hr)) // fehlgeschlagen?
    	{
    		MessageBox(0, L"Creating the d3dDevice failed!", L"Error", MB_OK | MB_ICONERROR);
    		return false;
    	}
    
    	if(featureLevel != D3D_FEATURE_LEVEL_11_0) // directx11 nicht unterstützt?
    	{
    		MessageBox(0, L"Direct3D Feature Level 11 unsupported.", L"Error", MB_OK | MB_ICONERROR);
    		return false;
    	}
    
    	m_d3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m_4xMSAAQuality); // Wie gut kann vierfaches MSAA unterstützt werden?
    
    	// swap chain desc ausfüllen
    
    	DXGI_SWAP_CHAIN_DESC sd;
    	sd.BufferDesc.Width  = m_clientWidth;
    	sd.BufferDesc.Height = m_clientHeight;
    	sd.BufferDesc.RefreshRate.Numerator = 60;
    	sd.BufferDesc.RefreshRate.Denominator = 1;
    	sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    	if(m_enable4xMSAA)
    	{
    		sd.SampleDesc.Count   = 4;
    		sd.SampleDesc.Quality = m_4xMSAAQuality-1;
    	} else
    	{
    		sd.SampleDesc.Count   = 1;
    		sd.SampleDesc.Quality = 0;
    	}
    	sd.BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    	sd.BufferCount  = 1;
    	sd.OutputWindow = m_hWnd;
    	sd.Windowed     = true;
    	sd.SwapEffect   = DXGI_SWAP_EFFECT_DISCARD;
    	sd.Flags        = 0;
    
    	IDXGIDevice* dxgiDevice = 0;                                               // ein bisschen code zum erstellen der swap chain
    	m_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
    
    	IDXGIAdapter* dxgiAdapter = 0;
    	dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter);
    
    	IDXGIFactory* dxgiFactory = 0;
    	dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory);
    
    	dxgiFactory->CreateSwapChain(m_d3dDevice, &sd, &m_swapChain);
    
    	ReleaseCOM(dxgiDevice);  // ungenutzte COM objekte löschen
    	ReleaseCOM(dxgiAdapter);
    	ReleaseCOM(dxgiFactory);
    
    	Resize(); // Depth/Stencil Buffer und Viewport einstellen
    
    	return true;  // hat alles geklappt?!? - Nein eher nicht.... :(
    }
    

    Ich hoffe ihr könnt mir helfen. Ich werd noch verrückt! Ich kopier etwas funktionierendes und schreibe es minimal um und es geht nicht mehr 😡 !

    Bei weiteren Fragen nur zu 😉

    Danke schonmal
    MfG Sky :p

    Weiß keiner ne Lösung oder versteht ihr nicht was ich meine?
    Wenn ihr noch Fragen habt fragt einfach!
    Das ist echt frustrierend 😞



  • Hast du denn schon rausgefunden, was 126 als Fehler bedeutet?
    Wenn nicht, dann öffne mal im VS unter dem Menüpunkt "Tools" das Programm "Error Lookup"...



  • Wenn du gerade mit directx anfängst empfehle ich dir, erstmal auf directx 9 zu wechseln und dann später directx 11 zu verwenden.
    Wenn du die debug flag aktiviert hast und das Programm über PIX (beim directx sdk dabei) startest, bekommst du außerdem direkte infos warum diese und jene funktion fehlgeschlagen ist.



  • Zu 1):
    Setzt du denn auch den m_window Pointer bevor du GetMessage/PeekMessage aufrufst?


Log in to reply