Häufig gestellte Fragen zu DirectX

Dieser Artikel enthält eine Sammlung häufig gestellter Fragen (FAQ) zu Microsoft DirectX.

Allgemeine Probleme bei der DirectX-Entwicklung

Sollten Sich Spieleentwickler wirklich um die Unterstützung von x64-Editionen kümmern?

Absolut. Die x64-Technologie ist auf dem Markt weit verbreitet. Der Großteil der neuen CPUs, die in den letzten Jahren verkauft wurden, und fast alle Prozessorlinien in der Entwicklung von AMD und Intel sind x64-fähig. Windows Xp Professional x64 Edition hat die Betriebssystem-Aktivierungstechnologie für x64 eingeführt, die im April 2005 veröffentlicht wurde. Da x64-Editionen eine neue Generation nativer 64-Bit-Treiber erfordern, war dieses erste Release auf die OEM-Verteilung beschränkt.

Mit Windows Vista können Kunden beim Erwerb Windows-basierter Computer entweder 32-Bit- oder 64-Bit-Editionen auswählen, und Lizenzen für Windows Vista sind sowohl für 32-Bit- als auch für 64-Bit-Editionen des Betriebssystems gültig. Darüber hinaus sind viele 64-Bit-Treiber im Feld verfügbar, und Gerätehersteller müssen im Rahmen des Windows Certification Program sowohl native 32-Bit- als auch 64-Bit-Treiber bereitstellen.

All diese Faktoren erhöhen die Bereitstellungen von 64-Bit-Editionen von Windows erheblich. Wenn neue Computer mit mehr als 2 GB physischem RAM ausgeliefert werden, verringert sich der Incentives zur Verwendung eines 32-Bit-Betriebssystems erheblich zugunsten von 64-Bit-Editionen. Die 64-Bit-Technologie unterstützt vollständig nativen 32-Bit-Code, obwohl native 64-Bit-Implementierungen erforderlich sind, um den neuen 64-Bit-Speicherplatz voll nutzen zu können. Jede 32-Bit-Anwendung sollte eine 64-Bit-Kompatibilität als Mindestversandanforderung aufweisen, und die Erfüllung dieser Anforderung ist eine Baselineanforderung für Windows Vista-Kompatibilität. Inkompatibilitäten entstehen in der Regel durch die Verwendung von 16-Bit-Code, der für das Windows 3.1-Betriebssystem entwickelt wurde, oder durch die Installation von Treibern, die nicht sowohl in nativer 32-Bit- als auch in 64-Bit-Form bereitgestellt werden.

Weitere Informationen zur 64-Bit-Technologie finden Sie unter 64-Bit-Programmierung für Spieleentwickler.

Sollten Spieleentwickler weiterhin Spiele für Windows 95, Windows 98 oder Windows ME veröffentlichen?

Nicht mehr aus zwei Gründen: Leistung und Featuresatz.

Wenn die minimale CPU-Geschwindigkeit, die für Ihr Spiel erforderlich ist, 1,2 GHz oder höher beträgt (was bei Titeln mit hoher Leistung üblicher ist), wird die überwiegende Mehrheit der geeigneten Computer Windows XP ausgeführt. Als Computer mit CPU-Geschwindigkeiten über 1,2 GHz verkauft wurden, wurde Windows XP von fast allen Herstellern als Standardbetriebssystem installiert. Dies bedeutet, dass es viele Features in Windows XP gibt, die heutige Spieleentwickler nutzen sollten, einschließlich:

  • Verbessertes Multitasking: Dies führt zu einer besseren, reibungsloseren Benutzeroberfläche für Video, Audio und Gaming.
  • Stabileres Videotreibermodell, das ein einfacheres Debuggen, ein reibungsloses Spiel und eine bessere Leistung ermöglicht.
  • Einfachere Konfiguration für Netzwerke, wodurch der Zugriff auf Spiele mit mehreren Playern vereinfacht wird.
  • Unterstützung für DMA-Übertragungen standardmäßig von Festplatten , was zu einem reibungsloseren, schnelleren Laden von Anwendungen führt.
  • Windows Fehlerberichterstattung: Dies führt zu einem stabileren Betriebssystem, Treibern und Anwendungen.
  • Unicode-Unterstützung: Dies vereinfacht Lokalisierungsprobleme erheblich.
  • Bessere Sicherheit und Stabilität: Dies führt zu einer besseren Benutzererfahrung.
  • Bessere Unterstützung für moderne Hardware, von der die meisten nicht mehr Windows 98 Treiber verwenden.
  • Verbesserte Speicherverwaltung, was zu einer höheren Stabilität und Sicherheit führt.
  • Verbessertes NTFS-Dateisystem, das widerstandsfähiger gegen Fehler ist und eine bessere Leistung mit Sicherheitsfeatures bietet.

Sollten Spieleentwickler weiterhin Spiele für Windows 2000 veröffentlichen?

Nicht mehr. Zusätzlich zu den unter Sollten Spieleentwickler noch Spiele für Windows 95, Windows 98 oder Windows ME? aufgeführt sind, verfügt Windows 2000 nicht über diese Features:

  • Windows XP unterstützt erweiterte Prozessorfeatures wie Hyperthreading, Multi-Core und x64.
  • Windows XP unterstützt komponentenseitige Komponenten, wodurch Konflikte bei der Anwendungsversionsausführung erheblich reduziert werden.
  • Windows XP unterstützt den Speicherschutz ohne Ausführung, um schädliche Programme zu verhindern und das Debuggen zu unterstützen.
  • Windows XP bietet verbesserte Unterstützung für erweiterte AGP- und PCI Express-basierte Grafikkarten.
  • Windows XP unterstützt schnelles Wechseln von Benutzern, Remotedesktop und Remoteunterstützung, um die Produktsupportkosten zu senken.
  • Leistungstools wie PIX (im DirectX Developer SDK) unterstützen Windows 2000 nicht mehr.

Kurz gesagt, Windows 2000 wurde nie als Consumerbetriebssystem entworfen oder in den Markt übergezahlt.

Was sind die Unterschiede zwischen den verschiedenen Editionen von Windows Vista? Wie wirken sie sich auf meine DirectX-Anwendung aus?

Die Windows Vista-Familie umfasst fünf Editionen:

  • Windows Vista Home Basic
  • Windows Vista Home Premium
  • Windows Vista Business
  • Windows Vista Enterprise
  • Windows Vista Ultimate

Home Basic und Home Premium sind verbraucherorientierte Versionen mit Features wie Family Safety (früher als Jugendschutz bezeichnet) und Home Premium umfasst Media Center. Geschäfts- und Enterprise sind unternehmensorientierte Editionen mit Features wie Domäneneinführung und Remotedesktop-/Terminaldiensten. Die Ultimate Edition kombiniert alle Features der Consumer- und Unternehmenseditionen in einer Version. Alle Editionen sind sowohl in 32-Bit-Editionen (x86) als auch in 64-Bit-Editionen (x64) erhältlich, und Benutzer können denselben Produktbezeichner für beide Plattformen verwenden.

Die Technologie, die den verschiedenen Editionen zugrunde liegt, ist identisch, und sie verfügen alle über die gleiche Version der DirectX-Runtime und andere Komponenten. Die Editionen weisen jedoch einige geringfügige Unterschiede in Bezug auf Spiele auf:

  • Der Spiele-Explorer ist in allen Editionen vorhanden, aber die Verknüpfung "Games" auf dem Startmenü befindet sich nur in Home Basic, Home Premium und Ultimate. Der Games-Explorer kann weiterhin in allen Editionen gefunden werden (indem Sie auf Start klicken, auf Alle Programme zeigen und dann auf Spiele klicken), und die IGameExplorer-Schnittstellenfunktionen für alle Editionen.
  • Die in Windows enthaltenen Spiele sind in Business und Enterprise standardmäßig nicht verfügbar, können jedoch vom Administrator aktiviert werden.
  • Family Safety und Spielbewertungen werden nicht angezeigt oder beeinflussen das Verhalten von Business oder Enterprise, und sie werden bei Ultimate deaktiviert, wenn eine Domäne verknüpft wird.

Die Einstellungen für die Benutzerkontensteuerung verfügen in allen Editionen über die gleichen Standardwerte, können jedoch durch Gruppenrichtlinie Einstellungen für die Domäne unter Business, Enterprise und Ultimate überschrieben werden. Beispielsweise kann die Richtlinieneinstellung Benutzerkontensteuerung: Verhalten der Eingabeaufforderung für erhöhte Rechte für Standardbenutzer auf Anforderungen für erhöhte Rechte automatisch verweigern in vielen Geschäftseinstellungen festgelegt werden, um die Sicherheit zu erhöhen, und viele Benutzer in diesen Umgebungen werden immer als Standardbenutzer ausgeführt, ohne sich für die Ausführung als Administrator entscheiden zu können. Jedes Programm (z. B. ein Installationsprogramm), das Administratorrechte erfordert, entweder aufgrund der Erkennung des Legacysetups oder aufgrund eines Manifests, das die angeforderte Ausführungsebene als "requireAdministrator" angibt, kann in solchen Situationen immer nicht gestartet werden. Andere Richtlinieneinstellungen, z. B. Benutzerkontensteuerung: Nur ausführbare Dateien, die signiert und überprüft werden, können auch verhindern, dass Ihr Installationsprogramm funktioniert, wenn Sie die ausführbare Datei nicht mit Authenticode signieren.

Diese Arten von Richtlinienänderungen können auf jede Edition von Windows Vista angewendet werden, sind jedoch wahrscheinlicher auf Computern, die einer Domäne angehören.

Was sind die Unterschiede zwischen den verschiedenen Editionen von Windows 7? Wie wirken sie sich auf meine DirectX-Anwendung aus?

Der Großteil der Windows 7 Benutzer verfügt wahrscheinlich über eine von zwei Editionen: Windows 7 Home Premium, für Privatbenutzer oder Windows 7 Professional für Geschäftsbenutzer und Entwickler. Für große Unternehmen gibt es die volumenlizenzierte Windows 7 Enterprise Edition, die alle Windows 7 Features umfasst. Windows 7 Ultimate ist das Einzelhandelsäquivalent dieser Edition.

Windows 7 Starter Edition ist weltweit für OEMs verfügbar und sollte primär mit Netbooks, Notebookcomputern mit extrem geringem Leistungsdruck, bereitgestellt werden. Windows 7 Home Basic ist nur in neuen Märkten verfügbar.

Beachten Sie, dass alle Editionen von Windows 7 (mit Ausnahme der Starter Edition) sowohl für 32-Bit-Versionen (x86) als auch für 64-Bit-Versionen (x64) verfügbar sind und alle Verkaufspakete von Windows 7 Medien für beide Versionen enthalten. Wie bei Windows Vista können Benutzer auf beiden Plattformen denselben Einzelhandelsproduktbezeichner verwenden.

