Direct3D-CreateDevice funktioniert nicht



  • Hallo Leute,

    ich bin ein Anfänger in Sachen Direct3D und habe mich an die relativ simple Aufgabe gewagt eine Direct3DDevice-Schnittstelle zu erzeugen. Das Abfragen der Adapter und Videomodi klappt ganz gut, aber wenn ich dann das eigentliche Device erzeugen will funktioniert das nicht. Hier die Funktion in der ich 'CreateDevice' aufrufe:

    bool erzeuge_device(UINT adapter, const D3DDISPLAYMODE &mode){
    
    HRESULT hResult;
    D3DPRESENT_PARAMETERS PresentParams;
    
    ZeroMemory(&PresentParams, sizeof(D3DPRESENT_PARAMETERS));
    PresentParams.BackBufferWidth = mode.Width;
    PresentParams.BackBufferHeight = mode.Height;
    PresentParams.BackBufferFormat = D3DFMT_X8R8G8B8;
    PresentParams.BackBufferCount = 1;
    PresentParams.MultiSampleType = D3DMULTISAMPLE_NONE;
    PresentParams.MultiSampleQuality = 0;
    PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
    PresentParams.hDeviceWindow = hWindow;
    PresentParams.Windowed = false;
    PresentParams.EnableAutoDepthStencil = true;
    PresentParams.AutoDepthStencilFormat = D3DFMT_D24S8;
    PresentParams.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
    PresentParams.FullScreen_RefreshRateInHz = mode.RefreshRate;
    PresentParams.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
    //Geräteschnittstelle erzeugen
    
    if(FAILED(hResult = pD3D->CreateDevice(adapter, D3DDEVTYPE_HAL, hWindow, NULL, 
                                           &PresentParams, &pD3DDevice))){
    	MessageBoxA(NULL, "Konnte  kein Device erstellen",
    			  "Fehler",
    			   MB_OK | MB_ICONEXCLAMATION);
    	return false;
    	}else{
    	   //Cursor ausblenden
    	   ShowCursor(FALSE);
    	   return true;
    	}
    }
    

    Die Variablen 'hWindow' und 'pD3DDevice' globale Variablen.
    Wenn ich das Programm laufen lasse, dann kommt meine Fehlermeldung mit der Information, dass kein Device erstellt werden konnte.

    Die Werte der Argumente von 'CreateDevice' wenn ich debugge:
    - adapter = 0
    - hWindow = unused <Speicher kann nicht gelesen werden> 😕
    - PresentParams.hDeviceWindow = unused <Speicher kann nicht gelesen werden> 😕

    Aus diesen Werten entnehme ich, dass der Fehler bei 'hWindow' liegt, hier die Funktion in der das Fenster erstellt wird:

    bool InitWindow(int iWidth,
    		int iHeight){
    	//Fensterklassenstruktur ausfüllen
    	WNDCLASSEX WindowClass = {sizeof(WNDCLASSEX), CS_CLASSDC, WindowProc,
    				  0, 0, GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      TEXT("Direct3Dwindow"), NULL};
    
    	//Fensterklasse registrieren
    	if (!RegisterClassEx (&WindowClass) )
    		return (false);
    
    	//Das Fenster erzeugen	
    hWindow = CreateWindow(TEXT("Direct3Dwindow"),								
    		  NULL,						   
              WS_OVERLAPPEDWINDOW | WS_VISIBLE,	
              CW_USEDEFAULT, CW_USEDEFAULT,				
    		  iWidth, iHeight,							
    		  NULL,								
    		  NULL,								
    		  GetModuleHandle(NULL),								
    		  NULL);								
    
    if(!hWindow){
    	MessageBoxA(NULL, "Windows-Fenster konnte nicht erstellt werden!",
    			  "Fehler",
    			   MB_OK | MB_ICONEXCLAMATION);
    	    return false;
    	  }
        return true;
    }
    

    Auch hier direkt nach dem Aufrufen von 'CreateWindow' kann der Debugger den Wert von hWindow nicht lesen,
    ich weiß nicht was ich falsch mache, aber ich bin mit meinem Latein zu Ende. Ich habe auch schon ausführlich in Google nach der Lösung gesucht, aber nichts relevantes gefunden.

    Vielen Dank schon mal im Voraus, ich hoffe ihr könnt mir helfen.



  • NULL ist kein gültiger Wert für die BehaviorFlags...



  • Vielen Dank jetzt funktionierts.

    Ich hätte aber noch zwei Fragen:

    1. Wieso erstellt er mein Device nur mit den Flags
    D3DCREATE_HARDWARE_VERTEXPROCESSING
    D3DCREATE_SOFTWARE_VERTEXPROCESSING
    D3DCREATE_MIXED_VERTEXPROCESSING
    

    , nicht aber mit den Flags

    D3DCREATE_MULTITHREADED
    D3DCREATE_PUREDEVICE
    D3DCREATE_DISABLE_DRIVER_MANAGEMENT
    

    ???

    bool InitWindow(int iWidth,
    		int iHeight,
    		char* pcName){
    hWindow = CreateWindow(TEXT("Direct3Dwindow"),								
    		       pcName,						    
    		       WS_OVERLAPPEDWINDOW | WS_VISIBLE,	
    		       CW_USEDEFAULT, CW_USEDEFAULT,				
    		       iWidth, iHeight,							
    		       NULL,								
    		       NULL,								
    		       GetModuleHandle(NULL),								
    		       NULL);				
    }
    

    Hier meckert IntelliSense, dass char* nicht mit LPCWSTR kompatibel ist.
    Was muss ich tun damit ich einen Namen für das Fenster übergeben kann ???

    Vielen dank aber nochmal für die schnelle Hilfe 👍



  • aPineapple schrieb:

    Hier meckert IntelliSense, dass char* nicht mit LPCWSTR kompatibel ist.
    Was muss ich tun damit ich einen Namen für das Fenster übergeben kann ???

    Aus http://www.c-plusplus.net/forum/320773

    decimad schrieb:

    Noch kurz zur Begründung:

    Ursprünglich war Windows nicht für Unicode ausgelegt. Die ganzen Funktionen, die Strings annahmen, waren auf "const char*" oder soetwas ausgelegt. Nun kam die Zeit des Unicode und man hatte die Wahl einen zweiten Satz Funktionen anzubieten oder sich etwas anderes zu überlegen. Man traf die Wahl, zwei neue Sätze von Funktionen anzubieten, der eine endet auf "A" und bezeichnet die Ansi-Version und der andere "W" was zunächst eine Wide-Character Version und am Schluss UTF-16 wurde. Da jetzt die ursprünglichen Funktionsnamen frei wurden, nahmen Makros ihren Platz ein, die abhängig von den Compiler-Switches entweder auf die A- oder auf die W-Variante umleiten.
    Wenn man nun vergisst, den Unicode-Parameter einzustellen, dann leiten die Makros an die A-Variante weiter, was natürlich nicht funktionieren kann, wenn man ihnen Unicode-Argumente übergibt.

    Wenn du dir mal die Definition von RegisterClassEx anschaust, dann steht da folgendes:

    #ifdef UNICODE
    #define RegisterClassEx  RegisterClassExW
    #else
    #define RegisterClassEx  RegisterClassExA
    #endif // !UNICODE
    

    Mit CreateWindow ist es ähnlich. Einfach den Parameter aus deiner InitWindow Funktion auf wchar_t* ändern und den Parameter auch mit dem TEXT Makro übergeben.

    Hoffe ich konnte helfen
    floorball



  • Vielen Dank für die schnelle Antwort.
    Hat mir sehr geholfen.
    Danke.


Anmelden zum Antworten