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

n2k

Frischling

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

1

01.10.2014, 22:34

DirectX11: CreateBitmapFromDxgiSurface invalid args

Hallo zusammen,

ich sitze gerade an einer Win32 Desktop App und versuche verzweifelt meine DirectX Initialisierung gescheit ans Laufen zu bringen.

Ich verwende unter anderem DirectXTK für SpriteBatch. Das Teil habe ich auch ans Laufen gebracht. Jedoch haben die Sprites beim Rendern geflackert. Dieses Problem konnte ich mit anderen SwapChainDesc-Werten beseitigen.

Außerdem benutze ich den ID2D1DeviceContext zum Rendern von 2D-Primitiven. Den Backbuffer hole ich mir über CreateBitmapFromDxgiSurface() in eine Bitmap, welche ich dann als RenderTarget für den D2DContext setze. Das hat vorher auch alles wunderbar funktioniert, bis ich oben die SwapChainDesc geändert habe. Nach der Änderung bekomme ich von CreateBitmapFromDxgiSurface folgendes HRESULT: E_INVALIDARG One or more arguments are invalid.

Die SwapChainDesc Änderungen sind die folgenden:

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
24
25
26
// vorher:

// Allocate a swap chain descriptor.
//DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
//swapChainDesc.Width = 0;                           // use automatic sizing
//swapChainDesc.Height = 0;
//swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format
//swapChainDesc.Stereo = false;
//swapChainDesc.SampleDesc.Count = 1;                // don't use multi-sampling
//swapChainDesc.SampleDesc.Quality = 0;
//swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
//swapChainDesc.BufferCount = 2;                     // use double buffering to enable flip
//swapChainDesc.Scaling = DXGI_SCALING_NONE;
//swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all apps must use this SwapEffect
//swapChainDesc.Flags = 0;
 
// nachher:
DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
swapChainDesc.Width = width;
swapChainDesc.Height = height;
swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 2;


Jetzt ist zwar das Flackern weg, aber ich bekomme den Backbuffer vom DXGI nicht mehr. Wenn ich die Änderung rückgängig mache, bekomme ich den Backbuffer, aber es flackert wieder.

Ich verstehe nicht, welche Argumente genau ungültig sein sollen. Habe schon ein wenig mit den SwapChainDesc rumgespielt, komme aber auf keinen grünen Zweig.