Die zugrunde liegende Technologie in den verschiedenen Editionen ist identisch, und alle Editionen verfügen über die gleiche Version der DirectX-Runtime und andere Komponenten. Sie weisen einige Unterschiede in Bezug auf Gamingfeatures auf:

  • Games Explorer ist in allen Editionen vorhanden, aber die Verknüpfung "Games" auf dem Startmenü ist standardmäßig in Windows 7 Professional und Enterprise ausgeblendet. Games Explorer finden Sie weiterhin auf dem Startmenü (indem Sie auf Alle Programme klicken und dann auf Spiele doppelklicken), und die direkte Games-Verknüpfung kann vom Benutzer aktiviert werden.
  • Die in Windows enthaltenen Spiele sind standardmäßig nicht auf Windows 7 Professional und Enterprise verfügbar, können jedoch vom Administrator aktiviert werden.
  • Family Safety und Spielbewertungen sind in allen Editionen verfügbar, aber sie sind am Windows 7. Professional, Enterprise und Ultimate deaktiviert, wenn das Betriebssystem einer Domäne beitritt. Wie bei Windows Vista Ultimate kann dieses Feature auf einem Computer, der einer Domäne beigetreten ist, erneut aktiviert werden.

Einstellungen für die Benutzerkontensteuerung (User Account Control, UAC) können von Gruppenrichtlinie Einstellungen in Windows 7 Professional, Enterprise und Ultimate-Editionen beeinflusst werden, ähnlich wie Windows Vista. Weitere Informationen finden Sie unter Was sind die Unterschiede zwischen den verschiedenen Editionen von Windows Vista? Wie wirken sie sich auf meine DirectX-Anwendung aus?

Ist DirectX 10 für Windows XP verfügbar?

Nein. Windows Vista mit DirectX 10 enthält eine aktualisierte DirectX-Runtime, die auf der Runtime in Windows XP SP2 (DirectX 9.0c) basiert, mit Änderungen, die mit dem neuen Windows Display Driver Model (WDDM) und dem neuen Audiotreiberstapel sowie mit anderen Updates im Betriebssystem funktionieren. Zusätzlich zu Direct3D 9 unterstützt Windows Vista zwei neue Schnittstellen, wenn die richtige Videohardware und die richtigen Treiber vorhanden sind: Direct3D9Ex und Direct3D10.

Da diese neuen Schnittstellen auf der WDDM-Technologie basieren, sind sie in früheren Versionen von Windows nie verfügbar. Alle anderen Änderungen an DirectX-Technologien für Windows Vista gelten auch für die neue Version von Windows. Der Name DirectX 10 ist irreführend, da viele Technologien, die im DirectX SDK (XACT, XINPUT, D3DX) ausgeliefert werden, nicht von dieser Versionsnummer abgedeckt sind. Daher hat der Verweis auf die Versionsnummer der DirectX-Runtime als Ganzes einen Großteil seiner Bedeutung verloren, auch für 9.0c. Das DirectX-Diagnosetool (DXdiag.exe) auf Windows Vista meldet DirectX 10, aber dies bezieht sich eigentlich nur auf Direct3D 10.

Ist DirectX 11 für Windows Vista oder Windows XP verfügbar?

