2017-03-22 4 views
0

Ich habe einige Modelle (Geometrien), die eine Vertexinformation haben. Zum Beispiel Position, Normal, Farbe, Texkoord Jede dieser Informationen hat ihren eigenen Vertexpuffer. Aber einige dieser Modelle haben Texturkoordinaten einige nicht ... Um diese Unterschiede zu verwalten schrieb ich einen Vertexshader, der prüft, ob das Flag innerhalb des Konstantspuffers "hasTextureCoordinates" ist == 1. Und wenn ja, verwendet es den texcoord Parameter oder nicht . Aber Directx nicht wirklich wie dieses Problem zu umgehen und druckt:optionale vertexbufferobjects in directx11

D3D11 INFO: ID3D11DeviceContext :: Draw: Element [3] in der aktuellen Eingabe-Layout Erklärung Referenzen Eingabeschlitz 3, aber es gibt keinen Puffer dazu verpflichtet Slot. Dies ist in Ordnung, da Lesevorgänge von einem leeren Steckplatz als 0 definiert sind. Es ist auch möglich, dass der Entwickler weiß, dass die Daten trotzdem nicht verwendet werden. Dies ist nur ein Problem, wenn der Entwickler tatsächlich einen Eingabepuffer hier binden wollte. [EXECUTION INFO # 348: DEVICE_DRAW_VERTEX_BUFFER_NOT_SET]

Ich bin mir nicht sicher, ob alle Hardware dies richtig behandelt, auch nicht schön es ist in der Ausgabe dieser „Warnungen“ jedes Bild zu sehen ... Ich weiß, dass ich schreiben könnte, zwei Shader, eins mit und ohne Texcoods, aber das Problem ist, dass dies nicht der einzige vielleicht fehlende Parameter ist ... einige haben Farbe andere nicht, einige hat Farbe und Texturkoordinaten und so weiter. Und einen Shader für jede Kombination von Vertexpuffer-Eingaben zu schreiben, ist extrem redundant. Das ist extrem schlecht, denn wenn wir einen Shader ändern, müssen wir auch alle anderen ändern. Es gibt auch die Möglichkeit, Teile des Shaders in verschiedene Dateien zu legen und sie einzubinden, aber das ist verwirrend.

Gibt es eine Möglichkeit, directx zu sagen, dass der spezifische Vertexpuffer optional ist? Oder kennt jemand eine bessere Lösung für dieses Problem?

Antwort

1

Sie können diese spezifische Nachricht programmgesteuert unterdrücken. Da es ein INFO eher als ein FEHLER oder KORRUPTION Nachricht ist, ist es sicher zu ignorieren.

#include <wrl/client.h> 

using Microsoft::WRL::ComPtr; 

ComPtr<ID3D11Debug> d3dDebug; 
if (SUCCEEDED(device.As(&d3dDebug))) 
{ 
    ComPtr<ID3D11InfoQueue> d3dInfoQueue; 
    if (SUCCEEDED(d3dDebug.As(&d3dInfoQueue))) 
    { 
#ifdef _DEBUG 
     d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true); 
     d3dInfoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR, true); 
#endif 
     D3D11_MESSAGE_ID hide[] = 
     { 
      D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS, 
      D3D11_MESSAGE_ID_DEVICE_DRAW_VERTEX_BUFFER_NOT_SET, // <--- Your message here! 
      // Add more message IDs here as needed 
     }; 
     D3D11_INFO_QUEUE_FILTER filter = {}; 
     filter.DenyList.NumIDs = _countof(hide); 
     filter.DenyList.pIDList = hide; 
     d3dInfoQueue->AddStorageFilterEntries(&filter); 
    } 
} 

Neben Unterdrückung von ‚Rauschen‘ Nachrichten, in Debugbuilds dies bewirkt, dass auch die Debug-Schicht einen Stützpunkt erzeugen, wenn Sie ein ERROR oder KORRUPTION Nachricht getroffen haben als diejenigen wirklich sein müssen Fest.

Siehe Direct3D SDK Debug Layer Tricks

Hinweis I ComPtr hier zur Vereinfachung der QueryInterface Kette bin mit, und ich nehme an, Sie Ihr Gerät als ComPtr<ID3D11Device> device halten, wie ich in Anatomy of Direct3D 11 Create Device

in ich Sie auch davon ausgehen, verwenden VS 2013 oder höher, so dass D3D11_INFO_QUEUE_FILTER filter = {}; ausreicht, um die Struktur zu füllen.

+0

Sie denken also, dass diese Problemumgehung eine nette Möglichkeit ist, damit umzugehen? Oder gibt es bessere Möglichkeiten, das zu tun? – Thomas

+1

Im Allgemeinen ist eine bessere Lösung, verschiedene Eingabe-Layout-Objekte zu haben. Mein Punkt ist, dass Sie die INFO-Nachrichten ohne große Angst unterdrücken können. –