Anbei der Source Code meines Init-Codes der "window size dependent resources":

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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
void DeviceResources::InitWindowSizeDependentResources(HWND hWnd)
{
  HRESULT hr;

  RECT rc;
  GetClientRect(hWnd, &rc);
  UINT width = rc.right - rc.left;
  UINT height = rc.bottom - rc.top;

  // Identify the physical adapter (GPU or card) this device is runs on.
  ComPtr<IDXGIAdapter> dxgiAdapter;
  hr = m_dxgiDevice->GetAdapter(&dxgiAdapter);

  if (FAILED(hr))
  {
    throw std::exception("Identification of IDXGIAdapter failed");
  }

  // Get the factory object that created the DXGI device.
  ComPtr<IDXGIFactory2> dxgiFactory;
  hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));

  if (FAILED(hr))
  {
    throw std::exception("Get IDXGIFactory2 failed");
  }

  // Allocate a swap chain descriptor.
  //DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };
  //swapChainDesc.Width = 0;                           // use automatic sizing
  //swapChainDesc.Height = 0;
  //swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // this is the most common swapchain format
  //swapChainDesc.Stereo = false;
  //swapChainDesc.SampleDesc.Count = 1;                // don't use multi-sampling
  //swapChainDesc.SampleDesc.Quality = 0;
  //swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  //swapChainDesc.BufferCount = 2;                     // use double buffering to enable flip
  //swapChainDesc.Scaling = DXGI_SCALING_NONE;
  //swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; // all apps must use this SwapEffect
  //swapChainDesc.Flags = 0;

  DXGI_SWAP_CHAIN_DESC1 swapChainDesc;
  ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
  swapChainDesc.Width = width;
  swapChainDesc.Height = height;
  swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  swapChainDesc.SampleDesc.Count = 1;
  swapChainDesc.SampleDesc.Quality = 0;
  swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  swapChainDesc.BufferCount = 2;


  // Get the final swap chain for this window from the DXGI factory.
  hr = dxgiFactory->CreateSwapChainForHwnd(
    m_d3dDevice.Get(),
    hWnd,
    &swapChainDesc,
    NULL,
    NULL,
    &m_dxgiSwapChain
    );

  if (FAILED(hr))
  {
    throw std::exception("Creation of IDXGISwapChain failed");
  }

  // Ensure that DXGI doesn't queue more than one frame at a time (minimize power consumption).
  hr = m_dxgiDevice->SetMaximumFrameLatency(1);

  if (FAILED(hr))
  {
    throw std::exception("Set MaximumFrameLatency failed");
  }

  // Get the backbuffer for this window which is be the final 3D render target.
  ID3D11Texture2D* pBackBuffer;
  hr = m_dxgiSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pBackBuffer)); //GetBuffer(0, IID_PPV_ARGS(&backBuffer));

  if (FAILED(hr))
  {
    throw std::exception("Get BackBuffer failed");
  }

  // Create a Direct2D target bitmap associated with the
  // swap chain back buffer and set it as the current target.
  D2D1_BITMAP_PROPERTIES1 bitmapProperties =
    D2D1::BitmapProperties1(
    D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
    D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
    96.0f,
    96.0f
    );

  ComPtr<IDXGISurface2> dxgiBackBuffer;
  hr = m_dxgiSwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer));

  hr = m_d2dContext->CreateBitmapFromDxgiSurface(
    dxgiBackBuffer.Get(),
    &bitmapProperties,
    &m_d2dRenderTargetBitmap
    );

  m_d2dContext->SetTarget(m_d2dRenderTargetBitmap.Get());


  hr = m_d3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &m_d3dRenderTargetView);

  if (FAILED(hr))
  {
    throw std::exception("CreateRenderTargetView failed");
  }
  
  // Create depth stencil texture
  D3D11_TEXTURE2D_DESC descDepth;
  ZeroMemory(&descDepth, sizeof(descDepth));
  descDepth.Width = width;
  descDepth.Height = height;
  descDepth.MipLevels = 1;
  descDepth.ArraySize = 1;
  descDepth.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
  descDepth.SampleDesc.Count = 1;
  descDepth.SampleDesc.Quality = 0;
  descDepth.Usage = D3D11_USAGE_DEFAULT;
  descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
  descDepth.CPUAccessFlags = 0;
  descDepth.MiscFlags = 0;
  hr = m_d3dDevice->CreateTexture2D(&descDepth, nullptr, &m_d3dDepthStencil);

  if (FAILED(hr))
  {
    throw std::exception("CreateTexture2D failed");
  }

  // Create the depth stencil view
  D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
  ZeroMemory(&descDSV, sizeof(descDSV));
  descDSV.Format = descDepth.Format;
  descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
  descDSV.Texture2D.MipSlice = 0;
  hr = m_d3dDevice->CreateDepthStencilView(m_d3dDepthStencil.Get(), &descDSV, &m_d3dDepthStencilView);

  if (FAILED(hr))
  {
    throw std::exception("CreateDepthStencilView failed");
  }

  m_d3dContext->OMSetRenderTargets(1, m_d3dRenderTargetView.GetAddressOf(), m_d3dDepthStencilView.Get());

  // Setup the viewport 
  // todo: wozu genau? (eingebaut, damit es in SpriteBatch.End() nicht knallt...)
  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;
  m_d3dContext->RSSetViewports(1, &vp);
}


Hat jemand eine Idee, wie ich das Problem auflösen kann?

Vielen Dank im Voraus!

n2k

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

2

01.10.2014, 23:23

Du benutzt jetzt ja auch das falsche Colorformat!
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

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

n2k

Frischling

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

3

01.10.2014, 23:45

Hallo Legend,

danke für die Antwort.

Doofe Frage: welches Colorformat benötige ich nun? Und wieso benutze ich jetzt das falsche? Ich verstehe den Zusammenhang nicht :(

Gruß
n2k

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

02.10.2014, 07:01

Äh, warte, warte, für mich als Non-DX-User mal zum Verständnis: Du versuchst aber nicht D3D und D2D zu mischen, oder? Falls doch: Warum?
Jedenfalls ist mir nicht ganz klar wozu Du das Bitmap erstellen willst. Microsoft setzt in ihrem Sample das Ding einfach nur als Target und verwendet DXGI_FORMAT_UNKNOWN als Pixelformat.
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]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (02.10.2014, 07:10)


Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