DirectX 11 ist in Windows 7 integriert und als Update für Windows Vista verfügbar (siehe https://go.microsoft.com/fwlink/p/?linkid=160189 ). Dazu gehören die Direct3D 11-API, DirectX Graphic Infrastructure (DXGI) 1.1, 10Level9-Featureebenen, Windows Advanced Rasterization Platform (WARP) 10-Softwarerenderinggerät, Direct2D, DirectWrite und ein Update der Direct3D 10.1-API zur Unterstützung von 10Level9 und WARP 10.

Aus denselben Gründen wie in der vorherigen Frage (Ist DirectX 10 für Windows XP verfügbar? ), Direct3D 11 und zugehörige APIs sind auf Windows XP nicht verfügbar.

Was ist mit DirectShow passiert? Ich kann es nicht im DirectX SDK finden.

DirectShow wurde ab April 2005 aus dem DirectX SDK entfernt. Sie können die Header, Bibliotheken, Tools und Beispiele für DirectShow im Windows Software Development Kit (ehemals Platform SDK) abrufen. DirectSetup im DirectX SDK unterstützt weiterhin die Neuverteilung der DirectShow-Systemkomponenten, und die neuesten Komponenten sind bereits unter den folgenden Betriebssystemen installiert: Microsoft Windows XP Service Pack 2, Windows XP Professional x64 Edition, Windows Server 2003 Service Pack 1 und Windows Vista.

Welche Änderungen wurden an der DirectX-Runtime für Windows Vista vorgenommen?

Die primären Änderungen wurden vorgenommen, um das neue WDDM zu unterstützen. Weitere Informationen zum neuen Treibermodell, zu den Auswirkungen auf Direct3D 9 und zu den beiden neuen Grafikschnittstellen Direct3D 9Ex und Direct3D 10 finden Sie unter Grafik-APIs in Windows. Neue Grafik-APIs für Windows 7 – Direct3D 11, Direct2D, DirectWrite, DXGI 1.1 und ein aktualisiertes Direct3D 10.1 – sind als Update für Windows Vista verfügbar (siehe https://go.microsoft.com/fwlink/p/?linkid=160189 ).

Windows Vista Service Pack 1 enthält eine aktualisierte Version der DirectX-Runtime. Dieses Update erweitert die Unterstützung von Windows Vista um Direct3D 10.1 und bietet neue optionale Hardwarefeatures. (Alle Hardware, die Direct3D 10.1 unterstützen kann, unterstützt auch alle Features von Direct3D 10 vollständig.)

DirectSound wurde aktualisiert, um die Funktionen des neuen Windows Vista-Audiotreiberstapels verfügbar zu machen, der Mehrkanalsoftwarepuffer unterstützt. Die API für den beibehaltenen Direct3D-Modus wurde vollständig aus Windows Vista entfernt. DirectPlay Voice wurde ebenfalls entfernt, ebenso wie das NAT-Hilfsfeld von DirectPlay und die Aktionszuordnungsbenutzeroberfläche von DirectInput. Unterstützung für die DirectX 7- und DirectX 8-Schnittstellen für Visual Basic 6.0 ist auf Windows Vista nicht verfügbar.

Welche Änderungen wurden an der DirectX-Runtime für Windows 7 vorgenommen?

Windows 7 enthält alle DirectX-Runtimekomponenten in Windows Vista und fügt direct3D 11, DXGI 1.1, 10Level9, das WARP10-Softwaregerät, Direct2D, DirectWrite und ein Update für Direct3D 10.1 hinzu, um 10Level9 und WARP10 zu unterstützen. Weitere Informationen finden Sie unter Grafik-APIs in Windows.

Alle anderen Komponenten sind identisch mit Windows Vista, mit zusätzlicher nativer 64-Bit-Unterstützung (x64) für die DirectVista-Kern-API im Zusammenhang mit zeitstempeliertem KEYBOARD. Die Leistungsebene von DirectPerformance ist aus Anwendungskompatibilität weiterhin veraltet und nur für 32-Bit-Anwendungen auf Windows 7 verfügbar. Beachten Sie, dass die native 64-Bit-Unterstützung von DirectVista auf Windows Vista nicht verfügbar ist.

Ich bin der Meinung, dass ich einen Treiberfehler gefunden habe. Was kann ich tun?

Stellen Sie zunächst sicher, dass Sie die Ergebnisse mit dem Referenzraster überprüft haben. Überprüfen Sie dann die Ergebnisse mit der neuesten WHQL-zertifizierten Version des IHVs-Treibers. Sie können den WHQL-Status programmgesteuert überprüfen, indem Sie die GetAdapterIdentifier()-Methode auf der IDirect3D9-Schnittstelle verwenden, um das Flag D3DENUM _ WHQL _ LEVEL zu übergeben.

Warum werden so viele Fehlermeldungen angezeigt, wenn ich versuche, die Beispiele zu kompilieren?

Ihr Includepfad ist wahrscheinlich nicht richtig festgelegt. Viele Compiler, einschließlich Microsoft Visual C++, enthalten eine frühere Version des SDK. Wenn Ihr Includepfad also zuerst die Standardcompiler-Includeverzeichnisse durchsucht, erhalten Sie falsche Versionen der Headerdateien. Um dieses Problem zu beheben, stellen Sie sicher, dass der Includepfad und die Bibliothekspfade so festgelegt sind, dass zuerst die Microsoft DirectX-Include- und Bibliothekspfade durchsucht werden. Siehe auch die dxreadme.txt im SDK. Wenn Sie das DirectX SDK installieren und Visual C++, kann das Installationsprogramm optional die Includepfade für Sie einrichten.

Ich habe Linkerfehler zu mehreren oder fehlenden Symbolen für GUIDs (Globally Unique Identifiers) erhalten. Was kann ich tun?

Die verschiedenen GUIDs, die Sie verwenden, sollten nur einmal definiert werden. Die Definition für die GUID wird eingefügt, wenn Sie das INITGUID-Symbol definieren, bevor # Sie die DirectX-Headerdateien einfügen. Daher sollten Sie sicherstellen, dass dies nur für eine Kompilierungseinheit auftritt. Eine Alternative zu dieser Methode ist die Verknüpfung mit der dxguid.lib-Bibliothek, die Definitionen für alle DirectX-GUIDs enthält. Wenn Sie diese Methode verwenden (was empfohlen wird), sollten Sie niemals das # INITGUID-Symbol definieren.

Kann ich einen Zeiger auf eine DirectX-Schnittstelle in eine niedrigere Versionsnummer casten?

Nein. DirectX-Schnittstellen sind COM-Schnittstellen. Dies bedeutet, dass es nicht erforderlich ist, dass schnittstellen mit höheren Zahlen von den entsprechenden schnittstellen mit niedrigeren Zahlen abgeleitet werden. Daher ist die einzige sichere Möglichkeit, eine andere Schnittstelle zu einem DirectX-Objekt zu erhalten, die Verwendung der QueryInterface-Methode der Schnittstelle. Diese Methode ist Teil der IUnknown-Standardschnittstelle, von der alle COM-Schnittstellen ableiten müssen.

Kann ich die Verwendung von DirectX 9-Komponenten und DirectX 8- oder früheren Komponenten innerhalb derselben Anwendung kombinieren?

Sie können verschiedene Komponenten unterschiedlicher Versionen frei kombinieren. Beispielsweise können Sie DirectInput 8 mit Direct3D 9 in derselben Anwendung verwenden. Sie können jedoch im Allgemeinen keine verschiedenen Versionen derselben Komponente innerhalb derselben Anwendung mischen. Sie können z. B. DirectDraw 7 nicht mit Direct3D 9 kombinieren (da es sich dabei tatsächlich um die gleiche Komponente wie DirectDraw handelt, die seit DirectX 8 in Direct3D subsumiert wurde). Es gibt jedoch Ausnahmen, z. B. die Gemeinsame Verwendung von Direct3D 9 und Direct3D 10 in derselben Anwendung, was zulässig ist.

Kann ich die Verwendung von Direct3D 9 und Direct3D 10 innerhalb derselben Anwendung kombinieren?

Ja, Sie können diese Versionen von Direct3D zusammen in derselben Anwendung verwenden.

Was bedeuten die Rückgabewerte der Release- oder AddRef-Methoden?

Der Rückgabewert ist die aktuelle Verweisanzahl des Objekts. Die COM-Spezifikation besagt jedoch, dass Sie sich nicht darauf verlassen sollten, und der Wert ist im Allgemeinen nur für Debugzwecke verfügbar. Die beobachteten Werte können unerwartet sein, da verschiedene andere Systemobjekte Möglicherweise Verweise auf die von Ihnen erstellten DirectX-Objekte enthalten. Aus diesem Grund sollten Sie keinen Code schreiben, der "Release" wiederholt aufruft, bis die Verweisanzahl 0 (null) ist, da das Objekt dann möglicherweise wieder frei wird, obwohl möglicherweise noch eine andere Komponente darauf verweist.

Spielt es eine Rolle, in welcher Reihenfolge ich DirectX-Schnittstellen freilasse?

Dies sollte keine Rolle spielt, da COM-Schnittstellen als Verweis gezählt werden. Es gibt jedoch einige bekannte Fehler bei der Release reihenfolge der Schnittstellen in einigen Versionen von DirectX. Aus Sicherheitsgründen wird empfohlen, Schnittstellen nach Möglichkeit in umgekehrter Erstellungs reihenfolge frei zu geben.

Was ist ein intelligenter Zeiger, und sollte ich ihn verwenden?

Ein intelligenter Zeiger ist eine C++-Vorlagenklasse, die zum Kapseln von Zeigerfunktionen entwickelt wurde. Insbesondere gibt es intelligente Standardzeigerklassen, die zum Kapseln von COM-Schnittstellenzeigern entwickelt wurden. Diese Zeiger führen queryInterface automatisch anstelle einer Cast aus und verarbeiten AddRef und Release für Sie. Ob Sie sie verwenden sollten, ist größtenteils eine Frage des Vorliebes. Wenn Ihr Code viele Kopien von Schnittstellenzeigern mit mehreren AddRefs und Releases enthält, können intelligente Zeiger ihren Code wahrscheinlich übersichtlicher und weniger fehleranfällig machen. Andernfalls können Sie auf sie nicht zugreifen. Visual C++ enthält einen standardmäßigen intelligenten Microsoft COM-Zeiger, der in der Headerdatei "comdef.h" definiert ist (suchen Sie in der Hilfe nach com _ ptr _ t).

Ich habe Probleme beim Debuggen meiner DirectX-Anwendung, tipps?

Das häufigste Problem beim Debuggen von DirectX-Anwendungen ist der Versuch, zu debuggen, während eine DirectDraw-Oberfläche gesperrt ist. Diese Situation kann zu einer "Win16-Sperre" auf Microsoft Windows 9x-Systemen führen, wodurch verhindert wird, dass das Debuggerfenster gestrichen wird. Wenn Sie beim Sperren der Oberfläche das Flag D3DLOCK NOSYSLOCK angeben, kann dies _ in der Regel beseitigt werden. Windows 2000 ist dieses Problem nicht betroffen. Beim Entwickeln einer Anwendung ist es hilfreich, mit der Debugversion der DirectX-Runtime (ausgewählt bei der Installation des SDK) ausgeführt zu werden, die einige Parameterüberprüfungen ausführt und nützliche Meldungen an die Debuggerausgabe ausgibt.

Wie können Rückgabecodes richtig überprüft werden?

Verwenden Sie die Makros SUCCEEDED und FAILED. DirectX-Methoden können mehrere Erfolgs- und Fehlercodes zurückgeben, also eine einfache:

== D3D_OK

oder ein ähnlicher Test reicht nicht immer aus.

Gewusst wie Alt+TAB und andere Aufgabenwechsel deaktivieren?

Das ist nicht der! Spiele müssen in der Lage sein, Aufgabenwechsel ordnungsgemäß zu verarbeiten, da viele Dinge dazu führen, dass es geschieht: ALT+TAB, Remotedesktopverbindungen, schnelle Benutzerwechsel, Nutzungsgrenzwerte für die Jugendkontrolle und viele andere Ereignisse.

Gleichzeitig sind zwei häufige Quellen für versehentliche Aufgabenwechsel bei Spielen mit tastaturzentrierten Steuerelementschemas das Drücken der Windows-Logo-Taste und das Aktivieren der Barrierefreiheitsfunktion StickyKeys mit der UMSCHALTTASTE. Um diese Fälle durch Deaktivieren der Funktionalität zu adressieren, lesen Sie die unter Deaktivieren von Tastenkombinationen in Spielen beschriebenen Techniken.

Gibt es ein empfohlenes Buch, in dem COM erläutert wird?

Das von Microsoft Press veröffentlichte In-COM-Produkt von %. Es handelt sich um eine hervorragende Einführung in COM. Für einen ausführlicheren Blick auf COM wird auch das buch Essential COM von Don Box, das von Longman veröffentlicht wurde, dringend empfohlen.

Was ist verwalteter Code?

Verwalteter Code ist Code, dessen Ausführung von der .NET Framework Common Language Runtime (CLR) verwaltet wird. Er bezieht sich auf einen Vertrag der Zusammenarbeit zwischen nativ ausgeführten Code und der Laufzeit. Dieser Vertrag gibt an, dass die Laufzeit zu jedem Zeitpunkt der Ausführung eine ausgeführte CPU beenden und spezifische Informationen für die aktuelle CPU-Anweisungsadresse abrufen kann. Informationen, die abfragebar sein müssen, beziehen sich im Allgemeinen auf den Laufzeitzustand, z. B. den Inhalt des Register- oder Stapelspeichers.

Bevor der Code ausgeführt wird, wird die IL in systemeigenen ausführbaren Code kompiliert. Und da diese Kompilierung von der verwalteten Ausführungsumgebung (oder, richtiger, von einem Laufzeitcompiler erfolgt, der weiß, wie die verwaltete Ausführungsumgebung als Ziel verwendet werden soll), kann die verwaltete Ausführungsumgebung Garantien darüber geben, was der Code tun soll. Er kann Traps und entsprechende Garbage Collection-Hooks, Ausnahmebehandlung, Typsicherheit, Array- und Indexüberprüfungen usw. einfügen. Ein solcher Compiler stellt beispielsweise sicher, dass Stapelrahmen und alles genau richtig sind, damit der Garbage Collector im Hintergrund in einem separaten Thread ausgeführt werden kann, ständig durch die aktive Aufrufliste läuft, alle Stämme findet und alle aktiven Objekte verdrungen. Da die IL ein Konzept der Typsicherheit hat, behält die Ausführungs-Engine außerdem die Garantie der Typsicherheit bei, wodurch eine ganze Klasse von Programmierfehlern beseitigt wird, die häufig zu Sicherheitslücken führen.

Im Gegensatz zur nicht verwalteten Welt: Nicht verwaltete ausführbare Dateien sind im Grunde ein binäres Bild, x86-Code, das in den Arbeitsspeicher geladen wird. Der Programmzähler wird dort abgeknöhnt, und dies ist der letzte, den das Betriebssystem kennt. Es gibt Schutz vor Speicherverwaltung und Port-E/A usw., aber das System weiß nicht, was die Anwendung tut. Aus diesem Grund kann keine Garantie dafür geben, was geschieht, wenn die Anwendung ausgeführt wird.

Welche Bücher gibt es zur allgemeinen Windows Programmierung?

Viele. Die beiden dringend empfohlenen sind jedoch:

  • Programming Windows von Charles Petzod (Microsoft Press)
  • Programming Applications for Windows ( Programmieren von Anwendungen für Windows) von JeffreyUng (Microsoft Press)

Gewusst wie Debuggen mithilfe der Windows Symboldateien?

Microsoft veröffentlicht entfernte Symbole für alle System-DLLs (und einige andere). Fügen Sie ihrem Symbolpfad in den Projekteinstellungen in Visual Studio Folgendes hinzu, um darauf zuzugreifen:

srv*https://msdl.microsoft.com/download/symbols

Verwenden Sie zum lokalen Zwischenspeichern von Symbolen die folgende Syntax:

srv*c:\cache*https://msdl.microsoft.com/download/symbols

Wobei c: \ cache ein lokales Verzeichnis zum Zwischenspeichern von Symboldateien ist.

Fragen zu Direct3D

Allgemeine Direct3D-Fragen

Wo finde ich Informationen zu 3D-Grafiktechniken?

Das Standardbuch zu diesem Thema ist Computer Graphics: Principles and Practice von Foley, VanMobile et al. Es ist eine wertvolle Ressource für alle, die die mathematischen Grundlagen von Geometrie, Rasterung und Beleuchtungstechniken verstehen möchten. Die häufig gestellten Fragen zur Usenet-Gruppe comp.graphics.algorithms enthalten ebenfalls nützliches Material.

Emuliert Direct3D Funktionen, die nicht von Hardware bereitgestellt werden?

Das ist unterschiedlich. Direct3D verfügt über eine softwarevertex-processing-Pipeline mit vollem Funktionsumfang (einschließlich Unterstützung für benutzerdefinierte Vertex-Shader). Für Vorgänge auf Pixelebene wird jedoch keine Emulation bereitgestellt. -Anwendungen müssen die entsprechenden Caps-Bits überprüfen und die ValidateDevice-API verwenden, um die Unterstützung zu ermitteln.

Ist ein Softwarerasterizer in Direct3D enthalten?

Nicht für Leistungsanwendungen. Ein Referenzrasterizer wird für die Treiberüberprüfung bereitgestellt, aber die Implementierung ist auf Genauigkeit und nicht auf Leistung ausgelegt. Direct3D unterstützt Plug-In-Softwarerasterizer.

Wie kann ich die Farbtasten mit DirectX-Grafiken ausführen?

Farbschlüsselung wird nicht direkt unterstützt, stattdessen müssen Sie Alphablending verwenden, um die Farbtasten zu emulieren. Die D3DXCreateTextureFromFileEx()-Funktion kann verwendet werden, um dies zu erleichtern. Diese Funktion akzeptiert einen Schlüsselfarbparameter und ersetzt alle Pixel aus dem Quellbild, das die angegebene Farbe enthält, durch transparente schwarze Pixel in der erstellten Textur.

Verwendet der Direct3D-Geometriecode 3DNow! und/oder Pentium III SIMD-Anweisungen?

Ja. Die Direct3D-Geometriepipeline verfügt je nach Prozessortyp über mehrere verschiedene Codepfade und nutzt die speziellen Gleitkommavorgänge, die von 3DNow bereitgestellt werden. oder Pentium III SIMD-Anweisungen, wenn diese verfügbar sind. Dies schließt die Verarbeitung von benutzerdefinierten Vertex-Shadern ein.

Gewusst wie verhindern, dass transparente Pixel in den Z-Puffer geschrieben werden?

Sie können Pixel mit einem Alphawert herausfiltern, der über oder unter einem bestimmten Schwellenwert liegt. Sie steuern dieses Verhalten mit den Renderstates ALPHATESTENABLE, ALPHAREF und ALPHAFUNC.

Was ist ein Schablonenpuffer?

Ein Schablonenpuffer ist ein zusätzlicher Puffer von Informationen pro Pixel, ähnlich wie ein Z-Puffer. Tatsächlich befindet sie sich in einigen Bits eines Z-Puffers. Gängige Schablonen-/Z-Pufferformate sind 15-Bit-Z- und 1-Bit-Schablone oder 24-Bit-Z- und 8-Bit-Schablone. Es ist möglich, einfache arithmetische Operationen für den Inhalt des Schablonenpuffers pro Pixel auszuführen, während Polygone gerendert werden. Beispielsweise kann der Schablonenpuffer erhöht oder dekrementiert werden, oder das Pixel kann abgelehnt werden, wenn der Schablonenwert bei einem einfachen Vergleichstest fehlschlägt. Dies ist nützlich für Effekte, bei denen ein Bereich des Rahmenpuffers markiert und dann nur der markierte (oder nicht markierte) Bereich gerendert wird. Gute Beispiele sind volumetrische Effekte wie Schattenvolumes.

Gewusst wie einen Schablonenpuffer verwenden, um Schattenvolumes zu rendern?

Der Schlüssel zu diesem und anderen volumetrischen Schablonenpuffereffekten ist die Interaktion zwischen dem Schablonenpuffer und dem Z-Puffer. Eine Szene mit einem Schattenvolumen wird in drei Phasen gerendert. Zuerst wird die Szene ohne den Schatten wie gewohnt mithilfe des Z-Puffers gerendert. Als Nächstes wird der Schatten im Schablonenpuffer wie folgt markiert. Die vorderen Gesichter des Schattenvolumens werden mit unsichtbaren Polygonen gezeichnet, wobei Z-Tests aktiviert sind, Z-Schreibvorgänge jedoch deaktiviert sind und der Schablonenpuffer bei jedem Pixel erhöht wird, das den Z-Test übergibt. Die hinteren Gesichter des Schattenvolumes werden ähnlich gerendert, aber stattdessen wird der Schablonenwert dekrementiert.

Betrachten Sie nun ein einzelnes Pixel. Wenn sich die Kamera nicht im Schattenvolumen befindet, gibt es vier Möglichkeiten für den entsprechenden Punkt in der Szene. Wenn der Strahl von der Kamera bis zum Punkt das Schattenvolumen nicht überschneidet, wurden dort keine Schattenpolygone gezeichnet, und der Schablonenpuffer ist immer noch 0 (null). Andernfalls werden die Schattenpolygone z-gepuffert, und die Schablone bleibt wieder unverändert, wenn sich der Punkt vor dem Schattenvolume befindet. Wenn die Punkte hinter dem Schattenvolume liegen, wurde die gleiche Anzahl von Frontschattenflächen wie die hinteren Gesichter gerendert, und die Schablone ist 0 (null), nachdem sie so oft erhöht wie dekrementiert wurde.

Die letzte Möglichkeit besteht darin, dass der Punkt innerhalb des Schattenvolumens liegt. In diesem Fall wird die Hinterseite des Schattenvolumes z-gepuffert, aber nicht das vordere Gesicht, sodass der Schablonenpuffer ein Wert ungleich 0 (null) ist. Das Ergebnis ist, dass Teile des Framepuffers, die im Schatten stehen, einen Schablonenwert ungleich 0 aufweisen. Um den Schatten tatsächlich zu rendern, wird die gesamte Szene mit einem alphageblendeten Polygon umgeblendet, das nur Pixel mit einem Schablonenwert ungleich 0 beeinflusst. Ein Beispiel für diese Technik finden Sie im Beispiel "Schattenvolumen", das im DirectX SDK enthalten ist.

Was sind die Texel-Ausrichtungsregeln? Gewusst wie eine 1:1-Zuordnung erhalten?

Dies wird vollständig in der Direct3D 9-Dokumentation erläutert. Die Zusammenfassung lautet jedoch, dass Sie Ihre Bildschirmkoordinaten um -0,5 pixel voreinziehen sollten, um eine ordnungsgemäße Ausrichtung an Texel zu erreichen. Die meisten Karten entsprechen jetzt ordnungsgemäß den Texel-Ausrichtungsregeln, es gibt jedoch einige ältere Karten oder Treiber, die dies nicht tun. Um diese Fälle zu behandeln, empfiehlt es sich, sich an den betreffenden Hardwareanbieter zu wenden und aktualisierte Treiber oder deren vorgeschlagene Problemumgehung anzufordern. Beachten Sie, dass diese Regel in Direct3D 10 nicht mehr gilt.

Welchen Zweck hat das D3DCREATE \_ PUREDEVICE-Flag?

Verwenden Sie das D3DCREATE _ PUREDEVICE-Flag während der Geräteerstellung, um ein reines Gerät zu erstellen. Ein reines Gerät speichert nicht den aktuellen Zustand (während Zustandsänderungen), was häufig die Leistung verbessert. Dieses Gerät erfordert auch die Verarbeitung von Hardwarevertex. Ein reines Gerät wird in der Regel verwendet, wenn die Entwicklung und das Debuggen abgeschlossen sind und Sie die beste Leistung erzielen möchten.

Ein Nachteil eines reinen Geräts ist, dass es nicht alle * Get-API-Aufrufe unterstützt. Dies bedeutet, dass Sie kein reines Gerät verwenden können, um den Pipelinezustand abzufragen. Dies erschwert das Debuggen während der Ausführung einer Anwendung. Im Folgenden finden Sie eine Liste aller Methoden, die von einem reinen Gerät deaktiviert werden.

Ein zweiter Nachteil eines reinen Geräts besteht darin, dass keine redundanten Zustandsänderungen gefiltert werden. Wenn Sie ein reines Gerät verwenden, sollte Ihre Anwendung die Anzahl der Zustandsänderungen in der Renderschleife auf ein Minimum reduzieren. Dies kann das Filtern von Zustandsänderungen umfassen, um sicherzustellen, dass Zustände nicht mehr als einmal festgelegt werden. Dieser Trade-Off ist anwendungsabhängig. Wenn Sie mehr als 1.000 Set-Aufrufe pro Frame verwenden, sollten Sie erwägen, die Redundanzfilterung zu nutzen, die automatisch von einem nicht reinen Gerät durchgeführt wird.

Wie bei allen Leistungsproblemen besteht die einzige Möglichkeit, zu wissen, ob Ihre Anwendung mit einem reinen Gerät besser abschneiden wird, darin, die Leistung Ihrer Anwendung mit einem reinen und einem nicht reinen Gerät zu vergleichen. Ein reines Gerät kann eine Anwendung beschleunigen, indem der CPU-Mehraufwand der API reduziert wird. Aber seien Sie vorsichtig! In einigen Szenarien verlangsamt ein reines Gerät Ihre Anwendung (aufgrund der zusätzlichen CPU-Arbeit, die durch redundante Zustandsänderungen verursacht wird). Wenn Sie nicht sicher sind, welcher Gerätetyp für Ihre Anwendung am besten geeignet ist und Sie keine redundanten Änderungen in der Anwendung filtern, verwenden Sie ein nicht reines Gerät.

Gewusst wie die Anzeigegeräte in einem System mit mehreren Monitoren aufzählen?

Die Enumeration kann durch eine einfache Iteration durch die Anwendung mithilfe von Methoden der IDirect3D9-Schnittstelle ausgeführt werden. Rufen Sie GetAdapterCount auf, um die Anzahl der Anzeigeadapter im System zu bestimmen. Rufen Sie GetAdapterMonitor auf, um zu bestimmen, mit welchem physischen Monitor ein Adapter verbunden ist (diese Methode gibt einen HMONITOR zurück, den Sie dann in der Win32-API GetMonitorInfo verwenden können, um Informationen zum physischen Monitor zu bestimmen). Das Bestimmen der Merkmale eines bestimmten Anzeigeadapters oder das Erstellen eines Direct3D-Geräts auf diesem Adapter ist so einfach wie die Übergabe der entsprechenden Adapternummer anstelle von D3DADAPTER DEFAULT beim Aufrufen von _ GetDeviceCaps, CreateDevice oder anderen Methoden.

Was ist mit fixed function Bumpmapping in D3D9 passiert?

Ab Direct3D 9 haben wir die Überprüfung auf Karten enger, die nur > zwei gleichzeitige Texturen unterstützen konnten. Bei bestimmten älteren Karten sind nur drei Texturstufen verfügbar, wenn Sie einen bestimmten Alphamodulierungsvorgang verwenden. Die gängigste Verwendung, für die Benutzer die drei Phasen verwenden, ist das Einbetten von Bumpmapping, und Sie können dies weiterhin mit D3D9 tun.

Das Höhenfeld muss im Alphakanal gespeichert werden und wird zum Modulieren des Lichtbeitrags verwendet, d.&160;B.:

// Stage 0 is the base texture, with the height map in the alpha channel
m_pd3dDevice->SetTexture(0, m_pEmbossTexture );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0 );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
if( m_bShowEmbossMethod )
{
 // Stage 1 passes through the RGB channels (SELECTARG2 = CURRENT), and 
 // does a signed add with the inverted alpha channel. 
 // The texture coords associated with Stage 1 are the shifted ones, so 
 // the result is:
 //    (height - shifted_height) * tex.RGB * diffuse.RGB
   m_pd3dDevice->SetTexture( 1, m_pEmbossTexture );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_ADDSIGNED );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE|D3DTA_COMPLEMENT );
   m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );

   // Set up the alpha blender to multiply the alpha channel 
   // (monochrome emboss) with the src color (lighted texture)
   m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
   m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA );
   m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
}

