Die Community zu .NET und Classic VB.
Menü

Hardwareinformationen

 von 

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

Beispielprojekt zu diesem Tutorial 

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.