Direct3D Anfängerprobleme/-fragen



  • Hi Leute,
    ich fange gerade an mit Lernen von Direct3D. Dazu benutze ich die Tutorial auf der Seite directxtutorial.com. Leider ist da bald Schluss, man muss Premiummember werden. Habt ihr andere gute?

    Am Anfang muss man ja die <D3D10.h> und die <D3DX10.h> inkludieren. Leider findet er die 2., D3DX10.h, nicht obwohl beide Datein im Verzeichnis "C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Include" vorhanden sind...

    Dann für die Farben: Er findet D3DCOLOR_XRGB(...) nicht. Wahrscheinlich ist das in der fehlenden Datei. Bisher hab ich das so gelöst: float ColorRGBA[4] = {red, green, blue, 1.0f};
    Aber das ist etwas zu umständlich da man das ja immer wieder machen muss. Kann man dieses Array auch im Funktionsaufruf deklarieren? Also, das man hier : "device->ClearRenderTargetView(rtv, ColorRGBA);" Irgendwie das ColorRGBA vorher erst gar nicht deklarieren muss?: "device->ClearRenderTargetView(rtv, (float[]){red, green, blue, 1.0f});" Ich weiß sieht komisch aus aber war nur ein Beispiel....

    Ich hoffe ihr könnt mir helfen!
    mfG TheCrip



  • 1. Deine Include Anweisung muss entweder vollqualifiziert sein oder eine Datei referenzieren, die in einer der Include-Searchdirectories deiner IDE liegt.
    2. Das Makro D3DCOLOR_XRGB ist unter DirectX 9 in D3d9types.h definiert.
    3. In D3DX10.h wird auch D3D10.h includiert, weshalb du dies nicht extra noch einmal machen musst.
    4. ClearRenderTargetView ist folgendermaßen deklariert:

    MIDL_INTERFACE("9B7E4C0F-342C-4106-A19F-4F2704F689F0")
    ID3D10Device : public IUnknown
    {
    public:
    	virtual void STDMETHODCALLTYPE ClearRenderTargetView( 
    		/* [annotation] */ 
    		__in  ID3D10RenderTargetView *pRenderTargetView,
    		/* [annotation] */ 
    		__in  const FLOAT ColorRGBA[ 4 ]) = 0;
    };
    

    Unter MSDN ID3D10Device::ClearRenderTargetView Method ist die Deklaration leider falsch.

    Du kannst D3DXCOLOR aus der D3DX10Math.h benutzen:

    typedef struct D3DXCOLOR
    {
    #ifdef __cplusplus
    public:
        D3DXCOLOR() {};
        D3DXCOLOR( UINT  argb );
        D3DXCOLOR( CONST FLOAT * );
        D3DXCOLOR( CONST D3DXFLOAT16 * );
        D3DXCOLOR( FLOAT r, FLOAT g, FLOAT b, FLOAT a );
    
        // casting
        operator UINT  () const;
    
        operator FLOAT* ();
        operator CONST FLOAT* () const;
    
        // assignment operators
        D3DXCOLOR& operator += ( CONST D3DXCOLOR& );
        D3DXCOLOR& operator -= ( CONST D3DXCOLOR& );
        D3DXCOLOR& operator *= ( FLOAT );
        D3DXCOLOR& operator /= ( FLOAT );
    
        // unary operators
        D3DXCOLOR operator + () const;
        D3DXCOLOR operator - () const;
    
        // binary operators
        D3DXCOLOR operator + ( CONST D3DXCOLOR& ) const;
        D3DXCOLOR operator - ( CONST D3DXCOLOR& ) const;
        D3DXCOLOR operator * ( FLOAT ) const;
        D3DXCOLOR operator / ( FLOAT ) const;
    
        friend D3DXCOLOR operator * ( FLOAT, CONST D3DXCOLOR& );
    
        BOOL operator == ( CONST D3DXCOLOR& ) const;
        BOOL operator != ( CONST D3DXCOLOR& ) const;
    
    #endif //__cplusplus
        FLOAT r, g, b, a;
    } D3DXCOLOR, *LPD3DXCOLOR;
    

    Wie du - hoffentlich - siehst, ist der entsprechende Konvertierungsoperator überladen.



  • 1. Da er die D3D10.h findet und diese im gleichen Verzeichnis liegt müsste das doch auch eines der Directories sein. Mit dem ganzen Pfad klappt es, bisschen komisch
    2.Mist falsch geguckt...
    3.Ok danke aber bisher hat er diese ja nicht gefunden.
    4. Es ging mir gar nicht um die Deklaration . Vielen dank für das D3DXCOLOR!

    Neu:
    5. Ich möchte einen Buffer mit Vertexen erstellen. Im Tutorial für DX9 steht als Deklaration LPDIRECT3DVERTEXBUFFER9 v_buffer;. Was bei DX 10 ?

    Danke erstmal für deine Antworten!
    mfG TheCrip



  • TheCrip schrieb:

    1. Da er die D3D10.h findet und diese im gleichen Verzeichnis liegt müsste das doch auch eines der Directories sein. Mit dem ganzen Pfad klappt es, bisschen komisch

    Bist du dir denn überhaupt sicher, dass er die D3D10.h wirklich aus dem Verzeichnis inkludiert wie du es dir denkst?

    Ich denke mir jetzt einfach mal, dass du das Visual Studion benutzt. Überprüfe bitte ob du in den allgemeinen Optionen (

    Tools > Options > Project and Solutions > VC++ Directories
    

    ) oder in den Projekt-Einstellungen (

    Project > [i]ProjectName[/i] Properties > Configuration Properties > VC++ Directories
    

    ) entsprechende Include Directories gesetzt hast.

    Und wo wir schon beim Thema sind: Genau deswegen ist es "gefährlich" default Include Directories zu benutzen, da man am Ende gar nicht weiß, woher die Header geladen wurden. Damit ist nicht mehr sichergestellt, dass man überhaupt die richtige - gewünschte - Version inkludiert.
    Keine Frage, bei den Standard-Bibliotheken wäre alles andere quatsch, aber bei eigenen Headern sollte man schon vorsichtiger sein.

    Entweder gib die Vollqualifizierung an oder erweitere deine Include Directories um "Microsoft DirectX SDK (Month Year)\Include"

    TheCrip schrieb:

    4. Es ging mir gar nicht um die Deklaration .

    Das kannst du so gar nicht ernst meinen. Wenn du etwas derartiges (

    const float[4]
    

    ) als Klasse bereitstellen willst, dann brauchst du

    a) einen entsprechenden Konvertierungsoperator(

    operator CONST FLOAT* () const
    

    ).
    b) die korrekte Sequenz! Schließlich soll R nicht als A auf der anderen Seite erkannt werden.

    "Egal" ist die Deklaration also nicht 😉

    TheCrip schrieb:

    5. Ich möchte einen Buffer mit Vertexen erstellen. Im Tutorial für DX9 steht als Deklaration LPDIRECT3DVERTEXBUFFER9 v_buffer;. Was bei DX 10 ?

    Dieses Interface heißt nun ID3D10Buffer.



  • Ok danke : )

    5. Bei "ID3D10Buffer v_buffer;" kommt folgende Fehlermeldung:

    1>c:\users\niklas\documents\visual studio 2008\projects\firstgame\firstgame\firstgame.cpp(38) : error C2259: 'ID3D10Buffer': Instanz von abstrakter Klasse kann nicht erstellt werden
    1>        aufgrund folgender Member:
    1>        "HRESULT IUnknown::QueryInterface(const IID &,void **)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\unknwn.h(116): Siehe Deklaration von 'IUnknown::QueryInterface'
    1>        "ULONG IUnknown::AddRef(void)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\unknwn.h(120): Siehe Deklaration von 'IUnknown::AddRef'
    1>        "ULONG IUnknown::Release(void)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\unknwn.h(122): Siehe Deklaration von 'IUnknown::Release'
    1>        "void ID3D10DeviceChild::GetDevice(ID3D10Device **)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(816): Siehe Deklaration von 'ID3D10DeviceChild::GetDevice'
    1>        "HRESULT ID3D10DeviceChild::GetPrivateData(const GUID &,UINT *,void *)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(820): Siehe Deklaration von 'ID3D10DeviceChild::GetPrivateData'
    1>        "HRESULT ID3D10DeviceChild::SetPrivateData(const GUID &,UINT,const void *)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(828): Siehe Deklaration von 'ID3D10DeviceChild::SetPrivateData'
    1>        "HRESULT ID3D10DeviceChild::SetPrivateDataInterface(const GUID &,const IUnknown *)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(836): Siehe Deklaration von 'ID3D10DeviceChild::SetPrivateDataInterface'
    1>        "void ID3D10Resource::GetType(D3D10_RESOURCE_DIMENSION *)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(1484): Siehe Deklaration von 'ID3D10Resource::GetType'
    1>        "void ID3D10Resource::SetEvictionPriority(UINT)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(1488): Siehe Deklaration von 'ID3D10Resource::SetEvictionPriority'
    1>        "UINT ID3D10Resource::GetEvictionPriority(void)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(1492): Siehe Deklaration von 'ID3D10Resource::GetEvictionPriority'
    1>        "HRESULT ID3D10Buffer::Map(D3D10_MAP,UINT,void **)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(1670): Siehe Deklaration von 'ID3D10Buffer::Map'
    1>        "void ID3D10Buffer::Unmap(void)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(1678): Siehe Deklaration von 'ID3D10Buffer::Unmap'
    1>        "void ID3D10Buffer::GetDesc(D3D10_BUFFER_DESC *)": ist abstrakt
    1>        c:\program files\microsoft sdks\windows\v6.0a\include\d3d10.h(1680): Siehe Deklaration von 'ID3D10Buffer::GetDesc'
    


  • Zum einen kannst du es schon dem vorangestellten "I" enthnehmen, zum anderen habe ich es auch extra als solches deklariert. ID3D10Buffer ist ein Interface und ein Interface ist eine abstrakte Klasse mit ausschließlich pure virtual Methoden.

    Das ist bei IDIRECT3DVERTEXBUFFER9 auch der Fall. Richtig wäre also:

    ID3D10Buffer* pVertexBuf;
    

    oder eben

    LPD3D10Buffer pVertexBuf;
    

    was ein entsprechendes typedef ist.

    Das übergibst du dann an CreateVertexBuffer();



  • Ok vielen Dank. Ich hab jetzt den VertexBuffer mit 3 Punkten, so wie aus diesem msdn Sample: http://msdn.microsoft.com/en-us/library/bb205130(v=VS.85).aspx

    Wie kann ich das jetzt zeichnen?



  • Das geht mit der Methode DrawPrimitive der Geräteschnittstelle. (Unter DirectX9 was das zumindest so, weiss nicht, ob die Methode jetzt anders heißt).
    Ich würde mir an deiner Stelle ein Buch über 3D-Spiele/Grafikprogrammierung kaufen. Ich denke, dass es einfacher ist, sich das Wissen durch ein Buch anzueignen anstatt es sich stückweise aus dem Internet "zusammenzukratzen".
    Ist aber nur meine persönliche Meinung. Das Buch, das ich habe, war aus meiner Sicht eine gute Investition.

    MfG, Jochen



  • void ID3D10Device::IASetPrimitiveTopology(
      __in  D3D10_PRIMITIVE_TOPOLOGY Topology
    );
    
    void ID3D10Device::Draw(
      __in  UINT VertexCount,
      __in  UINT StartVertexLocation
    );
    

    Wie Jochen S. schon sagte, solltest du dir aber besser Lektüre über DirectX 10 anschaffen, denn ich bin nicht immer online um dir deine Fragen zu beantworten 😉

    Wenn du bereits vertraut mit DirectX 9 bist, dann reicht dir evtl. schon die Dokumentation die zum einen beim SDK mitgeliefert wird und zum anderen auf MSDN verfügbar ist.



  • Ich bin auch schon länger auf der Suche, aber ich finde kein deutsches für DX10... Kennt ihr eins?

    Danke nochmal für die Antworten!



  • Vielleicht verrät dir Jochen S. ja was für ein Buch er hatte, wenn er es schon lobt 😉

    Ein deutsches kann ich dir jedenfalls nicht empfehlen.



  • Ich habe das Buch "3D Spieleprogrammierung mit DirectX 9 und C++" (Hanser-Verlag). Das Buch ist auch deutsch.

    Allerdings wird dort nicht mit DirectX 10 gearbeitet, darum dürfte das Buch für dich wohl eher uninteressant sein. Allerdings finde ich, dass man auch mit DirectX 9 schöne Grafiken erzeugen kann. Das Buch jedenfalls schneidet auch fortgeschrittene Techniken wie Echtzeitschatten, Tiefenschärfe, Pixe-l/Vertex-Shader usw. an. Außerdem werden zwei komplette Spiele entwichekt. Dann habe ich noch das Buch "Game Programming Gems4", kann ich auch empfehlen, dort werden allerdings nur fortgeschrittene Techniken behandelt.

    MfG, Jochen



  • Das hab ich auch schon gefunden, aber leider such ich ja für DX10. Es gibt auch schon eins für DX11 aber das unterstützt meine Hardware leider nicht.
    Naja dann muss ich wohl ein englisches Buch suchen...



  • TheCrip schrieb:

    Das hab ich auch schon gefunden, aber leider such ich ja für DX10. Es gibt auch schon eins für DX11 aber das unterstützt meine Hardware leider nicht.

    Direct3D11 ist dank Feature Levels abwärtskompatibel und läuft sogar auf D3D9 und D3D10 Hardware, natürlich ohne die entsprechenden D3D11 Features. Ich würde heutzutage jedem dazu raten einfach gleich D3D11 zu lernen, die Unterschiede zu D3D10 sind zwar minimal aber wenn man schon was Neues lernt warum dann nicht gleich das aktuellste 😉



  • Ich programmiere mit DirectX 9, von daher weiss ich nicht, ob DirectX 10 oder 11 schwieriger zu handhaben ist oder nicht. Ich finde allerdings, dass man nicht unbedingt mit dem neuesten anfangen muss. Spiele wie z.B. Hitman oder Call of Duty haben bis jetzt auch nur DirectX 9 Grafik. Und an die Grafische Qualität dieser Spiele kommt man als alleiniger Programmierer sowiso nicht heran.
    Meine Meinung: Die neuen Features von DirectX 10 oder 11 dürften für Anfänger/Hobbyprogrammierer nicht allzu unverzichtbar sein.

    MfG, Jochen



  • also das tutorial auf directxtutorial.com ist eig komplett aufs dx9 ausgerichtet
    für die dx10 oder 11 version gibts da ja eigene rubriken, aber die kosten

    mache das auch grad... ist von der theorie eigentlichr echt einfach zu verstehen aber das umzusetzen ist schwerer, vor allem kommen oft irgendwelche fehler und man weiss nicht warum (unsichtbares dreieck weil die eck vertices in der falschen reihenfolge definiert wurden, abstürze des programms -> neu startend es pc erforderlich.... usw)

    aber macht spass und man erzeilt immer wieder ergebnisse dass es nicht frustriert...

    dein eines problem mit dem header hatte ich auch (nur für d3dx9.h) und das lag daran dass das dx sdk tatsächlich nicht eingebunden war, trotzdem aber die datei d3d9.h funktionierte + einfache spielereien

    statt d3dcolor kannst auch dword nehmen, lässt sich einfach so umcasten
    aber (!!!) die farben musst folgendermaßen setzen:
    RGB -> 0xFF, 0xFF, 0xFF
    Rot -> 0x FF 00 00 (aber als eine zeahl, kansnt im windows taschenrechner umrechnen)
    Grün -> 0x 00 FF 00
    Blau -> 0x 00 00 FF

    RGB 0x FF AA 00 wäre dann in DWORD also als Zahl
    DWORD = 16755200



  • Du musst da nichts im Windows-Taschenrechner unrechnen.
    Kannst das ja einfach so schreiben:

    DWROD dwColor = 0xFF8000 // Orange
    

    Allerdings wird auch viel mit Alphawerten (transparenz) gearbeitet. Der Alphawert wir im ersten Byte gespeichert:

    DWORD dwColor = 0xFF008000 // Dunkelgrün, völlig Opak.
    

    MfG, Jochen


Log in to reply