Dieses Beispiel ist zusammen mit anderen älteren Beispielen nicht mehr im aktuellen SDK-Release enthalten und wird in zukünftigen SDK-Releases nicht mehr bereitgestellt.

Geometry (Vertex)-Verarbeitung

Vertexstreams verwirren mich, wie sie funktionieren?

Direct3D stellt jeden Scheitelpunkt zusammen, der aus einem oder mehr Scheitelpunktstreams in den Verarbeitungsteil der Pipeline eingespeist wird. Nur ein Scheitelpunktstream entspricht dem alten Prä-DirectX 8-Modell, bei dem Scheitelpunkte aus einer einzelnen Quelle stammen. Mit DirectX 8 können verschiedene Scheitelpunktkomponenten aus verschiedenen Quellen stammen. Beispielsweise könnte ein Scheitelpunktpuffer Positionen und Normalwerte enthalten, während ein zweiter Farbwerte und Texturkoordinaten enthält.

Was ist ein Vertex-Shader?

Ein Vertex-Shader ist eine Prozedur zum Verarbeiten eines einzelnen Scheitelpunkts. Sie wird mithilfe einer einfachen assemblybasierten Sprache definiert, die von der D3DX-Hilfsprogrammbibliothek in einem Tokenstream zusammengestellt wird, der von Direct3D akzeptiert wird. Der Vertex-Shader nimmt als Eingabe einen einzelnen Scheitelpunkt und einen Satz konstanter Werte an. Es gibt eine Scheitelpunktposition (im Clip-Space) und optional einen Satz von Farben und Texturkoordinaten aus, die bei der Rasterung verwendet werden. Beachten Sie, dass bei einem benutzerdefinierten Vertex-Shader für die Vertexkomponenten keine Semantik mehr von Direct3D angewendet wird und Scheitelpunkte einfach beliebige Daten sind, die vom von Ihnen erstellten Vertex-Shader interpretiert werden.

