Versuche Directx Programmcode zu Optimieren (c++)



  • Hallo zusammen,

    ich versuche schon seit langem mit die DX Programmierung beizubringen.
    Als erstes habe ich mir ein Tutorial geschnappt und wollte es so umschreiben wie ich es gerne haben möchte, und da komme ich einfach nicht weiter!

    1. In der Hauptdatei sollte wenn möglich nur die wMain sein.
    2. Alle anderen Programmteile rufe ich dann über Funktionen auf.( Quasi alle Positionen im Inhaltsverzeichnis )

    Nun einige haben bei meinem Projekt Funktioniert und manche nicht.

    Ich hoffe mir kann jemand sagen, warum ich z.B die Funktion ( FrameRender() ) nicht in eine andere Datei auslagern kann ...--> Fehlermeldung "Zugriffsverletzung Pointer--> NULL"

    Hauptdatei:

    (Tutorial01.cpp)
    //--------------------------------------------------------------------------------------
    // File: Tutorial01.cpp
    //
    // This application demonstrates creating a Direct3D 11 device
    //
    // Copyright (c) Microsoft Corporation. All rights reserved.
    //--------------------------------------------------------------------------------------
    //---------------------------------INHALTSVERZEICHNIS-----------------------------------
    
    //----1--------DECLARATION+Foward declaration
    //----2--------WINMAIN zur initalisierung
    //----3--------Registrieren der Klassen und erzeugen eines Fensters
    //----4--------Nachrichtenschleife
    //----5--------Erzeugen eines "Direct3D Gerätes" und eines  "swap chain" (Übersetzt Tauschkette )
    //----6--------Frame wird gerändert
    //----7--------Grafikkarte wird geleert und Heruntergefahren
    /*
    Benötigtes Werkzeug:
    
    MessageBox(0, L"Haltepunkt 2", L"Meine App", MB_OK);
    
    */
    //----1----------------------------------------------------------------------------------
    #include <iostream>
    #include <windows.h>
    #include <d3dcompiler.h>
    #include <d3d10_1.h>
    #include <d3d11.h>
    #include <d3dx11.h>
    #include "GlobDefinitionen.cpp"
    #include "DXGeräteini.h"
    #include "Resourcedefinitionen.h"
    #include "DXHerrunterfahren.h"
    #include "DXRendern.h"
    #include <directxcolors.h>
    #include <directxmath.h>
    #include "WINFenster.h"
    #include <math.h>
    #include <assert.h>
    using namespace DirectX;
    
    // Forward Dekleration
    HRESULT FensterInit( HINSTANCE hInstance, int nCmdShow );
    
    HRESULT GeräteInit();
    void FrameRender();
    
    void FrameRender()
    {
    	// "backbuffer" wird geleert 
    	float ClearColor[4] = { 0.3f, 0.125f, 0.3f, 1.0f };						//red,green,blue,alpha->AbstandzurKamera			Hintergrundfarbe
    
    	(*g_pImmediateContext).ClearRenderTargetView(g_pRenderTargetView, ClearColor);
    	//
    	// Präsentieren Sie unseren Rückenpuffer zu unserem Frontpuffer
    	//
    	(*g_pSwapChain).Present(0, 0);
    }
    
    //----2----------------------------------------------------------------------------------
    // Einstiegspunkt zum Programm Initialisiert alles und geht in eine Nachrichtenverarbeitung Schleife.
    // Die Leerlaufzeit wird zum Rendern der Szene verwendet.
    //--------------------------------------------------------------------------------------
    int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
    {
    
    	UNREFERENCED_PARAMETER( hPrevInstance );
        UNREFERENCED_PARAMETER( lpCmdLine );
    
        if( FAILED( FensterInit( hInstance, nCmdShow ) ) )
    	{ 
    		MessageBox(0, L"Fehler! Windows Fenster Initialisierung", L"Meine App", MB_OK);
            return 0;
    	}
    
        if ( FAILED (GeräteInit ()))
        {
    		MessageBox(0, L"Fehler! Geräte Initialisierung", L"Meine App", MB_OK);
    		Gerätherunterfahren();
            return 0;
        }
    
        // Haupt Nachrichtenschleife
        MSG msg = {0};
        while( WM_QUIT != msg.message )
        {
            if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
            else
            {
    		FrameRender();
            }
        }
    	//--------7------------------------------------------------------------------------------
    	// Grafikkarte wird geleert und Heruntergefahren
    	//--------------------------------------------------------------------------------------
        Gerätherunterfahren();
    
        return ( int )msg.wParam;
    }
    
    //-----4---------------------------------------------------------------------------------
    // Wird jedes Mal aufgerufen, wenn die Anwendung eine Nachricht erhält
    //--------------------------------------------------------------------------------------
    LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
    
    	PAINTSTRUCT ps;
    	HDC hdc;
        switch( message )
        {
            case WM_PAINT:
                hdc = BeginPaint( hWnd, &ps );
    
    			//Ausgabe von Text---------------------------
    
    			SetTextColor(hdc, RGB(220, 100, 0));
    			TextOut(hdc, 10, 10, TEXT("Hallo ihr futzies" ), 17);
    
    			//--------------------------------------------
                EndPaint( hWnd, &ps );
                break;
    
            case WM_DESTROY:
                PostQuitMessage( 0 );
                break;
    
            default:
                return DefWindowProc( hWnd, message, wParam, lParam );
        }
    
        return 0;
    }
    
    //-----3---------------------------------------------------------------------------------
    // Register class and create window
    //--------------------------------------------------------------------------------------
    HRESULT FensterInit(HINSTANCE hInstance, int nCmdShow)
    {
    	//// Register class
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    	wcex.style = CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc = WndProc;
    	wcex.cbClsExtra = 0;
    	wcex.cbWndExtra = 0;
    	wcex.hInstance = hInstance;
    	wcex.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));									//ICON im Fenster wenn ALT+TAB verwendet wird
    	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
    	wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
    	wcex.lpszClassName = L"TutorialWindowClass";
    	wcex.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0); //ICON links oben im Fenster
    	if (!RegisterClassEx(&wcex))
    	{
    		MessageBox(0, L"Windows Klasse konnte nicht Registriert werden!", L"Meine App", MB_OK);
    
    		return 0;
    	}
    
    	// Create window
    	g_hInst = hInstance;
    	RECT rc = { 0, 0, 640, 480 };
    	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
    	g_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"TutorialWindowClass", L"Direct3D Version 11 Tutorial 1", WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,NULL);
    	if (!g_hWnd)
    	{ 
    		MessageBox(0, L"Windows konnte das Fenster nicht umsetzen!", L"Meine App", MB_OK);
    		return E_FAIL;
    	}
    	//Fenster wird angezeigt
    	ShowWindow(g_hWnd, nCmdShow);
    
    	return S_OK;
    }
    //*/
    
    ///*
    //-------5-------------------------------------------------------------------------------
    // Create Direct3D device and swap chain
    //--------------------------------------------------------------------------------------
    HRESULT GeräteInit()
    {
        static HRESULT hr = S_OK;
    	static RECT rc;											//Die RECT-Struktur definiert die Koordinaten der oberen linken und unteren rechten Ecke eines Rechtecks.
        GetClientRect( g_hWnd, &rc );
        UINT width = rc.right - rc.left;
        UINT height = rc.bottom - rc.top;
    
        UINT createDeviceFlags = 0;
    #ifdef _DEBUG
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif
    
        D3D_DRIVER_TYPE driverTypes[] =
        {
            D3D_DRIVER_TYPE_HARDWARE,
            D3D_DRIVER_TYPE_WARP,
            D3D_DRIVER_TYPE_REFERENCE,
        };
        UINT numDriverTypes = ARRAYSIZE( driverTypes );
    
        D3D_FEATURE_LEVEL featureLevels[] =
        {
            D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL_10_0,
        };
    	UINT numFeatureLevels = ARRAYSIZE( featureLevels );
    
    	DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory( &sd, sizeof( sd ) );
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;
    
        for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
        {
            g_driverType = driverTypes[driverTypeIndex];
            hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
                                                D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
            if( SUCCEEDED( hr ) )
                break;
        }
        if( FAILED( hr ) )
            return hr;
    
        // Create a render target view
        ID3D11Texture2D* pBackBuffer = NULL;
        hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );
        if( FAILED( hr ) )
            return hr;
    
        hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
        (*pBackBuffer).Release();
        if( FAILED( hr ) )
            return hr;
    
        (*g_pImmediateContext).OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
    
        // Einrichten der Kamera 
        D3D11_VIEWPORT vp;
        vp.Width = (FLOAT)width;
        vp.Height = (FLOAT)height;
        vp.MinDepth = 0.0f;
        vp.MaxDepth = 1.0f;
        vp.TopLeftX = 0;
        vp.TopLeftY = 0;
        g_pImmediateContext->RSSetViewports( 1, &vp );
    
        return S_OK;
    }
    //*/
    

    //DXRender.h Datei

    #ifndef DXRENDERN_H
    #define DXRENDERN_H
    
    void FrameRender();
    #endif
    

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    DXRender.CPP   // Text ist der Hauptdatei nur rauskopiert worden
    
    #include "GlobDefinitionen.cpp"
    #include "DXRendern.h"
    
    //--------6------------------------------------------------------------------------------
    // Frame wird gerändert
    //--------------------------------------------------------------------------------------
    void FrameRender()
    {
    	// "backbuffer" wird geleert 
    	float Hintergrundfarbe[4] = { 0.3f, 0.125f, 0.3f, 1.0f };						//red,green,blue,alpha->AbstandzurKamera			Hintergrundfarbe
    
    	(*g_pImmediateContext).ClearRenderTargetView(g_pRenderTargetView, Hintergrundfarbe);
    	//
    	// Präsentieren Sie unseren Rückenpuffer zu unserem Frontpuffer
    	//
    	(*g_pSwapChain).Present(0, 0);
    }
    
    // Globeldefinitions.cpp
    
    #ifndef GLOBDEFINITIONEN_CPP
    #define GLOBDEFINITIONEN_CPP
    #include <d3d10_1.h>
    #include <d3d11.h>
    #include <d3dx11.h>
    
    //Windows Script Definitionen
    #define ID_ICON_SMALL 1
    #define IDI_MYICON 2
    #define IDR_MYMENU 3
    
    	//--------------------------------------------------------------------------------------
    	// Globale Variables
    	//--------------------------------------------------------------------------------------
    
    	static D3D_DRIVER_TYPE         g_driverType = D3D_DRIVER_TYPE_NULL;
    	static D3D_FEATURE_LEVEL       g_featureLevel = D3D_FEATURE_LEVEL_11_0;
    	static ID3D11Device*           g_pd3dDevice = nullptr;
    	static ID3D11DeviceContext*    g_pImmediateContext = nullptr;
    	static IDXGISwapChain*         g_pSwapChain = nullptr;
    	static ID3D11RenderTargetView* g_pRenderTargetView = nullptr;
    
    	//--------------------------------------------------------------------------------------
    	// Globale Variables Windows Parameter
    	//--------------------------------------------------------------------------------------
    	static WNDCLASSEX wcex;
    	static HINSTANCE               g_hInst = nullptr;
    	static HWND                    g_hWnd = nullptr;
    
    #endif
    


  • was sagt dein debugger welcher pointer null ist?



  • rapso schrieb:

    was sagt dein debugger welcher pointer null ist?

    Antwort des Compilers: 👍

    Ausgelöste Ausnahme: Lesezugriffsverletzung

    "g_pImmediateContext" war "nullptr".

    Falls ein Handler für diese Ausnahme vorhanden ist, kann das Programm möglicherweise weiterhin sicher ausgeführt werden.



  • TippoMax2 schrieb:

    rapso schrieb:

    was sagt dein debugger welcher pointer null ist?

    Antwort des Compilers: 👍

    Ausgelöste Ausnahme: Lesezugriffsverletzung

    "g_pImmediateContext" war "nullptr".

    Falls ein Handler für diese Ausnahme vorhanden ist, kann das Programm möglicherweise weiterhin sicher ausgeführt werden.

    Der compiler erstellt nur das program, zur laufzeit ist dieser nicht mehr vorhanden. Du wirst das wohl in deiner IDE vom debugger erhalten.

    Jetzt musst du den pointer nur noch iniitialisieren.

    ach ja, kannst du mir sagen, was du durch das "static" in:

    static IDXGISwapChain*         g_pSwapChain = nullptr;
    

    beabsichtigst?



  • rapso schrieb:

    TippoMax2 schrieb:

    rapso schrieb:

    was sagt dein debugger welcher pointer null ist?

    Antwort des Compilers: 👍

    Ausgelöste Ausnahme: Lesezugriffsverletzung

    "g_pImmediateContext" war "nullptr".

    Falls ein Handler für diese Ausnahme vorhanden ist, kann das Programm möglicherweise weiterhin sicher ausgeführt werden.

    Der compiler erstellt nur das program, zur laufzeit ist dieser nicht mehr vorhanden. Du wirst das wohl in deiner IDE vom debugger erhalten.

    Jetzt musst du den pointer nur noch iniitialisieren.

    ach ja, kannst du mir sagen, was du durch das "static" in:

    static IDXGISwapChain*         g_pSwapChain = nullptr;
    

    beabsichtigst?

    Hallo ,

    ohne den "Static" Befehl habe ich eine mehrfach deklaration und wie ich die verhindern kann weiß ich nicht.

    Fehlercode des Compilers beim weglassen des STATIC befehls

    Fehler LNK2005 "struct ID3D11RenderTargetView *
    g_pRenderTargetView" (?g_pRenderTargetView@@3PEAUID3D11RenderTargetView@@EA)
    ist bereits in DXHerrunterfahren.obj definiert.

    Datei Globdefinitionen.cpp

    #include "DxHerrunterfahren.h"
    #include "GlobDefinitionen.cpp"
    
    //--------7------------------------------------------------------------------------------
    // Grafikkarte wird geleert und Heruntergefahren
    //--------------------------------------------------------------------------------------
    void Gerätherunterfahren()
    {
    
    	if (g_pImmediateContext) (*g_pImmediateContext).ClearState();
    	if (g_pRenderTargetView) (*g_pRenderTargetView).Release();
    	if (g_pSwapChain) (*g_pSwapChain).Release();
    	if (g_pImmediateContext) (*g_pImmediateContext).Release();
    	if (g_pd3dDevice) (*g_pd3dDevice).Release();
    
    }
    


  • Das "static" ist die Quelle deines Problems. Du musst die Grundlagen von C++ lernen, damit du etwas bewerkstelligen kannst, ansonsten wirst du wegen solcher grundlegenden Dinge immer wieder steckenbleiben.

    Ich verschiebe das mal in den C++ Bereich, da wird dir schneller geholfen. (Weil es nichts mit Spiele-/Grafikprogrammierung zu tun hat 😉 )



  • Dieser Thread wurde von Moderator/in rapso aus dem Forum Spiele-/Grafikprogrammierung in das Forum C++ (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    cpp schrieb:

    #include "GlobDefinitionen.cpp"

    Wer so etwas macht, darf alle entstehenden Probleme behalten.

    1. Wenn es Includeguards hat, dann ist es ein Header und sollte auch so benannt sein. .cpp implizit die Quelle einer eigenständigen Objektdatei, nicht etwas, dass in mehreren Übersetzungseinheiten (ÜE) eingebunden werden soll.
    2. Globale Variablen sind böse.
    3. Globale Variablen sind böse.
    4. Es wird nicht besser
    5.
    6.
    7.
    8. ...
    9. ...
    10. Du sollst keine globalen Variablen einsetzen.

    Elftes Gebot:
    Im Allgemeinen darf eine Variable nur einmal im Programm definiert werden. Deklarationen dürfen gerne so oft sie wollen auftreten, sofern sie alle übereinstimmen.
    Ohne static ist diese One-Definition-Rule (ODR) offenkundig verletzt.
    Mit static ist sie bloß deswegen nicht verletzt, weil static (in diesem Zusammenhang; static hat ja noch andere Verwendungen) internal linkage impliziert, der Linker bekommt dieses Symbol nie zu sehen und jede ÜE hat ihre eigene Version dieser Variablen, die mit den Anderen nichts zu tun hat.

    Wenn dann also irgendwo in main eine Variable g_pImmediateContext initialisiert, ist das ein anderes Objekt als dasjenige, welches FrameRender, das ja in einer anderen ÜE definiert ist, als die Variable g_pImmediateContext ansieht - dieses Objekt behält seinen Wert, den es beim Programmstart erhalten hat (nämlich nullptr).

    Nebenbemerkung: diese Verwendung von static ist in C++ veraltet, für diesen Zweck (wenn man also tatsächlich mal die gleiche Entität in verschiedenen ÜEs mehrfach haben will) sind anonyme Namensräume gedacht.

    Wenn also eine einzige globale Variable in mehreren ÜEs verwendet werden soll, dann darf *bisher* im Header nur eine Deklaration dieser Variablen auftreten.
    Das geschieht mit dem Schlüsselwort extern. Wichtig ist, dass diese Deklaration keinen Initialisierer enthält, sonst wird es zur Definition.
    Header:

    extern int foo;
    

    In einer einzigen Übersetzungseinheit muss diese Variable noch definiert werden, dort gehört dann ggf. ein Initialisierer hin:

    #include "header"
    int foo = 42;
    

    Diese Verdopplung des Codes ist unschön, insbesondere wenn man größere Mengen an Konstanten definieren will.

    Eine traditionelle Möglichkeit, diese Verdopplung zu vermeiden, setzt den Präprozessor ein. Die Deklaration im Header enthält zusätzlich den Initialisierer aber maskiert durch ein Makro. Dieses Makro hat dann nur in einer einzigen ÜE, die für die Definition zuständig ist, einen anderen Wert.
    Beispiel:
    Header

    #ifndef DO_INITIALIZE
    #define DO_INITIALISE(x)
    #endif 
    
    extern int foo DO_INITIALIZE(42);
    

    Nur in einer Quelldatei:

    #define DO_INITIALIZE(x) = x
    #include "header"
    

    13. Mit C++17 und hinreichender Unterstützung durch den Compiler (jetzt auch für die armen Programmierer, die auf Mikroweichs Compiler angewiesen sind, verfügbar), kann das das Schlüsselwort inline ganz analog zu traditionellen Inline-Funktionen eingesetzt werden.
    Header:

    inline int foo = 42; // und fertig
    

    14. Globale Variablen sind immer noch böse.



  • Ich hätte in den 14 Geboten gerne ein 'non-const' gesehen.



  • Ok Vielen Dank für die Erleuterungen.
    Es ist wichtig für einen Anfänger zu hören was SINNVOLL ist und was nicht.
    Da ich in Büchern nur die Theorie erlernen kann, und nicht die "Sinnvolle" ausführungen.

    Ok meine ursprüngliche Frage bleibt dennoch bestehen. Wie fange ich ein sinnvolles Projekt an. ( Auch ohne Globale Variablen ) 😉
    Wie schaffe ich es die Punkte 3-7 aus meiner Haupt Datei zu bekommen ?
    Mein Code sah mal vor der Funktionauslagerung so aus.....

    //---------------------------------INHALTSVERZEICHNIS-----------------------------------
    
    //----1--------DECLARATION+Foward declaration
    //----2--------WINMAIN zur initalisierung
    //----3--------Registrieren der Klassen und erzeugen eines Fensters
    //----4--------Nachrichtenschleife
    //----5--------Erzeugen eines "Direct3D Gerätes" und eines  "swap chain" (Übersetzt Tauschkette )
    //----6--------Frame wird gerändert
    //----7--------Grafikkarte wird geleert und Heruntergefahren
    /*
    Benötigtes Werkzeug:
    
    MessageBox(0, L"Haltepunkt 2", L"Meine App", MB_OK);
    
    */
    //----1----------------------------------------------------------------------------------
    #include <iostream>
    #include <windows.h>
    #include <d3d10_1.h>
    #include <d3d11.h>
    #include <d3dx11.h>
    #include "GlobDefinitionen.cpp"
    #include "Resourcedefinitionen.h"
    #include "DXHerrunterfahren.h"
    
    #include <directxcolors.h>
    #include <directxmath.h>
    
    using namespace std;
    
    // Forward Dekleration
    HRESULT FensterInit( HINSTANCE hInstance, int nCmdShow );
    HRESULT GeräteInit();
    
    //--------6------------------------------------------------------------------------------
    // Frame wird gerändert
    //--------------------------------------------------------------------------------------
    void Rendern()
    {
    	// "backbuffer" wird geleert 
    	float ClearColor[4] = { 0.3f, 0.125f, 0.3f, 1.0f };						//red,green,blue,alpha->AbstandzurKamera			Hintergrundfarbe
    	(*g_pImmediateContext).ClearRenderTargetView(g_pRenderTargetView, ClearColor);
    	//
    	// Präsentieren Sie unseren Rückenpuffer zu unserem Frontpuffer
    	//
    	(*g_pSwapChain).Present(0, 0);
    }
    
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);      //Wird in der Nachrichtenschleife erneut declariert
    //---------------------------------------------------------------------------------------
    
    //----2----------------------------------------------------------------------------------
    // Einstiegspunkt zum Programm Initialisiert alles und geht in eine Nachrichtenverarbeitung Schleife.
    // Die Leerlaufzeit wird zum Rendern der Szene verwendet.
    //--------------------------------------------------------------------------------------
    int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
    {
    
    	UNREFERENCED_PARAMETER( hPrevInstance );
        UNREFERENCED_PARAMETER( lpCmdLine );
    
        if( FAILED( FensterInit( hInstance, nCmdShow ) ) )
            return 0;
    
        if( FAILED( GeräteInit() ) )
        {
    		MessageBox(0, L"Fehler!", L"Meine App", MB_OK);
    		Gerätherunterfahren();
            return 0;
        }
    
        // Haupt Nachrichtenschleife
        MSG msg = {0};
        while( WM_QUIT != msg.message )
        {
            if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
            else
            {
    
                Rendern();
            }
        }
    	//--------7------------------------------------------------------------------------------
    	// Grafikkarte wird geleert und Heruntergefahren
    	//--------------------------------------------------------------------------------------
        Gerätherunterfahren();
    
        return ( int )msg.wParam;
    }
    
    //-----4---------------------------------------------------------------------------------
    // Wird jedes Mal aufgerufen, wenn die Anwendung eine Nachricht erhält
    //--------------------------------------------------------------------------------------
    LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
    {
    
    	PAINTSTRUCT ps;
    	HDC hdc;
        switch( message )
        {
            case WM_PAINT:
                hdc = BeginPaint( hWnd, &ps );
    
    			//Ausgabe von Text---------------------------
    
    			SetTextColor(hdc, RGB(220, 100, 0));
    			TextOut(hdc, 10, 10, TEXT("Hallo ihr futzies" ), 17);
    
    			//--------------------------------------------
                EndPaint( hWnd, &ps );
                break;
    
            case WM_DESTROY:
                PostQuitMessage( 0 );
                break;
    
            default:
                return DefWindowProc( hWnd, message, wParam, lParam );
        }
    
        return 0;
    }
    
    //-----3---------------------------------------------------------------------------------
    // Register class and create window
    //--------------------------------------------------------------------------------------
    HRESULT FensterInit(HINSTANCE hInstance, int nCmdShow)
    {
    	// Register class
    	WNDCLASSEX wcex;
    	wcex.cbSize = sizeof(WNDCLASSEX);
    	wcex.style = CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc = WndProc;
    	wcex.cbClsExtra = 0;
    	wcex.cbWndExtra = 0;
    	wcex.hInstance = hInstance;
    	wcex.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));									//ICON im Fenster wenn ALT+TAB verwendet wird
    	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
    	wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
    	wcex.lpszClassName = L"TutorialWindowClass";
    	wcex.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0); //ICON links oben im Fenster
    	if (!RegisterClassEx(&wcex))
    		return E_FAIL;
    
    	// Create window
    	g_hInst = hInstance;
    	RECT rc = { 0, 0, 640, 480 };
    	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
    	g_hWnd = CreateWindow(L"TutorialWindowClass", L"Direct3D Version 11 Tutorial 1", WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,
    		NULL);
    	if (!g_hWnd)
    		return E_FAIL;
    	//Fenster wird angezeigt
    	ShowWindow(g_hWnd, nCmdShow);
    
    	return S_OK;
    }
    
    //-------5-------------------------------------------------------------------------------
    // Create Direct3D device and swap chain
    //--------------------------------------------------------------------------------------
    HRESULT GeräteInit()
    {
        HRESULT hr = S_OK;
    	RECT rc;											//Die RECT-Struktur definiert die Koordinaten der oberen linken und unteren rechten Ecke eines Rechtecks.
        GetClientRect( g_hWnd, &rc );
        UINT width = rc.right - rc.left;
        UINT height = rc.bottom - rc.top;
    
        UINT createDeviceFlags = 0;
    #ifdef _DEBUG
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif
    
        D3D_DRIVER_TYPE driverTypes[] =
        {
            D3D_DRIVER_TYPE_HARDWARE,
            D3D_DRIVER_TYPE_WARP,
            D3D_DRIVER_TYPE_REFERENCE,
        };
        UINT numDriverTypes = ARRAYSIZE( driverTypes );
    
        D3D_FEATURE_LEVEL featureLevels[] =
        {
            D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL_10_0,
        };
    	UINT numFeatureLevels = ARRAYSIZE( featureLevels );
    
    	DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory( &sd, sizeof( sd ) );
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;
    
        for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
        {
            g_driverType = driverTypes[driverTypeIndex];
            hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
                                                D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
            if( SUCCEEDED( hr ) )
                break;
        }
        if( FAILED( hr ) )
            return hr;
    
        // Create a render target view
        ID3D11Texture2D* pBackBuffer = NULL;
        hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );
        if( FAILED( hr ) )
            return hr;
    
        hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
        (*pBackBuffer).Release();
        if( FAILED( hr ) )
            return hr;
    
        (*g_pImmediateContext).OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
    
        // Einrichten der Kamera 
        D3D11_VIEWPORT vp;
        vp.Width = (FLOAT)width;
        vp.Height = (FLOAT)height;
        vp.MinDepth = 0.0f;
        vp.MaxDepth = 1.0f;
        vp.TopLeftX = 0;
        vp.TopLeftY = 0;
        g_pImmediateContext->RSSetViewports( 1, &vp );
    
        return S_OK;
    }
    


  • Ehm das ist der Richtige !!!!!

    //--------------------------------------------------------------------------------------
    // File: Tutorial01.cpp
    //
    // This application demonstrates creating a Direct3D 11 device
    //
    // Copyright (c) Microsoft Corporation. All rights reserved.
    //--------------------------------------------------------------------------------------
    //---------------------------------INHALTSVERZEICHNIS-----------------------------------
    
    //----1--------DECLARATION+Foward declaration
    //----2--------WINMAIN zur initalisierung
    //----3--------Nachrichtenschleife
    //----4--------Registrieren der Klassen und erzeugen eines Fensters
    //----5--------Erzeugen eines "Direct3D Gerätes" und eines  "swap chain" (Übersetzt Tauschkette )
    //----6--------Frame wird gerändert
    //----7--------Grafikkarte wird geleert und Heruntergefahren
    /*
    Benötigtes Werkzeug:
    
    MessageBox(0, L"Haltepunkt 2", L"Meine App", MB_OK);
    
    */
    //----1----------------------------------------------------------------------------------
    #include <iostream>
    #include <windows.h>
    #include <d3dcompiler.h>
    #include <d3d10_1.h>
    #include <d3d11.h>
    #include <d3dx11.h>
    //#include "DXGeräteini.h"
    #include "Resourcedefinitionen.h"
    //#include "DXHerrunterfahren.h"
    //#include "DXRendern.h"
    #include <directxcolors.h>
    #include <directxmath.h>
    #include "WINFenster.h"
    #include <math.h>
    #include <assert.h>
    using namespace DirectX;
    
    //Windows Script Definitionen
    #define ID_ICON_SMALL 1
    #define IDI_MYICON 2
    #define IDR_MYMENU 3
    
    //--------------------------------------------------------------------------------------
    // Globale Variables
    //--------------------------------------------------------------------------------------
    
    D3D_DRIVER_TYPE         g_driverType = D3D_DRIVER_TYPE_NULL;
    D3D_FEATURE_LEVEL       g_featureLevel = D3D_FEATURE_LEVEL_11_0;
    ID3D11Device*           g_pd3dDevice = nullptr;
    ID3D11DeviceContext*    g_pImmediateContext = nullptr;
    IDXGISwapChain*         g_pSwapChain = nullptr;
    ID3D11RenderTargetView* g_pRenderTargetView = nullptr;
    
    //--------------------------------------------------------------------------------------
    // Globale Variables Windows Parameter
    //--------------------------------------------------------------------------------------
    WNDCLASSEX wcex;
    HINSTANCE               g_hInst = nullptr;
    HWND                    g_hWnd = nullptr;
    
    //----1----------------------------------------------------------------------------------
    // Forward Dekleration
    
    HRESULT FensterInit( HINSTANCE hInstance, int nCmdShow );
    HRESULT GeräteInit();
    void FrameRender();
    void Gerätherunterfahren();
    
    //----2----------------------------------------------------------------------------------
    // Einstiegspunkt zum Programm Initialisiert alles und geht in eine Nachrichtenverarbeitung Schleife.
    // Die Leerlaufzeit wird zum Rendern der Szene verwendet.
    //--------------------------------------------------------------------------------------
    int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
    {
    
    	UNREFERENCED_PARAMETER( hPrevInstance );
        UNREFERENCED_PARAMETER( lpCmdLine );
    
        if( FAILED( FensterInit( hInstance, nCmdShow ) ) )
    	{ 
    		MessageBox(0, L"Fehler! Windows Fenster Initialisierung", L"Meine App", MB_OK);
            return 0;
    	}
    
        if ( FAILED (GeräteInit ()))
        {
    		MessageBox(0, L"Fehler! Geräte Initialisierung", L"Meine App", MB_OK);
    		Gerätherunterfahren();
            return 0;
        }
    
        // Haupt Nachrichtenschleife
        MSG msg = {0};
        while( WM_QUIT != msg.message )
        {
            if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
            else
            {
    		FrameRender();
            }
        }
    	Gerätherunterfahren();
    
        return ( int )msg.wParam;
    }
    //-----4---------------------------------------------------------------------------------
    // Wird jedes Mal aufgerufen, wenn die Anwendung eine Nachricht erhält
    //--------------------------------------------------------------------------------------
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    
    	PAINTSTRUCT ps;
    	HDC hdc;
    	switch (message)
    	{
    	case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    
    		//Ausgabe von Text---------------------------
    
    		SetTextColor(hdc, RGB(220, 100, 0));
    		TextOut(hdc, 10, 10, TEXT("Hallo ihr futzies"), 17);
    
    		//--------------------------------------------
    		EndPaint(hWnd, &ps);
    		break;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    
    	return 0;
    }
    
    //-----3---------------------------------------------------------------------------------
    // Register class and create window
    //--------------------------------------------------------------------------------------
    HRESULT FensterInit(HINSTANCE hInstance, int nCmdShow)
    {
    	//// Register class
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    	wcex.style = CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc = WndProc;
    	wcex.cbClsExtra = 0;
    	wcex.cbWndExtra = 0;
    	wcex.hInstance = hInstance;
    	wcex.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));									//ICON im Fenster wenn ALT+TAB verwendet wird
    	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
    	wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
    	wcex.lpszClassName = L"TutorialWindowClass";
    	wcex.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0); //ICON links oben im Fenster
    	if (!RegisterClassEx(&wcex))
    	{
    		MessageBox(0, L"Windows Klasse konnte nicht Registriert werden!", L"Meine App", MB_OK);
    
    		return 0;
    	}
    
    	// Create window
    	g_hInst = hInstance;
    	RECT rc = { 0, 0, 640, 480 };
    	AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
    	g_hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"TutorialWindowClass", L"Direct3D Version 11 Tutorial 1", WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
    	if (!g_hWnd)
    	{
    		MessageBox(0, L"Windows konnte das Fenster nicht erzeugen!", L"Meine App", MB_OK);
    		return E_FAIL;
    	}
    	//Fenster wird angezeigt
    	ShowWindow(g_hWnd, nCmdShow);
    
    	return S_OK;
    }
    
    //-------5-------------------------------------------------------------------------------
    // Create Direct3D device and swap chain
    //--------------------------------------------------------------------------------------
    HRESULT GeräteInit()
    {
        static HRESULT hr = S_OK;
    	static RECT rc;											//Die RECT-Struktur definiert die Koordinaten der oberen linken und unteren rechten Ecke eines Rechtecks.
        GetClientRect( g_hWnd, &rc );
        UINT width = rc.right - rc.left;
        UINT height = rc.bottom - rc.top;
    
        UINT createDeviceFlags = 0;
    #ifdef _DEBUG
        createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif
    
        D3D_DRIVER_TYPE driverTypes[] =
        {
            D3D_DRIVER_TYPE_HARDWARE,
            D3D_DRIVER_TYPE_WARP,
            D3D_DRIVER_TYPE_REFERENCE,
        };
        UINT numDriverTypes = ARRAYSIZE( driverTypes );
    
        D3D_FEATURE_LEVEL featureLevels[] =
        {
            D3D_FEATURE_LEVEL_11_0,
            D3D_FEATURE_LEVEL_10_1,
            D3D_FEATURE_LEVEL_10_0,
        };
    	UINT numFeatureLevels = ARRAYSIZE( featureLevels );
    
    	DXGI_SWAP_CHAIN_DESC sd;
        ZeroMemory( &sd, sizeof( sd ) );
        sd.BufferCount = 1;
        sd.BufferDesc.Width = width;
        sd.BufferDesc.Height = height;
        sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
        sd.BufferDesc.RefreshRate.Numerator = 60;
        sd.BufferDesc.RefreshRate.Denominator = 1;
        sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
        sd.OutputWindow = g_hWnd;
        sd.SampleDesc.Count = 1;
        sd.SampleDesc.Quality = 0;
        sd.Windowed = TRUE;
    
        for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
        {
            g_driverType = driverTypes[driverTypeIndex];
            hr = D3D11CreateDeviceAndSwapChain(NULL, g_driverType, NULL, createDeviceFlags, featureLevels, numFeatureLevels,
                                                D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &g_featureLevel, &g_pImmediateContext );
            if( SUCCEEDED( hr ) )
                break;
        }
        if( FAILED( hr ) )
            return hr;
    
        // Create a render target view
        ID3D11Texture2D* pBackBuffer = NULL;
        hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), ( LPVOID* )&pBackBuffer );
        if( FAILED( hr ) )
            return hr;
    
        hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );
        (*pBackBuffer).Release();
        if( FAILED( hr ) )
            return hr;
    
        (*g_pImmediateContext).OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
    
        // Einrichten der Kamera 
        D3D11_VIEWPORT vp;
        vp.Width = (FLOAT)width;
        vp.Height = (FLOAT)height;
        vp.MinDepth = 0.0f;
        vp.MaxDepth = 1.0f;
        vp.TopLeftX = 0;
        vp.TopLeftY = 0;
        g_pImmediateContext->RSSetViewports( 1, &vp );
    
        return S_OK;
    }
    //--------6------------------------------------------------------------------------------
    // Frame wird Gerändert
    //--------------------------------------------------------------------------------------
    void FrameRender()
    {
    	// "backbuffer" wird geleert 
    	float ClearColor[4] = { 0.3f, 0.125f, 0.3f, 1.0f };	//red,green,blue,alpha->AbstandzurKamera (Hintergrundfarbe)
    		(*g_pImmediateContext).ClearRenderTargetView(g_pRenderTargetView, ClearColor);
    		(*g_pSwapChain).Present(0, 0);                       // Präsentieren Sie unseren Rückenpuffer zu unserem Frontpuffer
    }
    //--------7------------------------------------------------------------------------------
    // Grafikkarte wird geleert und Heruntergefahren
    //--------------------------------------------------------------------------------------
    void Gerätherunterfahren()
    {
    	if (g_pImmediateContext) (*g_pImmediateContext).ClearState();
    	if (g_pRenderTargetView) (*g_pRenderTargetView).Release();
    	if (g_pSwapChain) (*g_pSwapChain).Release();
    	if (g_pImmediateContext) (*g_pImmediateContext).Release();
    	if (g_pd3dDevice) (*g_pd3dDevice).Release();
    }
    

  • Mod

    Eine Variante zum Start könnte so aussehen (ungetestet):
    Stichwort RAII. Ungarische Notation kann auch vergessen werden. Wir leben nicht mehr in den 80ern.
    Klassen sind ein guter Ausgangspunkt für die Aufteilung in separate Übersetzungseinheiten.

    #include <iterator>
    #include <string>
    #include <d3d11.h>
    
    // A. Alexandrescu's ScopeGuard
    template <class Fun>
    class ScopeGuard {
        Fun f_;
        bool active_ = true;
    public:
        ScopeGuard() = delete;
        ScopeGuard(const Fun& f) noexcept : f_(f) {}
        ScopeGuard(Fun&& f)      noexcept : f_(std::move(f)) {}
        ScopeGuard(const ScopeGuard&) = delete;
        ScopeGuard(ScopeGuard&& other) noexcept
            : f_(std::move(f)), active_(other.active_)
        {
            other.dismiss();
        }
        ScopeGuard& operator=(const ScopeGuard&) = delete;
        ScopeGuard& operator=(ScopeGuard&&) = delete;
        ~ScopeGuard() noexcept(noexcept(f_()))
        {
            if (active_)
                f_();
        }
        void dismiss() noexcept { active_ = false; }
    };
    
    enum class ScopeGuardOnExit {};
    
    template <typename Fun>
    auto operator+(ScopeGuardOnExit, Fun&& fn) noexcept {
        return ScopeGuard<Fun>(std::forward<Fun>(fn));
    }
    
    #define SCOPE_GUARD_CONCATENATE_IMPL(s1, s2) s1##s2
    #define SCOPE_GUARD_CONCATENATE(s1, s2) SCOPE_GUARD_CONCATENATE_IMPL(s1, s2)
    #ifdef __COUNTER__
    #define SCOPE_GUARD_ANONYMOUS_VARIABLE(str) SCOPE_GUARD_CONCATENATE(str, __COUNTER__)
    #else
    #define SCOPE_GUARD_ANONYMOUS_VARIABLE(str) SCOPE_GUARD_CONCATENATE(str, __LINE__)
    #endif
    
    #define SCOPE_EXIT auto SCOPE_GUARD_ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) = ::ScopeGuardOnExit() + [&]()
    
    //Windows Script Definitionen
    enum
    {
        ID_ICON_SMALL = 1,
        IDI_MYICON = 2,
        IDR_MYMENU = 3
    };
    
    class msgbox_exception : public std::runtime_error
    {
    public:
        explicit msgbox_exception(std::wstring text, std::wstring  = L"Meine App")
        : std::runtime_error("msgbox_exception"), text(std::move(text)), caption(std::move(caption))
        {}
    
        void show() const noexcept {
            MessageBox(0, text.data(), caption.data(), MB_OK);
        }
    private:
        std::wstring text;
        std::wstring caption;
    };
    
    class WindowContext {
    public:
        WindowContext(HINSTANCE appHandle, int show_cmd)
        : windowHandle(), windowClass()
        {
            windowClass.cbSize = sizeof(windowClass);
            windowClass.style = CS_HREDRAW | CS_VREDRAW;
            windowClass.lpfnWndProc = WndProc;
            windowClass.cbClsExtra = 0;
            windowClass.cbWndExtra = 0;
            windowClass.hInstance = appHandle;
            //ICON im Fenster wenn ALT+TAB verwendet wird
            windowClass.hIcon = LoadIcon(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_MYICON));
            windowClass.hCursor = LoadCursor(nullptr, IDC_ARROW);
            windowClass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
            windowClass.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU);
            windowClass.lpszClassName = L"TutorialWindowClass";
            //ICON links oben im Fenster
            windowClass.hIconSm = (HICON)LoadImage(GetModuleHandle(nullptr), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0);
            if (!RegisterClassEx(&windowClass))
                throw msgbox_exception(L"Window Klasse konnte nicht Registriert werden!");
    
            // Create window
            RECT rc = { 0, 0, 640, 480 }; // magic numbers, yeah!
            AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE);
            windowHandle = CreateWindowEx(WS_EX_CLIENTEDGE, L"TutorialWindowClass", L"Direct3D Version 11 Tutorial 1",
                WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr,
                appHandle, nullptr);
            if (!windowHandle)
                throw msgbox_exception(L"Windows konnte das Fenster nicht erzeugen!");
    
            //Fenster wird angezeigt
            ShowWindow(windowHandle, show_cmd);
        }
    
        HWND getWindowHandle() const noexcept
        {
            return windowHandle;
        }
    private:
        static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
        {
            PAINTSTRUCT ps;
            HDC hdc;
            switch (message)
            {
            case WM_PAINT:
                hdc = BeginPaint(hWnd, &ps);
    
                //Ausgabe von Text---------------------------
    
                SetTextColor(hdc, RGB(220, 100, 0));
                TextOut(hdc, 10, 10, TEXT("Hallo ihr futzies"), 17);
    
                //--------------------------------------------
                EndPaint(hWnd, &ps);
                break;
    
            case WM_DESTROY:
                PostQuitMessage(0);
                break;
    
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
    
            return 0;
        }
    
        HWND windowHandle;
        WNDCLASSEX windowClass;
    };
    
    class D3dDeviceContext
    {
    public:
        D3dDeviceContext(const D3dDeviceContext&) = delete;
        D3dDeviceContext(D3dDeviceContext&&) = delete;
        D3dDeviceContext& operator=(const D3dDeviceContext&) = delete;
        D3dDeviceContext& operator=(D3dDeviceContext&&) = delete;
    
        explicit D3dDeviceContext(HWND windowHandle)
        {
            //Die RECT-Struktur definiert die Koordinaten der oberen linken und unteren rechten Ecke eines Rechtecks.
            RECT windowRect{};
            if (!GetClientRect(windowHandle, &windowRect))
                throw msgbox_exception(L"oops!");
            width = windowRect.right - windowRect.left;
            height = windowRect.bottom - windowRect.top;
    
            UINT createDeviceFlags = 0;
    #ifdef _DEBUG
            createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
    #endif
    
            static constexpr D3D_FEATURE_LEVEL featureLevels[] =
            {
                D3D_FEATURE_LEVEL_11_0,
                D3D_FEATURE_LEVEL_10_1,
                D3D_FEATURE_LEVEL_10_0,
            };
    
            DXGI_SWAP_CHAIN_DESC sd{};
            sd.BufferCount = 1;
            sd.BufferDesc.Width = width;
            sd.BufferDesc.Height = height;
            sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
            sd.BufferDesc.RefreshRate.Numerator = 60;
            sd.BufferDesc.RefreshRate.Denominator = 1;
            sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
            sd.OutputWindow = windowHandle;
            sd.SampleDesc.Count = 1;
            sd.SampleDesc.Quality = 0;
            sd.Windowed = TRUE;
    
            for (auto dt : { D3D_DRIVER_TYPE_HARDWARE, D3D_DRIVER_TYPE_WARP, D3D_DRIVER_TYPE_REFERENCE })
            {
                if (S_OK == D3D11CreateDeviceAndSwapChain(nullptr, dt, nullptr, createDeviceFlags, featureLevels,
                    std::size(featureLevels), D3D11_SDK_VERSION, &sd, &swapChain, &d3dDevice, &featureLevel, &immediateContext))
                {
                    driverType = dt;
                    return;
                }
            }
            throw msgbox_exception(L"Fehler! Geräte Initialisierung");
        }
    
        ~D3dDeviceContext() noexcept
        {
            immediateContext->ClearState();
            swapChain->Release();
            immediateContext->Release();
            d3dDevice->Release();
        }
    
        D3D_DRIVER_TYPE getDriverType() const noexcept
        {
            return driverType;
        }
    
        D3D_FEATURE_LEVEL getFeatureLevel() const noexcept
        {
            return featureLevel;
        }
    
        ID3D11Device* getD3dDevice() const noexcept
        {
            return d3dDevice;
        }
    
        ID3D11DeviceContext* getImmediateContext() const noexcept
        {
            return immediateContext;
        }
    
        IDXGISwapChain* getSwapChain() const noexcept
        {
            return swapChain;
        }
    
        UINT getWidth() const noexcept
        {
            return width;
        }
    
        UINT getHeight() const noexcept
        {
            return height;
        }
    private:
        D3D_DRIVER_TYPE         driverType;
        D3D_FEATURE_LEVEL       featureLevel;
        ID3D11Device*           d3dDevice;
        ID3D11DeviceContext*    immediateContext;
        IDXGISwapChain*         swapChain;
        UINT                    width;
        UINT                    height;
    };
    
    class D3dContext : private D3dDeviceContext
    {
    public:
        D3dContext(const D3dContext&) = delete;
        D3dContext(D3dContext&&) = delete;
        D3dContext& operator=(const D3dContext&) = delete;
        D3dContext& operator=(D3dContext&&) = delete;
    
        explicit D3dContext(HWND windowHandle)
        : D3dDeviceContext(windowHandle)
        {
            {
                // Create a render target view
                void* backBuffer_as_void_ptr = nullptr;
                if (S_OK != getSwapChain()->GetBuffer(0, __uuidof(ID3D11Texture2D), &backBuffer_as_void_ptr))
                    throw msgbox_exception(L"Fehler! D3dContext Initialisierung (swapChain->GetBuffer)");
    
                auto backBuffer = static_cast<ID3D11Texture2D*>(backBuffer_as_void_ptr);;
                SCOPE_EXIT{ backBuffer->Release(); };
    
                if (S_OK != getD3dDevice()->CreateRenderTargetView(backBuffer, nullptr, &renderTargetView))
                    throw msgbox_exception(L"Fehler! D3dContext Initialisierung (d3dDevice->CreateRenderTargetView)");
            }
    
            getImmediateContext()->OMSetRenderTargets(1, &renderTargetView, nullptr);
    
            // Einrichten der Kamera
            D3D11_VIEWPORT vp{};
            vp.Width = static_cast<FLOAT>(getWidth());
            vp.Height = static_cast<FLOAT>(getHeight());
            vp.MinDepth = 0.0f;
            vp.MaxDepth = 1.0f;
            vp.TopLeftX = 0;
            vp.TopLeftY = 0;
            getImmediateContext()->RSSetViewports(1, &vp);
        }
    
        ~D3dContext() noexcept
        {
            getImmediateContext()->ClearState();
            renderTargetView->Release();
        }
    
        using D3dDeviceContext::getDriverType;
        using D3dDeviceContext::getFeatureLevel;
        using D3dDeviceContext::getD3dDevice;
        using D3dDeviceContext::getImmediateContext;
        using D3dDeviceContext::getSwapChain;
        using D3dDeviceContext::getHeight;
        using D3dDeviceContext::getWidth;
    
        ID3D11RenderTargetView* getRenderTargetView() const noexcept
        {
            return renderTargetView;
        }
    private:
        ID3D11RenderTargetView* renderTargetView;
    };
    
    void FrameRender(D3dContext& context)
    {
        // "backbuffer" wird geleert
        float ClearColor[4] = { 0.3f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alpha->AbstandzurKamera (Hintergrundfarbe)
        context.getImmediateContext()->ClearRenderTargetView(context.getRenderTargetView(), ClearColor);
        context.getSwapChain()->Present(0, 0);  // Präsentieren Sie unseren Rückenpuffer zu unserem Frontpuffer
    }
    
    int WINAPI wWinMain(HINSTANCE appHandle, HINSTANCE /*hPrevInstance*/, LPWSTR /*lpCmdLine*/, int showCmd)
    {
        try
        {
            WindowContext appWindow(appHandle, showCmd);
    
            D3dContext graphicContext(appWindow.getWindowHandle());
    
            // Haupt Nachrichtenschleife
            MSG msg{};
            while (WM_QUIT != msg.message)
            {
                if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
                else
                {
                    FrameRender(graphicContext);
                }
            }
    
            return static_cast<int>(msg.wParam);
        }
        catch (const msgbox_exception& e)
        {
            e.show();
            return 0;
        }
    }
    


  • Ja Super Waaaahnnnsinn ! Du hast das alles mal kurz umgeschrieben und es Funktioniert auf ANHIEB !!!!

    Ich bin überwältigt. Aber ein paar Fragen habe ich nun doch noch zu der Notation.

    Anfängerfragen:

    1. Ich bin jetzt in der Laage die Klassen aus meinem Projekt in andere Dateien zu exportieren ( Richtig oder Falsch ? )
    2. Ist das nun eine Moderne Art um Windows Programme zu Sortieren ( Ja/oder Nein ? )
    3. Was gibt es noch für andere Notationen und wo finde ich diese im "WWW" ?
    4. Es gibt viele Funktionsüberladungen im Programm. Sind diese wirklich notwendig ?
    5. Wenn diese Notation Modern ist, hat sie besondere Vorteile in der Speicherressourcen verwaltung ?
    6. Ach so ja und allgemein Gefragt wo finde ich Informationen über das Windows Script ??

    z.B

    enum
    {
    	ID_ICON_SMALL = 1,
    	IDI_MYICON = 2,
    	IDR_MYMENU = 3
    };
    

    Würde mich noch Sehr über die Beantwortung der Fragen freuen 😉


  • Mod

    TippoMax5 schrieb:

    1. Ich bin jetzt in der Laage die Klassen aus meinem Projekt in andere Dateien zu exportieren ( Richtig oder Falsch ? )

    Klassendefinitionen gehören nat. im Allgemeinen in Header. Die Funktionen (die ich jetzt der Bequemlichkeit halber einfach innerhalb der Klassendefinitionen definiert habe) können nat. in anderen .cpp-Datein landen.

    TippoMax5 schrieb:

    2. Ist das nun eine Moderne Art um Windows Programme zu Sortieren ( Ja/oder Nein ? )

    k.A., bin kein Windowsprogrammierer. Kommt auch drauf an, was "modern" bedeutet. Wenn es das ist, was jeder macht, dann wahrscheinlich: nein (weil die Mehrheit erfahrungsgemäß träge und lernresistent ist).

    TippoMax5 schrieb:

    3. Was gibt es noch für andere Notationen und wo finde ich diese im "WWW" ?

    +Referenzen

    TippoMax5 schrieb:

    4. Es gibt viele Funktionsüberladungen im Programm. Sind diese wirklich notwendig ?

    Überladungen sehe ich keine. Wenn du nur die vielen kleinen Zugrissfunktionen meinst. Die sind sicher für das minimale Beispiel selbst nicht erforderlich. Als Ausgangspunkt für die Programmerweiterung: absolut. Es sei denn, du magst stundenlanges Debuggen nur um Fehler zu finden, auf die dich auch der Compiler hätte bringen können.

    TippoMax5 schrieb:

    5. Wenn diese Notation Modern ist, hat sie besondere Vorteile in der Speicherressourcen verwaltung ?

    Ich sehe keine Verbindung.

    6. Ach so ja und allgemein Gefragt wo finde ich Informationen über das Windows Script ??

    z.B

    enum
    {
    	ID_ICON_SMALL = 1,
    	IDI_MYICON = 2,
    	IDR_MYMENU = 3
    };
    

    k.A., MSDN nehme ich mal stark an. Das habe ich schliesslich nur übernommen.


Anmelden zum Antworten