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 INTRedest 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 INTRedest 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 offenDas 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?