Hardwareinformationen
von Jack Hoxley (übersetzt von Daniel Noll)
Einführung
Enumeration ist eine ziemlich einfache Idee, mit der Sie sich herumschlagen müssen - nebenbei brauchen Sie sie um ein weitergebbares DirectX-Programm zu erstellen. Enumeration ist eine Technik mit der Sie herausfinden können, was Ihre Hardware kann - Sie stellen Fragen(was der Computer machen kann) und er wird Ihnen sagen ob oder ob nicht. In diesen Tutorien, werden wir immer feste Einstellungen, wie Auflösungen und Renderer, benutzen - keinen würde es schocken, wenn das Programm nicht läuft, aber in einem richtigen Programm(wie ein veröffentlichtes Spiel), das viele Leute benutzen, wollen Sie es so solid wie einen Stein machen.
In Spielen wird Enumeration z.B. benutzt, um eine Liste von möglichen Auflösungen anzuzeigen, in denen Sie das Spiel spielen können - es wird aber außerdem an Stellen benutzt, wo Sie sie wahrscheinlich nicht erkennen. Ein Spiel kann z.B. die Hardware nach der Fähigkeit zum Bump-mapping durchsuchen; wenn der Enumerationsprozess True zurückgibt, dann bekommen Sie ein Spiel mit Bump-mapping, wenn nicht, kann das Spiel ohne Bump-mapping auskommen, es kann aber auch etwas anderes tun(z.B. Software Bump-mapping).
Dieses Kapitel soll beide Typen der Enumeration erklären; Displaymodus/Renderer- und Hardwareenumeration. Es gibt sehr viele Hardwareeigenschaften zum Abfragen, so das wir hier nur die Struktur behandeln - Wir werden in späteren Kapiteln noch ab und zu mal Enumeration benutzten, alle wichtigen Details werden dann besprochen. Falls Sie das DirectX8 SDK haben, können Sie alle möglichen Information dazu abrufen.
Display Device-, Adapter- und Auflösungsenumeration
Zuerst wollen wir wissen in welchen Modi wir unser Programm starten können. Im Fenstermodus ist es ziemlich egal, aber im Fullscreen-Modus müssen Sie einen korrekten Displaymodus einstellen, den die Hardware unterstützt - oder bekommen einen Fehler, wenn Sie versuchen ein Device zu erstellen. Hier ist eine einfach Hierarchie, die Sie sich für die Enumeration der Displaymodi und Formaten merken müssen:
ADAPTER => DEVICE => AUFLÖSUNGEN UND FÄHIGKEITEN
Zuerst müssen wir die verfügbaren Adapter finden, dann suchen wir uns eine unterstützte Device(HAL oder Reference) für einen Adapter aus und finden damit die unterstützten Auflösungen und Fähigkeiten heraus. So, zuerst zeige ich Ihnen einen Weg um die Adapter zu enummerieren:
'D3D sollte ein gültiges Objekt vom Typ Direct3D8 sein. 'AdapterInfo sollte eine erstellte Variable vom Typ 'D3DADAPTER_IDENTIFIER8 sein. Private Sub EnumerateAdapters() Dim I As Integer, sTemp As String, J As Integer 'Dieser Wert ist entweder 1 oder 2 nAdapters = D3D.GetAdapterCount For I = 0 To nAdapters - 1 'Die wichtigen Daten erfassen D3D.GetAdapterIdentifier I, 0, AdapterInfo 'Den Namen des Adapters herausbekommen. Leider ist er 'als eine Liste von Zeichencodes gespeichert, 'welche wir in einen String parsen müssen. ' - Fragen Sie mich nicht warum; scheint 'ein bisschen umständlich zu sein :) sTemp = "" 'Reset the string ready for our use For J = 0 To 511 sTemp = sTemp & Chr$(AdapterInfo.Description(J)) Next J sTemp = Replace(sTemp, Chr$(0), " ") cmbAdapters.AddItem sTemp Next I End Sub
Wahrscheinlich werden Sie das Ausgabe-Control ändern - im Moment kommt alles in die "cmbAdapters"-Combobox. Der obere Code zählt praktisch nur die Anzahl der verfügbaren Adapter(fast immer 1), dann geht er sie durch und sammelt alle wichtigen Werte ein (in die AdapterInfo-Variable). Sollten Sie mehr Info über einen Adapter brauchen als seinen Namen, können Sie diese (brauchbaren) Informationen bekommen:
Description: | Eine kleine Information über den Adapter. Dazu da um Sie dem Benutzer anzuzeigen. |
Driver: | Welchen Treiber die Hardware benutzt - wieder um dem Benutzer anzuzeigen. (Es wird normalerweise eine DLL sein) |
DeviceID: | Eine Nummer die den Chip-Typ identifiziert. Kann 0 sein, falls unbekannt. |
DeviceIdentifier: | Eine Gruppe von vier Variablen, die die benutzte Hardware wiedergibt. Wenn Sie die Hardware erkennen wollen, dann benutzten Sie am besten diese Variable. |
Jetzt können wir nachschauen, was für Devices die Adapter unterstützen. Software Renderer sind ein größeres Thema and sind bis jetzt wahrscheinlich noch nicht nötig, also lassen wir sie ganz aus dem Spiel. Stattdessen schauen wir einfach nach, ob der HAL unterstützt wird; der Reference-Rasterer sollte immer vorhanden sein, also setzten wir das einfach voraus.
Private Sub EnumerateDevices() On Local Error Resume Next 'Fehlerbehandlung Dim Caps As D3DCAPS8 D3D.GetDeviceCaps cmbAdapters.ListIndex, _ D3DDEVTYPE_HAL, Caps cmbDevice.AddItem "Reference Rasterizer (REF)" 'Reference Device ist immer vorhanden If Err.Number <> D3DERR_NOTAVAILABLE Then cmbDevice.AddItem "Hardware Acceleration (HAL)" End If End Sub
Eine etwas radikale Methode, aber es funktioniert und ist ziemlich einfach. Wenn wir versuchen irgendetwas von der HAL-Device zu lesen, dann bekommen wir den Fehlercode "D3DERR_NOTAVAILABLE".
Das letzte was wir überprüfen wollen, sind die verfügbaren Display-Modi. Das kann nur dann geschehen, wenn wir einen Adapter und einen Device ausgesucht haben.
Private Sub EnumerateDispModes(Renderer As Long) cmbRes.Clear 'Alle Einträge löschen Dim I As Integer, ModeTemp As D3DDISPLAYMODE nModes = D3D.GetAdapterModeCount(cmbAdapters.ListIndex) For I = 0 To nModes - 1 'Durch alle Modi 'laufen und Daten sammeln Call D3D.EnumAdapterModes(cmbAdapters.ListIndex, _ I, ModeTemp) 'Zuerst wird alles in zwei Gruppen aufgeteilt - ' 16 Bit oder 32 Bit If ModeTemp.Format = D3DFMT_R8G8B8 Or _ ModeTemp.Format = D3DFMT_X8R8G8B8 Or _ ModeTemp.Format = D3DFMT_A8R8G8B8 Then 'Überprüfen ob der Device OK ist If D3D.CheckDeviceType(cmbAdapters.ListIndex, _ Renderer, ModeTemp.Format, _ ModeTemp.Format, False) >= 0 Then 'zur Liste hinzufügen cmbRes.AddItem ModeTemp.Width & "x" & _ ModeTemp.Height & " 32 bit" & _ " [FMT: " & ModeTemp.Format & "]" End If Else If D3D.CheckDeviceType(cmbAdapters.ListIndex, Renderer, _ ModeTemp.Format, ModeTemp.Format, False) >= 0 Then cmbRes.AddItem ModeTemp.Width & "x" & _ ModeTemp.Height & " 16 bit" & " [FMT: " & _ ModeTemp.Format & "]" End If End If Next I cmbRes.ListIndex = cmbRes.ListCount - 1 End Sub
Nachdem wir die Anzahl der Display-Modes abgefragt haben, gehen wir sie durch und teilen Sie in zwei Farbtiefe-Gruppen(16 und 32 Bit) ein. Dann überprüfen wir, ob Direct3D mit diesen Einstellungen(Adapter, Device, Auflösung, ...) zusammenarbeitet. Nachdem die Einträge in der Liste sind, kann der Benutzter auswählen, welche er benutzten will. Zu bemerken wäre noch der "[FMT: ]" Teil am Ende; dieser zeigt die exakte Farbtiefe an, da 16/32 Bit nicht allzu präzis sind.
Wenn Sie sich die Beispiel anschauen, dann werden Sie bemerken, dass die Auflösungen immer wenn Sie einen neuen Adapter oder Device aussuchen wiederberechnet werden.
Hardwarefähigkeiten
Der letzte brauchbare Teil ist herauszubekommen, was die Hardware für Funktionen unterstützt. Das ist besonders brauchbar, wenn Sie eine spezielle Funktion benutzten wollen, die hardwareabhängig ist oder noch nicht oft unterstützt wird. Diese Art der Enumeration ist (wieder mal) ziemlich einfach, es gibt aber hunderte(vielleicht tausende) Dinge, die man überprüfen kann.
Der erste Teil ist, die Informationen zu bekommen:
'D3D muss ein gültiges Direct3D8-Objekt sein Dim Caps As D3DCAPS8 'Enthält alle Informationen D3D.GetDeviceCaps cmbAdapters.ListIndex, Renderer, Caps
Nachdem wir jetzt eine Struktur haben, die alle Daten enthält("Caps"), können wir nachfragen, was wir wissen wollen. Es gibt viele mögliche Flags, alle sind im VB-Objektbrowser angezeigt, aber wahrscheinlich können Sie von den meisten nicht erraten, was sie für eine Wirkung haben. Die DirectX8-Hilfedatei enthält auch hier alle Informationen dazu, wenn Sie die Datei nicht besitzen, dann müssen Sie warten bis einer Ihnen erzählt, was die Flags tun oder einfach raten.
Hier sind ein paar Beispiele um ein paar Infos zu bekommen:
If Caps.MaxActiveLights = -1 Then List1.AddItem "Maximum Active Lights: Unlimited" Else List1.AddItem "Maximum Active Lights: " & _ Caps.MaxActiveLights End If List1.AddItem "Maximum Point Vertex size: " & Caps.MaxPointSize List1.AddItem "Maximum Texture Size: " & _ Caps.MaxTextureWidth & "x" & Caps.MaxTextureHeight List1.AddItem "Maximum Primatives in one call: " & _ Caps.MaxPrimitiveCount If Caps.TextureCaps And D3DPTEXTURECAPS_SQUAREONLY Then List1.AddItem "Textures must always be square" End If If Caps.TextureCaps And D3DPTEXTURECAPS_CUBEMAP Then List1.AddItem "Device Supports Cube Mapping" End If If Caps.TextureCaps And D3DPTEXTURECAPS_VOLUMEMAP Then List1.AddItem "Device Supports Volume Mapping" End If
Ihre Meinung
Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.