Führt ein Vertex-Shader eine perspektivische Division oder Clipping durch?

Nein. Der Vertex-Shader gibt eine homogene Koordinate im Clipbereich für die transformierte Scheitelpunktposition aus. Perspektivische Division und Clipping erfolgt automatisch nach dem Shader.

Kann ich geometrie mit einem Vertex-Shader generieren?

Ein Vertex-Shader kann keine Scheitelpunkte erstellen oder zerstören. sie arbeitet gleichzeitig an einem einzelnen Scheitelpunkt, nimmt einen nicht verarbeiteten Scheitelpunkt als Eingabe und gibt einen einzelnen verarbeiteten Scheitelpunkt aus. Sie kann daher verwendet werden, um vorhandene Geometrie zu bearbeiten (Anwenden von Generierungs- oder Skinningvorgängen), aber tatsächlich keine neue Geometrie an sich zu generieren.

Kann ich einen benutzerdefinierten Vertex-Shader auf die Ergebnisse der Geometriepipeline mit fester Funktion anwenden (oder umgekehrt)?

Nein. Sie müssen das eine oder das andere auswählen. Wenn Sie einen benutzerdefinierten Vertex-Shader verwenden, sind Sie für die Durchführung der gesamten Vertextransformation verantwortlich.

Kann ich einen benutzerdefinierten Vertex-Shader verwenden, wenn er von meiner Hardware nicht unterstützt wird?

Ja. Die Direct3D-Software-Vertexverarbeitungs-Engine unterstützt benutzerdefinierte Vertex-Shader mit einer überraschend hohen Leistung vollständig.

Gewusst wie, ob die Hardware meinen benutzerdefinierten Vertex-Shader unterstützt?

Geräte, die Vertexshader in der Hardware unterstützen können, müssen das Feld D3DCAPS9::VertexShaderVersion ausfüllen, um die Versionsebene des von ihnen unterstützten Vertexshaders anzugeben. Jedes Gerät, das eine bestimmte Ebene des Vertex-Shaders unterstützt, muss alle rechtlichen Vertex-Shader unterstützen, die die Spezifikation für diese Ebene oder darunter erfüllen.

Wie viele Konstantenregister sind für Vertex-Shader verfügbar?

Geräte, die Im Vergleich zu 1.0-Vertex-Shadern unterstützen, müssen mindestens 96 konstante Register unterstützen. Geräte unterstützen möglicherweise mehr als diese Mindestanzahl und können dies über das Feld D3DCAPS9::MaxVertexShaderConst melden.

Kann ich Positionsdaten zwischen Scheitelungen mit unterschiedlichen Texturkoordinaten freigeben?

Das übliche Beispiel für diese Situation ist ein Würfel, in dem Sie für jedes Gesicht eine andere Textur verwenden möchten. Leider ist die Antwort nein. Derzeit ist es nicht möglich, die Scheitelpunktkomponenten unabhängig voneinander zu indizieren. Selbst bei mehreren Scheitelpunktstreams werden alle Datenströme zusammen indiziert.

Wenn ich eine indizierte Liste von Primitiven übersenden, werden von Direct3D alle Scheitelungen im Puffer oder nur diejenigen, die ich indiziert habe, verarbeiten?

Bei Verwendung der Softwaregeometriepipeline transformiert Direct3D zunächst alle Scheitelungen im bereich, den Sie übermittelt haben, anstatt sie bei Bedarf zu transformieren, während sie indiziert werden. Bei datendichten Daten (d. h. bei denen die meisten Scheitelungen verwendet werden) ist dies effizienter, insbesondere wenn SIMD-Anweisungen verfügbar sind. Wenn Ihre Daten spärlich gepackt sind (d. h., viele Scheitelungen werden nicht verwendet), sollten Sie eine Neurangierung der Daten in Erwägung ziehen, um zu viele redundante Transformationen zu vermeiden. Bei Verwendung der Hardwaregeometriebeschleunigung werden Scheitelungen in der Regel bei Bedarf transformiert.

Was ist ein Indexpuffer?

Ein Indexpuffer entspricht genau einem Scheitelpunktpuffer, enthält jedoch Indizes für die Verwendung in DrawIndexedPrimitive-Aufrufen. Es wird dringend empfohlen, aus denselben Gründen wie Scheitelpunktpuffer indexpuffer anstelle von unformatiert zugewiesenem Arbeitsspeicher zu verwenden, wenn dies möglich ist.

Ich sehe, dass 32-Bit-Indizes ein unterstützter Typ sind. kann ich sie auf allen Geräten verwenden?

Nein. Sie müssen das Feld D3DCAPS9::MaxVertexIndex überprüfen, um den maximalen Indexwert zu bestimmen, der vom Gerät unterstützt wird. Dieser Wert muss größer als 2 bis zur 16. Leistung -1 (0xffff) sein, damit Indexpuffer vom Typ D3DFMT _ INDEX32 unterstützt werden. Beachten Sie außerdem, dass einige Geräte möglicherweise 32-Bit-Indizes unterstützen, aber einen maximalen Indexwert unter 2 bis zur 32. Leistung –1 (0xffffffff). In diesem Fall muss die Anwendung den vom Gerät gemeldeten Grenzwert achten.

Unterstützt die S/W-Scheitelpunktverarbeitung 64 Bit?

Es gibt eine optimierte Scheitelpunktpipeline für x64, aber sie ist für IA64 nicht vorhanden.

Leistungsoptimierung

Wie kann ich die Leistung meiner Direct3D-Anwendung verbessern?

Im Folgenden finden Sie wichtige Bereiche, die Sie beim Optimieren der Leistung betrachten müssen:

Batchgröße

Direct3D ist für große Batches von Primitiven optimiert. Desto mehr Polygone können in einem einzigen Aufruf gesendet werden, desto besser. Eine gute Faustregel ist, durchschnittlich 1.000 Scheiteltices pro primitivem Aufruf zu erreichen. Unterhalb dieser Ebene erhalten Sie wahrscheinlich nicht die optimale Leistung, darüber hinaus, und Sie werden die Renditen und potenzielle Konflikte mit Parallelitätsüberlegungen verringern (siehe unten).

Statusänderungen

Das Ändern des Renderzustands kann ein aufwendiger Vorgang sein, insbesondere beim Ändern der Textur. Aus diesem Grund ist es wichtig, die Anzahl der pro Frame vorgenommenen Zustandsänderungen so weit wie möglich zu minimieren. Versuchen Sie außerdem, Änderungen des Scheitelpunkts oder Indexpuffers zu minimieren.

Hinweis

Ab DirectX 8 sind die Kosten für die Änderung des Scheitelpunktpuffers nicht mehr so teuer wie bei früheren Versionen, aber es ist dennoch eine bewährte Methode, Vertexpufferänderungen nach Möglichkeit zu vermeiden.

 

Parallelität

Wenn Sie das Rendering gleichzeitig mit einer anderen Verarbeitung durchführen können, profitieren Sie von der Systemleistung. Dieses Ziel kann mit dem Ziel der Reduzierung von Renderzustandsänderungen in Konflikt stehen. Sie müssen ein Gleichgewicht zwischen der Batchverarbeitung finden, um Zustandsänderungen zu reduzieren und Daten frühzeitig an den Treiber zu pushen, um Parallelität zu erzielen. Die Verwendung mehrerer Scheitelpunktpuffer in Roundrobin-Weise kann bei der Parallelität helfen.

Texturuploads

Das Hochladen von Texturen auf das Gerät verbraucht Bandbreite und führt zu einem Bandbreiten-Wettbewerb mit Scheitelpunktdaten. Aus diesem Grund ist es wichtig, den Texturspeicher nicht zu überbeladen. Dies würde dazu zwingen, dass Ihr Zwischenspeicherungsschema übermäßige Mengen von Texturen für jeden Frame hochladen würde.

Vertex- und Indexpuffer

Sie sollten immer Scheitelpunkt- und Indexpuffer anstelle von einfachen Blöcken des von der Anwendung zugewiesenen Arbeitsspeichers verwenden. Die Sperrsemantik für Scheitelpunkt- und Indexpuffer kann zumindest einen redundanten Kopiervorgang vermeiden. Bei einigen Treibern kann der Scheitelpunkt- oder Indexpuffer in einem besseren Arbeitsspeicher (z. B. im Video- oder AGP-Speicher) für den Zugriff durch die Hardware platziert werden.

Zustandsmakroblöcke

Diese wurden in DirectX 7.0 eingeführt. Sie bieten einen Mechanismus zum Aufzeichnen einer Reihe von Zustandsänderungen (einschließlich Beleuchtungs-, Material- und Matrixänderungen) in einem Makro, das dann mit einem einzigen Aufruf wiedergegeben werden kann. Das hat zwei Vorteile:

  • Sie verringern den Aufrufaufwand, indem Sie einen Aufruf anstelle von vielen aufrufen.
  • Ein treiberbewusster Treiber kann die Zustandsänderungen vorab analysieren und vor kompilieren, wodurch das Übermitteln an die Grafikhardware wesentlich schneller ist.

Zustandsänderungen können immer noch teuer sein, aber die Verwendung von Zustandsmakros kann dazu beitragen, zumindest einen Teil der Kosten zu senken. Verwenden Sie nur ein einzelnes Direct3D-Gerät. Wenn Sie auf mehrere Ziele rendern müssen, verwenden Sie SetRenderTarget. Wenn Sie eine Fensteranwendung mit mehreren 3D-Fenstern erstellen, verwenden Sie die CreateAdditionalSwapChain-API. Die Runtime ist für ein einzelnes Gerät optimiert, und es gibt erhebliche Geschwindigkeitssentzuge für die Verwendung mehrerer Geräte.

Welche primitiven Typen (Strips, Lüfter, Listen und so weiter) sollte ich verwenden?

Viele Gitternetze, die in echten Daten gefunden werden, verfügen über Scheitelungen, die von mehreren Polygonen gemeinsam genutzt werden. Um die Leistung zu maximieren, ist es wünschenswert, die Duplizierung in Scheitelwerten zu reduzieren, die transformiert und über den Bus an das Renderinggerät gesendet werden. Es ist klar, dass die Verwendung einfacher Dreieckslisten keine Scheitelpunktfreigabe erreicht, wodurch sie die am wenigsten optimale Methode ist. Die Wahl besteht dann zwischen der Verwendung von Strips und Lüftern, die eine bestimmte Konnektivitätsbeziehung zwischen Polygonen implizieren, und der Verwendung indizierter Listen. Wenn die Daten natürlich in Strips und Lüfter fallen, sind diese die am besten geeignete Wahl, da sie die an den Treiber gesendeten Daten minimieren. Das Zerteilen von Gittern in Strips und Lüfter führt jedoch häufig zu einer großen Anzahl separater Teile, was eine große Anzahl von DrawPrimitive-Aufrufen impliziert. Aus diesem Grund ist die effizienteste Methode in der Regel die Verwendung eines einzelnen DrawIndexedPrimitive-Aufrufs mit einer Dreiecksliste. Ein zusätzlicher Vorteil der Verwendung einer indizierten Liste ist, dass ein Vorteil auch dann genutzt werden kann, wenn aufeinander folgende Dreiecke nur einen einzelnen Scheitelpunkt teilen. Wenn Ihre Daten auf natürliche Weise in große Strips oder Lüfter fallen, sollten Sie also Strips oder Lüfter verwenden. Verwenden Sie andernfalls indizierte Listen.

