Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

1

23.10.2013, 19:44

CreateSwapChain Problem

Hallo!
Ich habe ein Problem beim Erstellen eines zweiten SwapChains. Ich erstelle einen SwapChain ganz am Anfang. Wenn ich danach versuche einen zweiten SwapChain zu erstellen bekomme ich folgenden fehler in der Debugausgabe und als Fehlerbeschreibung:

Quellcode

1
2
3
4
5
6
7
ERROR:   Call m_pIDXGIFactory->CreateSwapChain throws error DXGI_ERROR_INVALID_C
ALL  Description: The application has made an erroneous API call that it had enough information to avoid. This error is intended to denote that the application
should be altered to avoid the error. Use of the debug version of the DXGI.DLL
will provide run-time debug output with further information.

// Ausgabe
DXGI ERROR: IDXGIFactory::CreateSwapChain: Must specify at least one buffer. [ MISCELLANEOUS ERROR #5: ]

Hier der Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
DXGI_SWAP_CHAIN_DESC sd;
    ZeroMemory(&sd, sizeof(DXGI_SWAP_CHAIN_DESC));

    sd.BufferDesc.Width  = (int)vSize.x;
    sd.BufferDesc.Height = (int)vSize.y;
    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    sd.BufferUsage  = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow = hWnd;
    sd.SwapEffect   = DXGI_SWAP_EFFECT_DISCARD;
    sd.Flags        = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
    sd.Windowed     = true;
    sd.SampleDesc.Count   = 1;
    sd.SampleDesc.Quality = 0;
    sd.BufferDesc.RefreshRate.Numerator = 60;
    sd.BufferDesc.RefreshRate.Denominator = 1;

    m_pSwapChain = NULL;

    HRESULT hResult = Direct3D::Instance().GetFactory()->CreateSwapChain(Direct3D::Instance().GetDevice(), &sd, &m_pSwapChain);
    if(FAILED(hResult))
        LOG_ERROR_DIRECTX("m_pIDXGIFactory->CreateSwapChain", hResult, NXE_ERROR);


Ich kann mir den Fehler nicht wirklich erklären. Danke im Voraus.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

2

23.10.2013, 20:51

sd.BufferCount = 1;

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

24.10.2013, 06:46

Jo, das steht ja da relativ eindeutig:

DXGI ERROR: IDXGIFactory::CreateSwapChain: Must specify at least one buffer. [ MISCELLANEOUS ERROR #5: ]

;)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

4

25.10.2013, 22:20

Oh mann. Danke! Da stand ich wohl etwas auf der Leitung.

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

5

27.10.2013, 21:37

Ich habe btw folgende Vorschläge um den Code zu verbessern:

1. Verwende nie ZeroMemory, lieber die Sprache ausnutzen:

C-/C++-Quelltext

1
2
DXGI_SWAP_CHAIN_DESC sd = { }; // C++98
DXGI_SWAP_CHAIN_DESC sd{ }; // C++11/14


2. Nutze C++-Casts, wir schreiben immerhin das Jahr 2013

C-/C++-Quelltext

1
2
sd.BufferDesc.Width  = static_cast<int>(vSize.x);
sd.BufferDesc.Height = static_cast<int>(vSize.y);


3. Nutze nullptr anstelle von NULL (ist ab VS2010 unterstützt)

C-/C++-Quelltext

1
m_pSwapChain = nullptr;


4. Nutze Smart-Pointer für COM-Objekte, falls du dies noch nicht tust (sieht nicht so aus). Das macht dir das Leben viel leichter.

5. Ich sehe ein Singleton, warum? :hmm:

Und zu D3D11: Du kannst beide Werte von RefreshRate auf 0 setzen, dann werden diese für dich gesetzt. :)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

27.10.2013, 22:13

1. Verwende nie ZeroMemory, lieber die Sprache ausnutzen:

C-/C++-Quelltext

1
2
DXGI_SWAP_CHAIN_DESC sd = { }; // C++98
DXGI_SWAP_CHAIN_DESC sd{ }; // C++11/14

Ich würde überhaupt das struct entweder gleich richtig initialisieren, oder nicht initialisieren und einfach alle Member setzen...

Und zu D3D11: Du kannst beide Werte von RefreshRate auf 0 setzen, dann werden diese für dich gesetzt. :)

Die Refresh Rate explizit auf 60 zu setzen, ist sogar eine eher schlechte Idee. Nicht jeder Monitor hat notwendigerweise eine Refresh Rate von exakt 60 Hz. Wenn die angegebene RefreshRate aber nicht exakt mit der des angeschlossenens Monitor übereinstimmt, kann DXGI z.B. im Fullscreen nicht Flippen, sondern muss Blitten. Daher: RefreshRate besser einfach leer lassen, sofern man keinen ganz speziellen Grund hat, tatsächlich eine ganz bestimmte Refresh Rate anzufordern... ;)

Edit: "Leer lassen" heißt in dem Fall natürlich, auf 0/1 bzw. 0/0 setzen...

Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von »dot« (27.10.2013, 22:21)


Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

7

27.10.2013, 22:44


3. Nutze nullptr anstelle von NULL (ist ab VS2010 unterstützt)

C-/C++-Quelltext

1
m_pSwapChain = nullptr;


Ich dachte, dass wäre eine managed Null-Referenz für C++/CLI. :hmm:
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

27.10.2013, 22:50

Ist es unter Visual C++ auch. Vor allem ist es aber das Standard-C++ Schlüsselwort, welches das Nullpointer Literal bezeichnet... ;)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
void f(int a);
void f(A* a);

// ...

f(0);
f(NULL);
f(nullptr);

// Welche der beiden Funktionen wird wann aufgerufen?

9

28.10.2013, 00:13

Die Refresh Rate explizit auf 60 zu setzen, ist sogar eine eher schlechte Idee. Nicht jeder Monitor hat notwendigerweise eine Refresh Rate von exakt 60 Hz. Wenn die angegebene RefreshRate aber nicht exakt mit der des angeschlossenens Monitor übereinstimmt, kann DXGI z.B. im Fullscreen nicht Flippen, sondern muss Blitten. Daher: RefreshRate besser einfach leer lassen, sofern man keinen ganz speziellen Grund hat, tatsächlich eine ganz bestimmte Refresh Rate anzufordern...

Ja, deswegen habe ich das auch erwähnt :) Hätte ich wohl dazu schreiben sollen :P

Ich würde überhaupt das struct entweder gleich richtig initialisieren, oder nicht initialisieren und einfach alle Member setzen...

Ersteres finde ich immer furchtbar, weil es überhaupt nicht mehr offensichtlich ist, wofür die Werte stehen.
Deswegen setze ich lieber alle Member "per Hand", aber initialisiere das struct auch, allerdings fällt mir auch grade auf, dass ich die Member ja dann doppelt mit einem Wert versehe...

Edit: Übrigens Happy Birthday :)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

28.10.2013, 00:30

Ersteres finde ich immer furchtbar, weil es überhaupt nicht mehr offensichtlich ist, wofür die Werte stehen.

Geht mir genau so.

Deswegen setze ich lieber alle Member "per Hand", aber initialisiere das struct auch, allerdings fällt mir auch grade auf, dass ich die Member ja dann doppelt mit einem Wert versehe...

In der Tat. Ich würde mal vermuten, dass jeder anständige Compiler in der Lage ist, das entsprechend zu optimieren. Aber ausprobiert hab ich's noch nie... ;)

Edit: Übrigens Happy Birthday :)

Danke :)

Werbeanzeige