Direct3D9 Initialisierung



  • @TGGC
    du hast schon so viele Spiele programmiert. Du wirst doch alleine ein Quake Clone zustande bringen. tztztz.

    Kauf dir erst mal das neuste Buch von SZ. Da steht alles über Indoorgames.

    🙄



  • Hab das was ich gesucht habe jetzt doch noch in dem Tutorial vom SDK gefunden,
    aber bei deren Code ist das echt schwer durchzublicken, wer verwendet bitte
    für int und void makros à la VOID und INT 😮

    Redest du von diesem Buch ?



  • SirLant schrieb:

    Hab das was ich gesucht habe jetzt doch noch in dem Tutorial vom SDK gefunden,
    aber bei deren Code ist das echt schwer durchzublicken, wer verwendet bitte
    für int und void makros à la VOID und INT 😮

    Redest du von diesem Buch ?

    Du hast Recht. Woher soll man auch wissen das mit VOID, void gemeint sein soll.



  • @TGGC: Ich empfehle dir, ein paar Tutorials über Direct3D durchzumachen und dann würde ich versuchen, das Ganze selber in Klassen zu packen und zu kapseln. Damit hast du eine auf dich zugeschnittene Lösung, die einfach zu bedienen ist und die du trotzdem verstehst.
    Dann wirds auch was mit dem Quake. 😉 😃
    Naja, vielleicht kommts ja beim richtigen an... 🙄

    btw. VOID und INT sind keine Makros. Voraussetzung ist, dass man solche Grundlegenden Begriffe und sinnvollerweise auch Objektorientierung versteht.



  • Sicher? Das INT gebe ich ja noch zu, aber das VOID kannst du nicht abstreiten.

    // WINNT.H
    #define VOID void
    
    // WINDEF.H
    typedef int                 INT;
    


  • Das ist doch kein Makro.



  • Optimizer schrieb:

    Das ist doch kein Makro.

    In Assembler-Code ist ein Makro ein Codeblock, der noch vor der Compilierung anstatt des Makro-Namens in den Code eingesetzt wird.
    Genau das geschieht hier auch.
    Was ist denn Deiner Meinung nach ein Makro?!? 😕
    Oder spielst Du darauf an, daß keine Parameter benutzt werden?



  • Gut also schön, dann ist VOID eben als einzige Ausnahme gegenüber LONG, DWORD, INT, FLOAT ein Makro. 🙄
    Und trotzdem hat es keinen anderen Effekt als eine Typdefinition.



  • Optimizer schrieb:

    Und trotzdem hat es keinen anderen Effekt als eine Typdefinition.

    Hat auch niemand behauptet... 🙄



  • Letzte Nacht hab ich mit Hilfe meines Buches, der DirectX Hilfe und nem Tut von Stefan Zerbst
    das mit der Initialisierung hinbekommen bzw. meine eigene Klasse dafür geschrieben.

    Da der Zerbst aber in seinem Beispiel ein globales Objekt verwendet, gefällt mir
    das nicht so, allerdings wüsst ich jetzt auch nicht wie ich das ändern kann, da
    sowohl die winmain als auch die msgproc auf die Daten zugreift. Man muss wohl das
    ganze System ändern, nur weiß ich nicht wie.
    Wäre daher für Ratschläge offen 🙂

    Das ganze ist wohl so gemacht, damit man über ESC das Programm beenden kann und
    das würd ich gern so lassen. Es geht um das globale Objekt g_set.

    #include <windows.h>
    #include <d3d9.h>
    #include <tribase.h>
    #include "dxInit.h"
    
    // Dieses Objekt meine ich
    mode g_set; // Einstellungen für Dircect3D
    
    // Ist die Idee so gut? Also, dass ich die Klasse erbe und die Render sowie Move
    // Funktion definiere? Wollte zuerst Funktionszeiger benutzen, diese könen aber
    // Nicht auf die internen Daten zugreifen.
    class DX_App : public dxInit {
    	public:
    
    		virtual void move (float time) {
    			// nothing
    		}
    
    		virtual HRESULT render (float time) {
    			_pDevice->Clear(0, NULL, 
                        D3DCLEAR_TARGET |
                        D3DCLEAR_ZBUFFER, 
                        D3DCOLOR_XRGB(0,0,0), 
                        1.0f, 0);
    
    			 _pDevice->BeginScene();
    
    				// Nothing
    
    			 _pDevice->EndScene();
    
    			if (FAILED(_pDevice->Present(NULL,NULL,NULL, NULL)))
    				 return E_FAIL;
    
    			 return S_OK;
    		}
    };
    
    LRESULT WINAPI MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
       switch(msg) {
    
          case WM_ACTIVATE: {
             g_set.IsActive = (BOOL)wParam;
             } break;
    
          case WM_KEYDOWN: {
             switch (wParam) {
                case VK_ESCAPE: {
                   g_set.done = true;
                   PostMessage(hwnd, WM_CLOSE, 0, 0);
                   return 0;
                   } break;
                }
             } break;
    
          case WM_DESTROY: {
             g_set.done = true;
             PostQuitMessage(0);
             return 1;
             } break;
          default: break;
          }
       return DefWindowProc(hwnd,msg,wParam,lParam);
    } // MsgProc
    
    int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, 
                       LPSTR lpCmdLine, int nCmdShow) {
       WNDCLASSEX wndclass;
       TCHAR szAppClass[] = TEXT("Pyramide");
       MSG msg;
    
       DX_App MyApp; 
    
       wndclass.cbSize = sizeof(wndclass);
       wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
       wndclass.lpfnWndProc = MsgProc;
       wndclass.cbClsExtra = 0;
       wndclass.cbWndExtra = 0;
       wndclass.hInstance = hInst;
       wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
       wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
       wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
       wndclass.lpszMenuName = NULL;
       wndclass.lpszClassName = szAppClass;
       wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    
       if (RegisterClassEx(&wndclass)==0) return 0;
    
       if (!(g_set.hwnd=CreateWindowEx(NULL, szAppClass,
                      "Pyramide",
                      WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                      GetSystemMetrics(SM_CXSCREEN)/2-250,
                      GetSystemMetrics(SM_CYSCREEN)/2-187,
                      500, 375, NULL, NULL, hInst, NULL)))
          return 0;
    
       ShowWindow(g_set.hwnd, SW_HIDE);
    
       g_set.IsActive = false;
       g_set.done     = false;
    
       // windowed or fullscreen mode?
       if (MessageBox(g_set.hwnd, "Start in windowed mode?", 
            "Pyramide", MB_YESNO|MB_ICONINFORMATION)==IDNO)
          g_set.windowed = false;
       else g_set.windowed = true;
    
       if ( FAILED( MyApp.Init(g_set) )) {
          MessageBox(g_set.hwnd, "Initializing Application_C failed.", 
              "Pyramide", MB_OK|MB_ICONERROR);
          g_set.done = true;
          }
       else ShowWindow(g_set.hwnd, SW_SHOW);
    
       while (!g_set.done) {
          while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
             TranslateMessage(&msg);
             DispatchMessage(&msg);
             }
          if (g_set.IsActive) MyApp.Tick();
          }
    
       MyApp.Release();
       UnregisterClass(szAppClass, hInst);
       return (int)msg.wParam;
    } // WinMain
    

    Danke 🙂



  • Tja, hättest vielleicht erst garnicht mit dem copy'n'paste angefangen sollen?

    Bye, TGGC (Der Held ist zurück)



  • SirLant schrieb:

    Da der Zerbst aber in seinem Beispiel ein globales Objekt verwendet, gefällt mir das nicht so, allerdings wüsst ich jetzt auch nicht wie ich das ändern kann

    z.B. mit nen singleton

    SirLant schrieb:

    // Ist die Idee so gut? Also, dass ich die Klasse erbe und die Render sowie Move
    // Funktion definiere? Wollte zuerst Funktionszeiger benutzen, diese könen aber
    // Nicht auf die internen Daten zugreifen.
    class DX_App : public dxInit {
    	public:
    
    		virtual void move (float time) {
    			// nothing
    		}
    
    		virtual HRESULT render (float time) {
    			_pDevice->Clear(0, NULL, 
                        D3DCLEAR_TARGET |
                        D3DCLEAR_ZBUFFER, 
                        D3DCOLOR_XRGB(0,0,0), 
                        1.0f, 0);
    
    			 _pDevice->BeginScene();
    
    				// Nothing
    
    			 _pDevice->EndScene();
    
    			if (FAILED(_pDevice->Present(NULL,NULL,NULL, NULL)))
    				 return E_FAIL;
    
    			 return S_OK;
    		}
    };
    

    Nein. Die Idee ist meiner Meinung nach schrecklich! Vorallem weil du die Klasse dann auch noch die Main Datei deklarierst bzw. definierst! Ich würde 2 getrennte Objekte verwenden.

    Du solltest vielleicht erst mal richtig OOP lernen und erst dann mit DirectX anfangen.

    Buch:
    Objektorientierte Programmierung für Dummies | ISBN: 3826629841



  • Das Buch hab ich schon gelesen, deswegen hab ich ja auch gefragt ob das so gut
    ist, weil nen Buch lesen und nacher auch alles sauber zu coden sind zweierlei.
    Wie meinst du mit nem Singleton? Dass ich nur eine Instanz haben darf in der
    Anwendung ist klar, aber ich brauche ja trotzdem meine beiden Methoden um was
    auf den Bildschirm zu bringen und zu verändern.



  • Welche Daten brauchst du denn (angeblich) überall(also global)?

    Bye, TGGC (Der Held ist zurück)



  • Global ja nicht wirklich, ich brauch ja nur Zugriff auf LPDIRECT3D9 und LPDIRECT3DDEVICE9 für die Render-Funktion. Für Sachen wie Material usw. kann ich ja Factory-Klassen benutzen.



  • Also warum hast du es global gemacht, wenn es nicht global gebraucht wird?

    Bye, TGGC (Der Held ist zurück)



  • Die sind nicht global, in der Struktur g_set steht folgendes:

    struct mode {
    	HWND hwnd;  // Window Handle
    	bool done; // Abbruchkriterium
    	bool windowed; // Fenstermodus?
    	BOOL IsActive; // Focus ?
    };
    

    Das was die Klasse dxInit braucht ist nur das Windows-Handle und die Init-Methode
    noch die Variable windowed, könnte ich also auch direkt übergeben.

    Deklaration von dxInit:

    class dxInit {
    	public:
    		dxInit (void); // constructor
    		virtual ~dxInit (void); // destructor
    
    		HRESULT Init (const mode & settings); // initialisierung von DirectX
    		HRESULT Tick (float time = 0.0f); // Timer
    		void Release (void); // Geräteschnittstelle freigeben
    
    	protected:
    		LPDIRECT3D9 _pD3D; //
    		LPDIRECT3DDEVICE9 _pDevice; // Geräteschnittstelle
    		D3DPRESENT_PARAMETERS _PP; // Einstellungen für die Schnittstelle
    		HWND _hwnd; // Window Handle
    		virtual void move (float time) = 0; // Neu Berechnen und Positionieren
    		virtual HRESULT render (float time) = 0; // Rendern
    };
    

    Das einzige was danach noch global wäre, wären die Variablen für den ESC-Tastendruck
    um das Programm zu beenden. Und diese würd ich gerne losbekommen, aber die
    werden in winmain und der winprc benutzt



  • Also hab ich es jetzt richtig verstanden? Das einzige was global ist und weg
    soll ist eine Variable für den ESC Druck?

    Bye, TGGC (Der Held ist zurück)



  • Genau das ist alles.



  • Wieso sind eigentlich am gleichen Tag 2 Threads mit DirectX Initialisierung als Thema entstanden? 😕


Anmelden zum Antworten