Wie bestimmen Sie den Gesamttexturspeicher einer Karte, mit Ausnahme des AGP-Speichers?

IDirect3DDevice9::GetAvailableTextureMem gibt den gesamten verfügbaren Arbeitsspeicher einschließlich AGP zurück. Das Zuordnen von Ressourcen basierend auf der Annahme, wie viel Videoarbeitsspeicher Sie haben, ist keine gute Idee. Was geschieht beispielsweise, wenn die Karte unter einer Unified Memory Architecture (UMA) ausgeführt wird oder die Texturen komprimieren kann? Möglicherweise ist mehr Speicherplatz verfügbar, als Sie vielleicht gedacht haben. Sie sollten Ressourcen erstellen und nach Fehlern aufgrund von "nicht genügend Arbeitsspeicher" suchen und dann wieder auf die Texturen skalieren. Beispielsweise können Sie die obersten Mip-Ebenen Ihrer Texturen entfernen.

Was ist ein gutes Verwendungsmuster für Scheitelpunktpuffer, wenn ich dynamische Daten generiere?

  1. Erstellen Sie einen Scheitelpunktpuffer mithilfe der D3DUSAGE _ DYNAMIC- und D3DUSAGE _ WRITEONLY-Verwendungsflags und des D3DPOOL _ DEFAULT-Poolflags. (Geben Sie auch D3DUSAGE _ an. SOFTWAREPROCESSING, wenn Sie die Softwarevertexverarbeitung verwenden.)
  2. I = 0.
  3. Legen Sie den Zustand fest (Texturen, Renderstate usw.).
  4. Überprüfen Sie, ob im Puffer Speicherplatz vorhanden ist, z. B. I + M <= N? (Wobei M die Anzahl der neuen Scheitelpunkte ist.)
  5. Wenn ja, sperren Sie die VB mit D3DLOCK _ NOOVERWRITE. Dadurch wird Direct3D und dem Treiber mitgeteilt, dass Sie Scheitelpunkte hinzufügen und die zuvor als Batch ausgeführten Knoten nicht ändern. Wenn also ein DMA-Vorgang ausgeführt wird, wird er nicht unterbrochen. Wenn nein, wechseln Sie zu 11.
  6. Füllen Sie die M-Scheitelpunkte bei I aus.
  7. Entsperren.
  8. Rufen Sie Draw [ Indexed ] Primitive auf. Verwenden Sie für nicht indizierte Primitive I als StartVertex-Parameter. Stellen Sie bei indizierten Primitiven sicher, dass die Indizes auf den richtigen Teil des Scheitelpunktpuffers zeigen (es ist möglicherweise am einfachsten, den BaseVertexIndex-Parameter des SetIndices-Aufrufs zu verwenden, um dies zu erreichen).
  9. I += M.
  10. Wechseln Sie zu 3.
  11. Ok, also haben wir nicht mehr viel Platz, also beginnen wir mit einem neuen VB. Wir möchten nicht dieselbe verwenden, da möglicherweise ein DMA-Vorgang ausgeführt wird. Wir kommunizieren mit Direct3D und dem Treiber, indem wir die gleichen VB mit dem D3DLOCK _ DISCARD-Flag sperren. Dies bedeutet: "Sie können mir einen neuen Zeiger geben, da ich mit dem alten fertig bin und mir die alten Inhalte nicht mehr interessieren."
  12. I = 0.
  13. Wechseln Sie zu 4 (oder 6).

Warum muss ich weitere Informationen in der D3DVERTEXELEMENT9-Struktur angeben?

Ab Direct3D 9 ist die Vertexstreamdeklaration nicht mehr nur ein DWORD-Array, sie ist jetzt ein Array von D3DVERTEXELEMENT9-Strukturen. Die Runtime nutzt die zusätzlichen semantischen und Nutzungsinformationen, um den Inhalt von Scheitelpunktstreams an Vertex-Shader-Eingaberegister/-Variablen zu binden. Bei Direct3D 9 werden Scheitelpunktdeklarationen von Vertex-Shadern entkoppelt, was die Verwendung von Shadern mit Geometrien unterschiedlicher Formate vereinfacht, da die Laufzeit nur die Daten bindet, die der Shader benötigt.

Die neuen Scheitelpunktdeklarationen können entweder mit der festen Funktionspipeline oder mit Shadern verwendet werden. Für die Feste Funktionspipeline ist es nicht erforderlich, SetVertexShader aufzurufen. Wenn Sie jedoch zur festen Funktionspipeline wechseln möchten und zuvor einen Vertexshader verwendet haben, rufen Sie SetVertexShader(NULL) auf. Wenn dies abgeschlossen ist, müssen Sie weiterhin SetFVF aufrufen, um den FVF-Code zu deklarieren.

Wenn Sie Vertexshader verwenden, rufen Sie SetVertexShader mit dem Vertexshader-Objekt auf. Rufen Sie außerdem SetFVF auf, um eine Scheitelpunktdeklaration einzurichten. Hierbei werden die informationen verwendet, die implizit in der FVF enthalten sind. SetVertexDeclaration kann anstelle von SetFVF aufgerufen werden, da es Scheitelpunktdeklarationen unterstützt, die nicht mit einer FVF ausgedrückt werden können.

D3DX-Hilfsprogrammbibliothek

Welche Dateiformate werden von den Funktionen des D3DX-Imagedateiladeprogramm unterstützt?

Die D3DX-Bilddateiladefunktionen unterstützen BMP-, TGA-, JPG-, DIB-, PPM- und DDS-Dateien.

Die Textrenderingfunktionen in D3DX funktionieren scheinbar nicht, was kann ich nicht tun?

Ein häufiger Fehler bei der Verwendung der Funktionen ID3DXFont::D rawText besteht darin, eine Alphakomponente von 0 (null) für den Farbparameter anzugeben. führt zu vollständig transparentem (d. h. unsichtbaren) Text. Stellen Sie für vollständig nicht transparenten Text sicher, dass die Alphakomponente des Farbparameters vollständig ausgelastet ist (255).

Wie kann ich den Inhalt einer Oberfläche oder Textur in einer Datei speichern?

Das DirectX 8.1 SDK hat der D3DX-Bibliothek speziell für diesen Zweck zwei Funktionen hinzugefügt: D3DXSaveSurfaceToFile() und D3DXSaveTextureToFile(). Diese Funktionen unterstützen das Speichern eines Bilds in einer Datei im BMP- oder DDS-Format. In früheren Versionen mussten Sie die Oberfläche sperren und die Bilddaten lesen und dann in eine Bitmapdatei schreiben. Informationen zum Schreiben einer Funktion zum Speichern von Bitmaps finden Sie unter Speichern eines Bilds.

Alternativ können GDI+ verwendet werden, um das Image in einer Vielzahl von Formaten zu speichern. Dies erfordert jedoch zusätzliche Unterstützungsdateien, die mit Ihrer Anwendung verteilt werden müssen.

Wie kann ich die High Level Shader Language (HLSL) in meinem Spiel verwenden?

Es gibt drei Möglichkeiten, wie die Microsoft High Level Shader Language (HLSL) in Ihre Spiel-Engine integriert werden kann:

  • Kompilieren Sie Ihre Shaderquelle in eine Vertex- oder Pixelschattierungsassembly (mithilfe des Befehlszeilenhilfsprogramms fxc.exe), und verwenden Sie D3DXAssembleShader() zur Laufzeit. Auf diese Weise kann sogar ein DirectX 8-Spiel die Leistungsfähigkeit von HLSL nutzen.
  • Verwenden Sie D3DXCompileShader(), um Ihre Shaderquelle in tokenstream- und constant table-Form zu kompilieren. Laden Sie zur Laufzeit den Tokenstream und die konstante Tabelle, und rufen Sie CreateVertexShader() oder CreatePixelShader() auf dem Gerät auf, um Ihre Shader zu erstellen.
  • Am einfachsten können Sie das D3DX Effects-System nutzen, indem Sie D3DXCreateEffectFromFile() oder D3DXCreateEffectFromResource() mit Ihrer Effect-Datei aufrufen.

Welchen Zweck hat das neue Shadercompilerflag?

Ab dem DirectX SDK vom Dezember 2006 wurde der neue HLSL-Compiler, der für Direct3D 10 entwickelt wurde, für Direct3D 9-Ziele aktiviert. Der neue Compiler unterstützt ps _ 1 _ x-Ziele nicht und ist jetzt der Standardcompiler für alle Direct3D HLSL-Shader. Ein Flag für Abwärtskompatibilität kann verwendet werden, um die Kompilierung von PS _ 1 _ x-Zielen als PS _ 2 _ 0-Ziele zu erzwingen.

Anwendungen, die den Legacycompiler verwenden möchten, können dies auch weiterhin tun, indem sie zur Laufzeit ein Flag bereitstellen (siehe Compilerflags)oder einen Schalter bereitstellen, wenn fxc verwendet wird.

Was ist die richtige Methode, um Shader aus einem Effekt abzurufen?

Verwenden Sie D3DXCreateEffect, um einen ID3DXEffect zu erstellen, und verwenden Sie dann GetPassDesc, um einen D3DXPASS _ DESC abzurufen. Diese Struktur enthält Zeiger auf Scheitelpunkt- und Pixel-Shader.

Verwenden Sie id3DXEffectCompiler::GetPassDesc nicht. Vertex- und Pixel-Shaderhandles, die von dieser Methode zurückgegeben werden, sind NULL.

Wozu dient die intrinsische HLSL noise()-Eigenschaft?

Die intrinsische Rauschfunktion generiert Perlinrauschen, wie von Ken Perlin definiert. Die HLSL-Funktion kann derzeit nur zum Füllen von Texturen in Textur-Shadern verwendet werden, da die aktuelle h/w-Methode die Methode nicht nativ unterstützt. Textur-Shader werden in Konjuktion mit den D3DXFill * Texture()-Funktionen verwendet, die nützliche Hilfsfunktionen sind, um prozedural definierte Texturen während der Ladezeit zu generieren.

Gewusst wie erkennen, ob das Pixelshadermodell 2.0 oder 2.a verwendet werden soll?

Sie können die Funktionen D3DXGetPixelShaderProfile() und D3DXGetPixelShaderProfile() verwenden, die eine Zeichenfolge zurückgeben, die bestimmt, welches HLSL-Profil am besten für das ausgeführte Gerät geeignet ist.

Gewusst wie auf die Parameter in meinen vorkompilierten Effekt-Shadern zugreifen?

