Für DirectX ein Windows Fenster erstellen



  • Hi,
    Ich versuche gerade DirectX zu initialisieren. Mein Programm scheitert aber jedes mal an Zeile 126 (mSwapChain->GetBuffer)
    Fehlermeldung: Zugriffsverletzung beim lesen an Position 0x0000000.
    Ich vermute es liegt an Zeile 96. Da habe ich einfach mal auf gut Glück 0 statt der Variable mhMainWnd eingetragen in der Hoffnung das es damit den Standard aufruft. Die Variable mhMainWnd soll:
    "A handle to the window we are rendering into"
    sein. Jetzt kann ich natürlich kein Windows Programmiren und habe auch relativ wenig Lust mich wegen einer Zeile Code da rein zu arbeiten. Insbesondere weil in dem Buch steht das ich kein Windows Programmieren können muss. Beispiel Code gibt es zwar aber der lässt sich auch nicht kompilieren 🙂
    Kann natürlich auch sein das es wo anders scheitert. Was ich brauche ist eine idealerweise bereits bei Visual Studio enthaltene Bibliothek, mit einer Funktion die der Varaible den korrekten Wert liefert. Danke für Antworten.

    #include <iostream>
    #include <Windows.h>
    #include <assert.h>
    #include <xnamath.h>
    #include <D3D11.h>
    
    bool MSAA_4X = true;
    
    #define ReleaseCOM(x) { if(x){ x->Release(); x = 0; } }
    
    int mClientWidth = 2560;
    int mClientHeight = 1280;
    
    #define DEBUG
    
    using namespace std;
    int main()
    {
    	if(!XMVerifyCPUSupport())
    	{
    		cout << "ERROR: xna math not supported" << endl;
    		return 0;
    	}
    
    	UINT createDeviceFlags = 0;
    
    	#if defined(DEBUG) || defined(_DEBUG)
    		createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
        #endif
    
    	D3D_FEATURE_LEVEL featureLevel;
    	ID3D11Device* md3dDevice;
    	ID3D11DeviceContext* md3dImmediateContext;
    
    	HRESULT hr = D3D11CreateDevice
    		(
    		0,
    		D3D_DRIVER_TYPE_HARDWARE,
    		0,
    		createDeviceFlags,
    		0,
    		0,
    		D3D11_SDK_VERSION,
    		&md3dDevice,
    		&featureLevel,
    		&md3dImmediateContext
    		);
    
    	if(FAILED(hr))
    	{
    		MessageBox(0, L"D3D11CreateDevice Failed.", 0, 0);
    		Sleep(5000);
    		return 0;
    	}
    
    	if(featureLevel != D3D_FEATURE_LEVEL_11_0)
    	{
    		MessageBox(0, L"Direct3D Feature Level 11 unsupported.", 0, 0);
    		Sleep(5000);
    		return 0;
    	}
    
    	DDXGI_SWAP_CHAIN_DESC sd;
    	sd.BufferDesc.Width = mClientWidth;   
    	sd.BufferDesc.Height = mClientHeight;
    	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;
    
    	UINT MSAAQuality_4X;
    	md3dDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &MSAAQuality_4X);
    
    	if(MSAA_4X)
    	{
    		sd.SampleDesc.Count = 4;
    		sd.SampleDesc.Quality = MSAAQuality_4X - 1;
    	}
    
    	else
    	{
    		sd.SampleDesc.Count = 1;
    		sd.SampleDesc.Quality = 0;
    	}
    
    	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    	sd.BufferCount = 1;
    	sd.OutputWindow = 0;  //mhMainWnd sollte hier statt 0 stehen. 
    	sd.Windowed = true;
    	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    	sd.Flags = 0;
    
    	IDXGIDevice* dxgiDevice = 0;
    	md3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
    
    	IDXGIAdapter* dxgiAdapter = 0;
    	dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&dxgiAdapter);
    
    	IDXGIFactory* dxgiFactory = 0;
    	dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxgiFactory);
    
    	IDXGISwapChain* mSwapChain;
    	dxgiFactory->CreateSwapChain(md3dDevice, &sd, &mSwapChain);
    
    	ReleaseCOM(dxgiDevice);		
    	ReleaseCOM(dxgiAdapter);
    	ReleaseCOM(dxgiFactory);
    
    	ID3D11RenderTargetView* mRenderTargetView; 
    	ID3D11Texture2D* backBuffer;
    	mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer));
    	md3dDevice->CreateRenderTargetView(backBuffer, 0, &mRenderTargetView);
    	ReleaseCOM(backBuffer);
    


  • Neo234 schrieb:

    Ich versuche gerade DirectX zu initialisieren. Mein Programm scheitert aber jedes mal an Zeile 126 (mSwapChain->GetBuffer)
    Fehlermeldung: Zugriffsverletzung beim lesen an Position 0x0000000.

    Grund für den Fehler: CreateSwapChain() schlägt fehl und dein mSwapChain ist daher Null...

    Neo234 schrieb:

    Ich vermute es liegt an Zeile 96. Da habe ich einfach mal auf gut Glück 0 statt der Variable mhMainWnd eingetragen in der Hoffnung das es damit den Standard aufruft.

    Wie stellst du dir das vor? Was für einen "Standard" soll "es" da deiner Meinung nach "aufrufen"?

    Neo234 schrieb:

    Die Variable mhMainWnd soll:
    "A handle to the window we are rendering into"
    sein.

    Exakt, mit Null übergeben wird da also nix...

    Neo234 schrieb:

    Jetzt kann ich natürlich kein Windows Programmiren und habe auch relativ wenig Lust mich wegen einer Zeile Code da rein zu arbeiten.

    Schlechte Voraussetzungen, wenn du mit Direct3D arbeiten willst; da wirst du nicht drum herum kommen...

    Neo234 schrieb:

    Kann natürlich auch sein das es wo anders scheitert. Was ich brauche ist eine idealerweise bereits bei Visual Studio enthaltene Bibliothek, mit einer Funktion die der Varaible den korrekten Wert liefert.

    Lern, wie du mit der WinAPI ein Fenster erzeugst.

    Abgesehen davon noch ein paar Anmerkungen:

    1. Verwend Smartpointer (!)

    2. Gibt es einen bestimmten Grund, wieso du die Refresh Rate auf exakt 60Hz festlegst? Wenn nein, dann stell die besser auf 0 und überlass DXGI die Wahl.

    MSDN schrieb:

    It is important not to assume that certain refresh rates will always be supported and to simply hard-code a value. Often, developers choose 60 Hz as the refresh rate, not knowing that the enumerated refresh rate from the monitor is approximately 60,000 / 1,001 Hz from the monitor. If the refresh rate does not match the expected refresh rate of 60, DXGI is forced to perform a blit in full-screen mode instead of a flip.



  • Danke für die Antwort. Es war vorher oft so das man einfach 0 eintragen konnte, deshalb hab ichs auf gut Glück probiert. Was anderes hätte ich auch schlecht eintragen können. Wie der Fehler zustande kommt ist mir auch klar und wie ich ihn beheben könnte auch nur fehlen mir die Windows kenntnisse. Ich werde mir das ganze jetzt wohl aneignen müssen. Was die Refrehsrate betrifft die ist da ohne Begründung angegeben. Ich werde sie dann jetzt allerdings ändern.

    PS: Die Seite akzeptiert meine login Daten nicht. Deshalb anderer Name



  • DERNeo234 schrieb:

    Ich werde mir das ganze jetzt wohl aneignen müssen. Was die Refrehsrate betrifft die ist da ohne Begründung angegeben. Ich werde sie dann jetzt allerdings ändern.

    👍



  • Das Fenster zu erstellen ist nicht so wild, keine Sorge. Du benutzt wahrscheinlich Visual Studio, damit kannst Du auch automatisch eine GUI-Anwendung erstellen und dort Deinen DirectX-Code einfügen. Sollte zum schnellen Start reichen; um eine Auseinandersetzung mit dem Fenster wirst Du allerdings nicht herumkommen, aber das merkst Du dann schon selbst, wenn Du soweit bist 😉



  • Eine Frage......wie kannst du allen ernstes versuchen, DirectX in einem Fenster zu initialisieren ohne ein Fenster zu haben?!? 😕 Wo willst du denn rendern in deinem ''Standart''? 😕



  • Eine Frage...wieso glaubst du allen ernstes, dass das nach zwei Jahren hier noch irgendwen interessiert? :p



  • Kein plan ich hab nur nach ner Lösung für mein problem gegoogelt und das hier gefunden.... 😃


Anmelden zum Antworten