5

02.10.2014, 09:09

Hallo Legend,

danke für die Antwort.

Doofe Frage: welches Colorformat benötige ich nun? Und wieso benutze ich jetzt das falsche? Ich verstehe den Zusammenhang nicht :(

Gruß
n2k


Hallo n2k,

ich kann dir leider nicht sagen warum, aber generell funktioniert D2D nur mit BGRA Formaten und nicht mit RGBA Formaten. Zumindestens ist das sicher wenn man D2D auf D3D drauf setzt.
Und du hast DXGI_FORMAT_B8G8R8A8_UNORM durch DXGI_FORMAT_R8G8B8A8_UNORM ersetzt und das funktioniert sicher nicht.

@BlueCobold: Nun, D2D ist eigentlich eine sehr nette 2D API und auch wenn man 3D zeichnet wird man einige 2D Sachen wie Fonts zeichnen u.ä. ebenfalls benutzen wollen. Klar kann man das selber per D3D implementieren. Aber für mich ist D2D besser als alles was ich mit vertretbarem Aufwand umgesetzt bekommen habe. Und seit D2D 1.1 ist auch die Interop mit DirectX 11 brauchbar. Und möglich das man UNKNOWN beim Erstellen von D2D angeben kann. Bei der D3D Swapchain muss man aber DXGI_FORMAT_B8G8R8A8_UNORM o.ä. angeben. Ich glaube dort würde Unknown nur zu einem Fehler führen.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

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

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

02.10.2014, 09:33

Bei der Swapchain ist das klar, ja.
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]

n2k

Frischling

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

7

02.10.2014, 11:50

Hallo zusammen,

danke nochmal für euer Feedback.

Also generell soll die Applikation erstmal ein Grundrahmen für 2D-Anwendungen darstellen. Die D3D-Devices habe ich drin, da ich das Projekt nach folgendem MSDN-Artikel zusammen geschustert habe.

Das Projekt soll eine Grundlage darstellen um alle möglichen Formen von 2D-Grafiken malen zu können. Bisher sind das bei mir D2D-Primitiven über den D2DContext. Außerdem möchte ich die SpriteBatch-Klasse von DirectXTK verwenden. Zuvor habe ich mit XNA entwickelt und fande das Konzept sehr komfortabel.

Jetzt, einen Tag später, in alter Frische erkenne ich auch, was du mit dem Colorformat meintest, Legend. Habe gestern Nacht den Unterschied der Formate nicht mehr erkannt. Die Format-"Strings" sahen für mich "gleich" aus :)

Begonnen hat die ganze Geschichte ja damit, dass ich zuvor nur über D2DContext renderte. Nachdem ich die SpriteBatch-Klasse eingebaut hatte, flackerte das Sprite beim Rendern, weswegen ich überhaupt diese Umstellung vornahm.

Jetzt, mit dem richtigen Format, lässt sich das Bitmap auch wieder vom DXGI holen. Jedoch werden meine Primitiven nicht mehr gerendert (über den D2DContext). Ich habe gestern soviel rumgeschraubt und probiert, dass ich da wohl irgendwas verfummelt habe.

Bin nur leider gerade auf Arbeit und kann der Sache nicht nachgehen :/

Aber vielleicht finde ich den "neuen Fehler" nachher ja. Zum Glück gibt es TFS und Rollbacks :)

PS: es ist echt nicht einfach als Einsteiger durch die ganzen DeviceResources und deren Bedeutung/Notwendigkeit durchzusteigen :)

Gruß
n2k

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

8

02.10.2014, 12:23

In diesem Fall würde ich dir empfehlen diesen Link durchzulesen: http://msdn.microsoft.com/en-us/library/…v=vs.85%29.aspx

Denn dann kannst du es dir vielleicht auch gleich ersparen D3D zu initialisieren.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

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

n2k

Frischling

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

9

02.10.2014, 12:26

Hallo Legend,

danke dir. Ich werde mir den Artikel nach Feierabend mal zu Gemüte führen :)

Gruß
n2k

Werbeanzeige