Über die ID3DXConstantTable-Schnittstelle, die für den Zugriff auf die Konstantentabelle verwendet wird. Diese Tabelle enthält die Variablen, die von übergeordneten Sprach-Shadern und -Effekten verwendet werden.

Gibt es eine Möglichkeit, Benutzerdaten zu einem Effekt oder einer anderen Ressource hinzuzufügen?

Ja, um private Daten festzulegen, die Sie SetPrivateData aufrufen (pReal ist das D3D-Texturobjekt, pSpoof ist das umschlossene Texturobjekt).

hr = pReal->SetPrivateData(IID_Spoof, &pSpoof, 
            sizeof(IDirect3DResource9*), 0)));

So suchen Sie den umschlossenen Zeiger:

    IDirect3DResource9* pSpoof;
    DWORD dwSize = sizeof(pSpoof);
    hr = pReal->GetPrivateData(IID_Spoof, (void*) &pSpoof, &dwSize);

Warum verlangsamt sich das Rendering eines ID3DXMesh-Objekts erheblich, nachdem ich Teilmengen definiert habe?

Sie haben das Gitternetz wahrscheinlich nicht optimiert, nachdem Sie die Gesichtsattribute definiert haben. Wenn Sie Attribute angeben und dann ID3DXMesh::D rawSubset() aufrufen, muss diese Methode eine Suche im Gitternetz nach allen Gesichtern durchführen, die die angeforderten Attribute enthalten. Darüber hinaus befinden sich die gerenderten Gesichter wahrscheinlich in einem zufälligen Zugriffsmuster und verwenden daher keinen Scheitelpunktcache. Nachdem Sie die Gesichtsattribute für Ihre Teilmengen definiert haben, rufen Sie die Methoden ID3DXMesh::Optimize oder ID3DXMesh::OptimizeInPlace auf, und geben Sie eine Optimierungsmethode von D3DXMESHOPT _ ATTRSORT oder stärker an. Beachten Sie, dass Sie für eine optimale Leistung mit dem D3DXMESHOPT _ VERTEXCACHE-Flag optimieren sollten, das auch Scheitelpunkte neu anordnt, um eine optimale Vertexcacheauslastung zu erzielen. Das für ein D3DX Mesh generierte Adjazenzarray verfügt über drei Einträge pro Gesicht, aber einige Gesichter verfügen möglicherweise nicht über angrenzende Gesichter an allen drei Rändern. Wie wird diese codiert? Einträge, bei denen keine angrenzenden Gesichter vorhanden sind, werden als 0xffffffff codiert.

Ich habe viel über die Vorberechnung von Radiance Transfer (PRT) gehört, wo kann ich mehr erfahren?

PRT ist ein neues Feature von D3DX, das im Sommer 2003 SDK Update hinzugefügt wurde. Sie ermöglicht das Rendern komplexer Beleuchtungsszenarien wie globale -Llumination, soft shadowing und Sub-Surface Scatter in Echtzeit. Das SDK enthält Dokumentation und Beispiele für die Integration der Technologie in Ihr Spiel. Die Beispiele PRT-Demobeispiel und LocalDeformablePRT-Beispiel veranschaulichen, wie der Simulator für Pro-Scheitelpunkt- bzw. Pro-Pixel-Beleuchtungsszenarien verwendet wird. Weitere Informationen zu diesem und anderen Themen finden Sie auch auf der Webseite von Peter Pike Sloan.

Wie kann ich in einer Textur rendern und Antialiasing verwenden?

Erstellen Sie mit Direct3DDevice9::CreateRenderTarget ein Multisampled-Renderziel. Nachdem sie die Szene auf dieses Renderziel gerendert hat, wird StretchRect von ihr in eine Renderzieltextur gestreckt. Wenn Sie änderungen am Textre des Offscreens (z. B. unscharf oder aufbrühend) nehmen, kopieren Sie ihn zurück in den Hintergrundpuffer, bevor Sie present() präsentieren.

DirectSound-Fragen

Warum kommt es beim Starten meiner Anwendung zu einem Burst statischer Daten? Ich sehe dieses Problem auch bei anderen Anwendungen.

Wahrscheinlich haben Sie die DirectX-Debuglaufzeit installiert. Die Debugversion der Laufzeit füllt Puffer mit statischen Puffern, damit Entwickler Fehler mit nicht initialisierten Puffern abfangen können. Sie können den Inhalt eines DirectSound-Puffers nach der Erstellung nicht garantieren. Insbesondere können Sie nicht davon ausgehen, dass ein Puffer mit auf 0 (null) gesetzt wird.

Warum kommt es zwischen dem Ändern eines Effektparameters und dem Hören der Ergebnisse zu einer Verzögerung?

Änderungen an wirksamen Parametern werden nicht immer sofort in DirectX 8 vorgenommen. Zur Effizienz verarbeitet DirectSound 100 Millisekunden sound-Daten in einem Puffer, beginnend beim Wiedergabecursor, bevor der Puffer abgespielt wird. Diese Vorverarbeitung erfolgt nach allen folgenden Aufrufen:

IDirectSoundBuffer8::SetCurrentPosition
IDirectSoundBuffer8::SetFX
IDirectSoundBuffer8::Stop
IDirectSoundBuffer8::Unlock

Ab DirectX 9 löst ein neuer FX-Verarbeitungsalgorithmus, der Effekte mit Just-in-Time verarbeitet, dieses Problem und verringert die Latenz. Der Algorithmus wurde dem IDirectSoundBuffer8::P lay()-Aufruf hinzugefügt, zusammen mit einem zusätzlichen Thread, der Effekte direkt vor dem Schreibcursor verarbeitet. Sie können also jederzeit Parameter festlegen, die erwartungsgemäß funktionieren. Beachten Sie jedoch, dass es bei einem Wiedergabepuffer eine kleine Verzögerung (in der Regel 100 ms) gibt, bevor Sie die Parameteränderung hören, da die Audiodaten zwischen den Wiedergabe- und Schreibcursorn (und etwas mehr Auf padding) zu diesem Zeitpunkt bereits verarbeitet wurden.

Gewusst wie, ob DSound installiert ist?

Wenn Sie DirectSoundEnumerate() nicht zum Auflisten der verfügbaren DSound-Geräte verwenden müssen, verknüpfen Sie Ihre Anwendung nicht mit dsound.lib, sondern verwenden Sie sie über coMs CoCreateInstance(CLSID DirectSound...), und initialisieren Sie dann das DSound-Objekt mit _ Initialize(NULL). Wenn Sie DirectSoundEnumerate() verwenden müssen, können Sie dsound.dll LoadLibrary("dsound.dll" ) dynamisch laden. und greifen mithilfe von GetProcAddress("DirectSoundEnumerateA/W") und GetProcAddress("DirectSoundCreateA/W") auf seine Methoden zu.

Gewusst wie Multichannel-Audio mit WAVEFORMATEXTENSIBLE erstellen?

Wenn Sie in den DirectSound-Hilfedateien keine Antwort auf Ihre Frage finden, finden Sie unter Multiple Channel Audio Data and WAVE Files (Audiodaten für mehrere Kanäle und WAVE-Dateien) einen guten Artikel mit weitere Informationen.

Wie kann ich DirectSound Voice Manager mit Eigenschaftensätzen wie EAX verwenden?

Wenn Sie in DirectSound 9.0 einen Puffer duplizieren, ist es jetzt möglich, die IDirectSoundBuffer8-Schnittstelle für den doppelten Puffer zu erhalten, wodurch Sie Zugriff auf die AcquireResources-Methode erhalten. Dadurch können Sie einen Puffer dem DSBCAPS _ LOCDEFER-Flag einer Hardwareressource zuordnen. Anschließend können Sie Ihre EAX-Parameter für diesen Puffer festlegen, bevor Sie Play() aufrufen müssen.

Ich habe Probleme mit unzuverlässigem Verhalten bei der Verwendung von Cursorpositionsbenachrichtigungen. Wie kann ich genauere Informationen erhalten?

Es gibt einige kleine Fehler in verschiedenen Versionen von DirectSound, dem Windows Core-Audiostapel und Audiotreibern, die Cursorpositionsbenachrichtigungen unzuverlässig machen. Vermeiden Sie Cursorpositionsbenachrichtigungen, es sei denn, Sie verwenden eine bekannte HW/SW-Konfiguration, bei der Sie wissen, dass sich Benachrichtigungen gut verhalten. Für die Positionsnachverfolgung ist GetCurrentPosition() eine sicherere Technik.

Bei Verwendung von GetCurrentPosition() kommt es zu Leistungseinbußen. Wie kann ich die Leistung verbessern?

Jeder GetCurrentPosition()-Aufruf für jeden Puffer verursacht einen Systemaufruf, und Systemaufrufe sollten minimiert werden, da sie eine große Komponente des CPU-Speicherbedarfs von DSound sind. Bei NT (Win2K und XP) bewegen sich die Cursor in SW-Puffern (und HW-Puffern auf einigen Geräten) in Schritten von 10 ms, sodass der Aufruf von GetCurrentPosition() alle 10 ms ideal ist. Wenn sie häufiger als alle 5 ms aufruft, kommt es zu leistungseinbußen.

Meine DirectSound-Anwendung nimmt zu viel CPU-Zeit in Anspruch oder wird langsam ausgeführt. Kann ich meinen Code optimieren?

