Denkproblem mit IDirect3DDevice9
-
Ich habe den Fehler gefunden, ich musste das lightning ausstellen. Allerdings bleiben mir da noch eine Frage. Wenn ich diesen Code benutze
void Draw() { d3dd->Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); d3dd->BeginScene(); d3dd->SetFVF(CUSTOMFVF); D3DXMATRIX matWorld; D3DXMatrixIdentity(&matWorld); d3dd->SetTransform(D3DTS_WORLD, &matWorld); D3DXMATRIX matView; D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3 (0.0f, 0.0f, 1.0f), &D3DXVECTOR3 (0.0f, 0.0f, 0.0f), &D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); d3dd->SetTransform(D3DTS_VIEW, &matView); D3DXMATRIX matProjection; D3DXMatrixOrthoOffCenterLH(&matProjection, 0.0f, width, 0.0f, height, 0.0f, 1.0f); d3dd->SetTransform(D3DTS_PROJECTION, &matProjection); d3dd->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); d3dd->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); d3dd->EndScene(); d3dd->Present(0, 0, 0, 0); }
müssen alle x-Koordinaten im negativen Bereich sein, damit man sie sehen kann. Die y-Koordinaten müssen aber positiv sein. Wie kann ich das ändern, damit auch die x-Koordinaten im positiven Bereich sein müssen?
-
Du meinst wohl die z-Koordinaten!? Nun, überleg dir einfach mal wo deine Kamera ist und wo sie hinschaut...
@hustbaer: Natürlich ist das immer eine Frage auf welcher Ebene du wie abstrahieren willst und dein Ansatz ist sicherlich eine gute Lösung. Ich setze meine Abstraktionsschicht normalerweise erst etwas höher an. Mein Ressourcenmanagement läuft über RAII, darum brauch ich keine Managerklasse die sich ums Aufräumen kümmert. Device Loss ist natürlich ein Argument in D3D9, da ich kaum noch D3D9 verwende bin ich da in der glücklichen Lage mich nicht wirklich drum kümmern zu müssen. Aber in dem Fall kommt man dann wohl kaum umhin eine zentrale Stelle zu haben die alle Objekte kennt und dann ein OnDeviceReset aufruft. Eine solche Stelle hat man normalerweise aber so oder so, nämlich jenes Objekt das sich ums Rendern und Presenten kümmert. Ich habe dazu üblicherweise ein Renderer Objekt das alle Fenster/Displays verwaltet. Für mich funktioniert das bisher ganz gut, dein Design ist allerdings natürlich auf einer anderen Ebene viel allgemeiner gehalten.
-
Nein ich meine die X-Koordinaten. Wenn ich diese Vektoren benutze
CUSTOMVERTEX vertices[] = { { -100.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(0, 0, 255), }, { -25.0f, 0.0f, 0.0f, D3DCOLOR_XRGB(0, 255, 0), }, { -50.0f, 50.0f, 0.0f, D3DCOLOR_XRGB(255, 0, 0), }, };
sehe ich die Eckpunkte im Fenster an den stellen 100|0 25|0 50|50
Aber der zweite Teil deiner Antwort hats gelöst, statt auf der z-Position 1.0f zu liegen muss die Kamera au der z-Position -1.0f liegen. Ich habe es vorher nur mit RH statt LH versucht, und dabei kam dann eben nichts bei raus.
-
Achso, sry hab deine Projektionsmatrix übersehen. Naja, ist doch klar, du verwendest D3DXMatrixOrthoOffCenterLH() und spezifizierst dass du den Bereich von x=0..width bzw y=0..height sehen willst. Nachdem deine Kamera von (0 0 1) aus entgegen die z-Achse blickt ist das genau der Bereich von x=0..-width und y=0..height!?
-
Ich habe noch ein Problem mit den Fullscreen Modus, ich habe jetzt schon ca. 10 verschiedene Beispiele ausprobiert, aber jedes mal hängt sich bei mir
CreateDevice()
auf. Die Funktion gibt auch keinen Wert mehr zurück und der Task Manager sagt mir, dass das Programm nicht mehr reagiert. Hier mal ein Minimalbeispiel, bei dem genau das passiert:WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = StaticWndProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL, IDC_ARROW); // wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszClassName = L"WindowClass"; RegisterClassEx(&wc); hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our Direct3D Program", WS_EX_TOPMOST | WS_POPUP, 0, 0, width, height, NULL, NULL, hInstance, NULL); d3d = Direct3DCreate9(D3D_SDK_VERSION); D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.Windowed = FALSE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hWnd; d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; d3dpp.BackBufferWidth = width; d3dpp.BackBufferHeight = height; if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3dd))) { return false; }
Ich kann das ganze noch mit etlichen Funktionen etc. erweitern, aber das Problem bleibt immer dasselbe.
Der Fenstermodus funktioniert aber einwandfrei.
-
Debug Runtime aktivieren und Fehlermeldungen prüfen?
-
Ich hab den Debugger an, und dadurch auch rausgefunden, worans liegt. Aber wenn ich CreateDevice aufrufe muss auch der Debugger dran glauben, weil wirklich alles hängen bleibt und ich nurnoch alles gewaltsam über den Task Manager beenden kann.
-
Warum eigentlich D3DCREATE_SOFTWARE_VERTEXPROCESSING, hast du nur Intel Chipset Grafik oder so!? Ich bin mir ziemlich sicher dass sich der Debugger nicht aufhängt. Das Problem mit Fullscreen debuggen ist aber dass, wenn die Ausführung unterbrochen wird, dann dein fullscreen Window über dem Debugger liegt. Was du dann siehst ist zwar das darunterliegende Fenster (wegen Device loss) allerdings kannst du nicht mit ihm interagieren weil dein fullscreen Window im Weg ist (wenn du genau schaust kannst du sicher den Rahmen sehen). Debuggen von fullscreen Anwendungen geht nur gescheit mit einem zweiten Bildschirm.
-
dot schrieb:
Warum eigentlich D3DCREATE_SOFTWARE_VERTEXPROCESSING, hast du nur Intel Chipset Grafik oder so!?
Ist wie gesagt nur ein Minimalbeispiel. Ich wollte eben alle möglichen Fehlerquellen reduzieren.
Gibt es auch irgendeine möglichkeit gescheit ohne zweiten Bildschirm zu debuggen?
-
DirektIx schrieb:
Gibt es auch irgendeine möglichkeit gescheit ohne zweiten Bildschirm zu debuggen?
Jop, den Fenstermodus :p
-
Das bringt mir ja viel, weil da ja alles so klappt wie es soll
Was mich aber auch wundert ist, dass dieses Problem im Internet anscheinend gar nciht existiert und ich der einzige Idiot bin, bei dem ständig das Programm abkratzt.
-
Kannst ja mal versuchen über ne log Datei oder so rauszufinden wo es ca. abkackt...
-
Hab ich ja schon, das macht es bei CreateDevice. Aber ich bin schon weitergekommen... oder auch nicht. Jetzt läuft zwar alles, aber eine Menge Code wird übersprungen. Der Debugger sagt dann:
Der Haltepunkt wird momentan nicht erreicht. Mit dieser Zeile ist kein ausführbarer Code verbunden. Mögliche Ursachen: Präprozessordirektiven oder Compiler-/Linkeroptimierungen
Als Präprozessordirektive ist mir im moment nur WIN32_LEAN_AND_MEAN eingefallen, aber das ist es nicht. Optimierungen habe ich zum Test mal alle ausgestellt.
Hier ist der Code, die übersprungenen Codezeilen sind markiert:WNDCLASSEX wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = StaticWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(0,IDI_APPLICATION); wc.hCursor = LoadCursor(0,IDC_ARROW); wc.hbrBackground= 0; wc.lpszMenuName = 0; wc.lpszClassName= className; wc.hIconSm = 0; // registrate WindowClass if (!RegisterClassEx(&wc)) { std::cerr << "Window Klasse konnte nicht registriert werden" << std::endl; return false; } // Settings for fullscreen-mode if (fullscreen) { DEVMODE dmScreenSettings; ZeroMemory(&dmScreenSettings, sizeof(DEVMODE)); dmScreenSettings.dmSize = sizeof(DEVMODE); dmScreenSettings.dmPelsWidth = width; dmScreenSettings.dmPelsHeight = height; dmScreenSettings.dmBitsPerPel = bpp; dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; // change settings for fullscreen-mode if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { if (MessageBox(0,L"Fullscreen Modus wird von ihrer Grafikkarte\nnicht unterstützt! Fenstermodus benutzen?",L"PROBLEM", MB_YESNO|MB_ICONEXCLAMATION) == IDYES) { fullscreen = false; } else { MessageBox(0,L"Programm wird geschlossen!",L"ERROR",MB_OK|MB_ICONERROR); return false; } } } DWORD dwExStyle; DWORD dwStyle; if (fullscreen) { dwExStyle = WS_EX_APPWINDOW; dwStyle = WS_POPUP; } else { dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX; } //adjust windowsize RECT windowRect; windowRect.left = static_cast<long>(0); windowRect.top = static_cast<long>(0); windowRect.right = static_cast<long>(width); windowRect.bottom = static_cast<long>(height); AdjustWindowRectEx(&windowRect, dwStyle, false, dwExStyle); // bis hier läuft es, danach wird eine Menge übersprungen if (!(hWnd = CreateWindowExW( dwExStyle, className, title, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, GetSystemMetrics(SM_CXSCREEN) / 2 - width / 2, GetSystemMetrics(SM_CYSCREEN) / 2 - height / 2, fullscreen ? 0 : windowRect.right - windowRect.left, fullscreen ? 0 : windowRect.bottom - windowRect.top, 0, 0, hInstance, this))) { std::cerr << "Fenster konnte nicht erstellt werden" << std::endl; return false; } if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION))) { std::cerr << "Direct3D Interface konnte nicht erstellt werden" << std::endl; return false; } if (d3d->CheckDeviceType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, !init.fullscreen)) { std::cerr << "Benötigter Device Type nicht verfügar" << std::endl; return false; } D3DPRESENT_PARAMETERS d3dpp; ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.BackBufferWidth = width; d3dpp.BackBufferHeight = height; d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hWnd; d3dpp.Windowed = !fullscreen; if ((d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3dd)) != D3D_OK) { if ((d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &d3dd)) != D3D_OK) { if ((d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3dd)) != D3D_OK) { std::cerr << "Kann keinen Direct3D Device erstellen" << std::endl; return false; } } } // bis hier ist alles übersprungen, aber hier läuft es wieder weiter ShowWindow(hWnd,SW_SHOW); SetForegroundWindow(hWnd); SetFocus(hWnd);
-
Habe deinen Quellcode jetzt nicht gelesen, doch wenn das ganze im Fenstermodus klappt, im Vollbildmodus jedoch nicht, könnte das an der Auflösung liegen die du einstellst. Im Vollbildmodus musst du eine gültige Auflösung verwenden die von deiner Graphikkarte unterstützt wird, irgendwelche exotischen Dinge woe 500x500 könnten da zum Absturz führen.