Es gibt mehrere Möglichkeiten, die Leistung Ihres Audiocodes zu verbessern:

  • Rufen Sie GetCurrentPosition nicht zu oft auf. Jeder GetCurrentPosition()-Aufruf für jeden Puffer verursacht einen Systemaufruf, und Systemaufrufe sollten minimiert werden, da sie eine große Komponente des CPU-Speicherbedarfs von DSound sind. Bei NT (Win2K und XP) bewegen sich die Cursor in SW-Puffern (und HW-Puffern auf einigen Geräten) in Schritten von 10 ms, sodass der Aufruf von GetCurrentPosition() alle 10 ms ideal ist. Wenn sie häufiger als alle 5 ms aufruft, kommt es zu einer Verschlechterung der Leistungseinbußen.

  • Verwenden Sie eine separate, niedrigere Bildfrequenz für Audio. Heutzutage Windows viele Spiele 100 Frames pro Sekunde überschreiten, und es ist in den meisten Fällen nicht erforderlich, Ihre 3D-Audioparameter mit der gleichen Bildfrequenz zu aktualisieren. Die Verarbeitung Ihrer Audiodaten pro Sekunde oder drittem Grafikframe oder alle 30 ms oder so kann die Anzahl der Audioaufrufe in Ihrer gesamten Anwendung erheblich reduzieren, ohne die Audioqualität zu verringern.

  • Verwenden Sie DS3D _ DEFERRED für 3D-Objekte. Die meisten Soundkarten reagieren sofort auf Parameteränderungen, und in einem einzelnen Frame kann sich vieles ändern, insbesondere wenn Sie die Position oder Ausrichtung des Listeners ändern. Dies führt dazu, dass die Soundkarte/CPU viele unnötige Berechnungen durchführen. Eine weitere schnelle und universelle Optimierung besteht also in der Verzögerung einiger Parameteränderungen und deren Commit am Ende des Frames.

    oder verwenden Sie mindestens SetAllParameters anstelle einzelner Set3DParamX-Aufrufe für Puffer.

    Ebenso sollten Sie mindestens SetAllParamenters-Aufrufe für 3D-Puffer anstelle der einzelnen Set3DParamX-Aufrufe verwenden. Versuchen Sie nach Möglichkeit, Systemaufrufe zu minimieren.

  • Keine redundanten Aufrufe; Speichern und sortieren Sie eine Liste von Wiedergabeaufrufen. Häufig gibt es in einem Audioupdateframe zwei Anforderungen, neue Sounds wieder zu geben. Wenn die Anforderungen beim Eintreffen verarbeitet werden, kann der erste neue Sound gestartet und dann sofort der zweite angeforderte Sound ersetzt werden. Dies führt zu redundanten Berechnungen, einem unnötigen Wiedergabeaufruf und einem unnötigen Stoppaufruf. Es ist besser, eine Liste von Anforderungen zu speichern, damit neue Sounds abgespielt werden, damit die Liste sortiert werden kann und nur die Stimmen, die mit der Wiedergabe beginnen sollten, tatsächlich jemals abgespielt werden.

    Außerdem sollten Sie lokale Kopien der 3D- und EAX-Parameter für jede Soundquelle speichern. Wenn eine Anforderung zum Festlegen eines Parameters auf einen bestimmten Wert gestellt wird, können Sie überprüfen, ob der Wert tatsächlich vom letzten festgelegten Wert abgesehen ist. Wenn nicht, muss der Aufruf nicht vorgenommen werden.

    Obwohl der Soundkartentreiber dieses Szenario wahrscheinlich erkennt und die (gleiche) Berechnung nicht erneut durchführen wird, muss der Audioaufruf den Audiotreiber erreichen (über einen Ringübergang), und dies ist bereits ein langsamer Vorgang.

Wenn ich einen Puffer streame, führt dies dazu, dass er zu einem Fehler führt und eine schlechte Leistung auf ich habe. Was ist die beste Möglichkeit zum Streamen eines Puffers?

Beim Streamen von Audiodaten in einen Puffer gibt es zwei grundlegende Algorithmen: After-Write-Cursor (AWC) und Before-Play-Cursor (BPC). AWC minimiert die Latenz auf Kosten einer Störung, während BPC das Gegenteil ist. Da es in der Regel keine interaktiven Änderungen am gestreamten Sound gibt, ist diese Art von Latenz selten ein Problem für Spiele und ähnliche Anwendungen, sodass BPC der geeignetere Algorithmus ist. In AWC wird jedes Mal, wenn ihr Streamingthread ausgeführt wird, die Daten in Ihren Schleifenpuffern bis zu N ms über die Schreibcursor hinaus auf -Puffern (in der Regel N=40 oder so, um jittern zu ermöglichen Windows planung zu ermöglichen). In BPC schreiben Sie immer so viele Daten wie möglich in die Puffer und füllen sie bis zu ihren Wiedergabecursorn (oder vielleicht 32 Bytes vorher), um Treiber zu ermöglichen, die ihren Wiedergabecursorfortschritt falsch melden.

Verwenden Sie BPC, um glimimize zu mimimisieren, und verwenden Sie Puffer mit einer Größe von 100 ms oder höher, auch wenn Ihre Spiele auf Ihrer Testhardware nicht störungsbeschleunigt werden, wird dies auf einem computerexternen Computer durchgeführt.

Ich spiele die gleichen Sounds immer wieder und sehr schnell und manchmal auch nicht richtig, oder der Play()-Aufruf dauert sehr lange. Wie sollte ich vorgehen?

Die Startlatenz (die sich von der oben erwähnten Streaminglatenz abzieht) kann bei hardwarebeschleunigenden Komponenten ein Problem sein (der Play()-Aufruf dauert auf bestimmten Soundkarten manchmal sehr lange). Wenn Sie diese Latenz wirklich reduzieren möchten, besteht ein praktischer Trick bei Twitch-Tönen (Stichaufnahmen, Luftaufnahmen und so weiter) in der Immer-Schleifen- und Stille-Wiedergabe einiger Puffer. Wenn Sie einen Twitch-Sound wieder geben müssen, wählen Sie einen freien Puffer aus, sehen Sie, wo sich der Schreibcursor befindet, und legen Sie den Sound direkt hinter dem Schreibcursor in den Puffer. Einige Soundcards führen für zurückgestellte Eigenschaften, von denen ich weiß, dass sie unterstützt werden, zu einem QuerySupport-Fehler. Gibt es eine Problemumgehung? Sie können einfach QuerySupport für die nicht verzögerten Versionen der Eigenschaften verwenden und trotzdem verzögerte Einstellungen verwenden. Dieses Problem kann auch mit den neuesten Soundcardtreibern behoben werden.

Gewusst wie SIE WAV-Dateien in WMA codieren?

Weitere Informationen finden Sie in der Dokumentation Windows Media Encoder unter: Windows Media Encoder 9-Serie.

Gewusst wie sie MP3-Dateien mit DirectSound decodieren?

DirectSound unterstützt die MP3-Decodierung nicht nativ. Sie können die Dateien selbst im Voraus decodieren (mithilfe eines ACM-Codecs eines DirectShow-Filters) oder einfach DirectShow selbst verwenden, wodurch die Decodierung für Sie möglich ist. Anschließend können Sie die resultierenden PCM-Audiodaten in Ihre DirectSound-Puffer kopieren.

DirectX-Erweiterungen für Alias Maya

Warum werden meine NURBS nicht angezeigt?

NURBS werden nicht unterstützt. Sie können sie in Polygongitternetze konvertieren.

Warum werden meine SUBDs nicht angezeigt?

SUBDs werden nicht unterstützt. Sie können sie in Polygongitternetze konvertieren.

Warum sieht meine Animation in der X-Datei anders aus als die Animation im Vorschaufenster?

Das Vorschaufenster ist nicht im strengsten Sinn animiert. Es wird keine Animation abspielt, sondern stattdessen mit dem aktuellen Zustand der Maya-Szene synchronisiert. Beim Exportieren der Animation werden die Matrizen bei jeder Transformation in Skalierung, Drehung (Quaternion) und Übersetzungskomponenten (häufig als SRTs bezeichnet) zergelegt. SRTs sind wünschenswerter als Matrizen, da sie gut interpolieren, eine kompaktere Form der Daten bereitstellen und unabhängig komprimiert werden können. Nicht alle Matrizen können in SRTs zerlegen. Wenn sie nicht zersetzt werden können, sind die resultierenden SRTs unbekannt, sodass kleine Fehler in der Animation erkannt werden können. Die beiden Features in Maya, die am häufigsten Probleme während der Zerlegung verursachen, sind Hear- und off-center-Drehungen oder Skalierungen. Wenn dieses Problem auftreten sollte, weil Sie dreh- oder skalierungsbasierte Rotationen verwenden, sollten Sie zusätzliche Transformationen hinzufügen, um die Hierarchieebene zu erhöhen.

Wenn die D3DX-Animation SRTs unterstützt, sieht sie wie folgt aus:

[S]x[R]x[T]

Mayas Matrizen sind viel komplizierter und erfordern einen erheblichen zusätzlichen Prozess, der wie folgt aussieht:

[SpInv]x[S]x[Sh]x[Sp]x[St]x[RpInv]x[Ro]x[R]x[Rp]x[Rt]x[T]

Ich habe mein Gitter mit RigidSkin skinned, aber das Gitternetz (oder der Teil) bewegt sich nicht. Warum?

Maya es Rigid Skin wird derzeit nicht unterstützt. Verwenden Sie Smooth Skin.

Wo ist mein gesamtes IK in der X-Datei enthalten?

X-Dateien unterstützen IK nicht. Stattdessen werden die IK-Lösungen in die Frames gebacken, die in der X-Datei gespeichert sind.

Warum werden keine meiner Materialfarben außer DirectXShaders angezeigt?

Die DirectX-Erweiterungen für Maya unterstützen derzeit nur DirectXShader-Materialien für Vorschau und Export. In einer zukünftigen Version werden möglicherweise andere Materialien unterstützt.

Fragen zu XInput

Kann ich DirectInput verwenden, um die Trigger zu lesen?

Ja, aber sie fungieren als die gleiche Achse. Daher können Sie die Trigger nicht unabhängig mit DirectInput lesen. Mit XInput geben die Trigger separate Werte zurück.

Weitere Informationen dazu, warum DirectInput die Trigger als eine Achse interpretiert, finden Sie unter Verwenden des Xbox 360 Controller mit DirectInput.

Wie viele Controller werden von XInput unterstützt?

XInput unterstützt 4 Controller, die gleichzeitig angeschlossen sind.

Unterstützt XInput nicht gängige Controller?

Nein, nicht.

Sind allgemeine Controller über DirectInput verfügbar?

Ja, Sie können über DirectInput auf allgemeine Controller zugreifen.

Gewusst wie erzwingen Sie Feedback zu den gängigen Controllern?

Verwenden Sie die XInputSetState-Funktion.

Warum ändert sich mein Standardaudiogerät?

Beim Verbinden des Headsets fungiert das Headset des Controllers als USB-Standardaudiogerät. Wenn es verbunden ist, ändert sich Windows automatisch, sodass dieses USB-Audiogerät standardmäßig verwendet wird. Da der Benutzer wahrscheinlich nicht möchte, dass alle Audiodaten das Headset durchlaufen, muss er es manuell an die ursprüngliche Einstellung anpassen.

Gewusst wie die Beleuchtung auf dem Controller zu steuern?

Die Beleuchtung auf dem Controller ist vom Betriebssystem vorgegeben und kann nicht geändert werden.

Gewusst wie auf die Schaltfläche Xbox 360 in meinen Anwendungen zugreifen?

Leider ist diese Schaltfläche für die zukünftige Verwendung reserviert.

Wo erhalte ich Treiber?

Die Treiber sind über Windows Update verfügbar.

Wie wird die Controller-ID bestimmt?

Beim XInput-Start wird die ID nicht deterministisch von der XInput-Engine und den angeschlossenen Controllern bestimmt. Wenn Controller während der Ausführung einer XInput-Anwendung angeschlossen werden, weist das System dem neuen Controller die niedrigste verfügbare Zahl zu. Wenn ein Controller getrennt ist, wird seine Nummer wieder verfügbar gemacht.

Gewusst wie die Audiogeräte für den Controller abrufen?

Verwenden Sie die XInputGetDSoundAudioDeviceGuids-Funktion. Weitere Informationen finden Sie im AudioController-Beispiel.

Was soll ich tun, wenn ein Controller nicht an das Netz gekoppelt ist?

Wenn der Controller von einem Player verwendet wurde, sollten Sie das Spiel anhalten, bis die Verbindung des Controllers wiederhergestellt ist und der Spieler eine Schaltfläche drückt, um zu signalisieren, dass er zum Anhalten bereit ist.