[D3D9] Problem mit Material

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Mr. S
Beiträge: 27
Registriert: 09.06.2011, 09:06

[D3D9] Problem mit Material

Beitrag von Mr. S »

Hallo!

Ich habe ein kleines Material-Problem beim rendern:

Bild

Der Pfeil sollte eigentlich die gleiche Farbe haben wie links am Rand die Zahl. Die gelbe Farbe auf der "Straße" sollte eigentlich knallgelb sein. Hat jemand eine Idee/Verdacht warum das so dunkel ist? Beleuchtung habe ich eingeschaltet und auch Umgebungslicht gesetzt:

Code: Alles auswählen

    pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
    pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
    pDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(255,255,255));
    pDevice->LightEnable(0, TRUE);
Das MAterial für den Pfeil sieht wie folgt aus:

Code: Alles auswählen

D3DCOLORVALUE green;   
green.a = 1.0f;   
green.b = 0.0f;   
green.g = 1.0f;   
green.r = 0.0f;   
D3DMATERIAL9 tmpMat;   
tmpMat.Diffuse = green;   
tmpMat.Ambient = tmpMat.Diffuse;   
pDevice->SetMaterial(&tmpMat); 
Bin dankbar für jede Hilfe!

THX
Mr. S
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D9] Problem mit Material

Beitrag von Krishty »

Hi,
Mr. S hat geschrieben:Der Pfeil sollte eigentlich die gleiche Farbe haben wie links am Rand die Zahl.
Du meinst rechts, oder?
Mr. S hat geschrieben:Das MAterial für den Pfeil sieht wie folgt aus:

Code: Alles auswählen

D3DCOLORVALUE green;   
green.a = 1.0f;   
green.b = 0.0f;   
green.g = 1.0f;   
green.r = 0.0f;   
D3DMATERIAL9 tmpMat;   
tmpMat.Diffuse = green;   
tmpMat.Ambient = tmpMat.Diffuse;   
pDevice->SetMaterial(&tmpMat); 
Du gibst dem Pfeil zwar ein knallgrünes Material, aber da kommt ja noch eine Textur obendrauf. Falls das dieselbe Textur ist wie auf dem Rasen (sieht für mich danach aus), dann wird die Grünkomponente der Textur (die ja nie 100 % ist weil der Rasen schattiert ist und nicht etwa knallgrün) mit der Grünkomponente der Textur multipliziert und der Pfeil sieht so aus, wie er aussieht.

Außerdem hat deine tmpMat-Struktur noch uninitialisierte Werte (für spekuläres Licht usw), die beliebige Werte haben können. Geh mal sicher, dass die genullt sind, indem du die Deklaration zu D3DMATERIAL9 tmpMat = { 0 }; erweiterst.

Zu guter Letzt: Muss es Direct3D 9 ohne Shader sein? Nichts von dem, was du da lernst, wird für dich je wieder von Belang sein.

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Problem mit Material

Beitrag von dot »

Und deine Lichtquellen sind richtig platziert und deine Normalvektoren stimmen? Knallgelb ist schön und gut, aber wenn kein Licht wirklich draufstrahlt dann wirst du auch nicht viel davon sehn ;)
Krishty hat geschrieben:Zu guter Letzt: Muss es Direct3D 9 ohne Shader sein? Nichts von dem, was du da lernst, wird für dich je wieder von Belang sein.
Naja, für den Anfang ist die FFP imo ganz ok um mal ein Gefühl zu bekommen wie alles so abläuft.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D9] Problem mit Material

Beitrag von Krishty »

So weit ich das sehe, benutzt er nur Umgebungslicht; da sollten die Normalen erstmal egal sein.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Problem mit Material

Beitrag von dot »

Ah stimmt, übersehen. Hast du vielleicht ein Vertexformat mit einer Farbe drin sodass diese anstatt der Materialfarbe genommen wird?
Dirk Schulz
Establishment
Beiträge: 130
Registriert: 01.03.2009, 14:21
Alter Benutzername: frittentuete

Re: [D3D9] Problem mit Material

Beitrag von Dirk Schulz »

Hi,
Krishty hat geschrieben:So weit ich das sehe, benutzt er nur Umgebungslicht; da sollten die Normalen erstmal egal sein.
Ist leider nicht ganz richtig. Er schaltet mit pDevice->SetRenderState(D3DRS_LIGHTING, TRUE); die interne Beleuchtungsberechnung an, für die die Normalen nötig sind. Nachzulesen in der Doku.

Ich würde aber auch sagen, dass das Hauptproblem eher die Vermischung zwischen grüner Textur und grüner Material-farbe ist. Vielleicht ist die Textur ja "unabsichtlich" auf dem Pfeil gelandet? :?:

Vielleicht mal beim Pfeil vor dem Rendern mit pDevice->SetTexture(0, NULL); die Textur ausschalten?!
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Problem mit Material

Beitrag von dot »

Dirk Schulz hat geschrieben:Ist leider nicht ganz richtig. Er schaltet mit pDevice->SetRenderState(D3DRS_LIGHTING, TRUE); die interne Beleuchtungsberechnung an, für die die Normalen nötig sind. Nachzulesen in der Doku.
Ja, aber da sein Ambient Light rein weiß ist macht das keinen Unterschied mehr (Beleuchtung = Ambient + Rest) ;)
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D9] Problem mit Material

Beitrag von Krishty »

Genau:
http://msdn.microsoft.com/en-us/library/bb172256 hat geschrieben:Ambient lighting provides constant lighting for a scene. It lights all object vertices the same because it is not dependent on any other lighting factors such as vertex normals, light direction, light position, range, or attenuation.
:)
Es wird ihm natürlich früher oder später Probleme machen, wenn seine Normalen nicht stimmen oder nicht vorhanden sind oder sonstwas. Aber bei dem speziellen Problem, das er jetzt im Augenblick hat, bringt es uns nicht weiter.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Mr. S
Beiträge: 27
Registriert: 09.06.2011, 09:06

Re: [D3D9] Problem mit Material

Beitrag von Mr. S »

Krishty hat geschrieben:Du meinst rechts, oder?
Ups, natürlich meinte rechts. Mein Fehler.
Krishty hat geschrieben:Du gibst dem Pfeil zwar ein knallgrünes Material, aber da kommt ja noch eine Textur obendrauf.
Muss da eine Textur drauf? Eigentlich soll der Pfeil nämlich nur mit einer Farbe angemalt werden.
Krishty hat geschrieben:Außerdem hat deine tmpMat-Struktur noch uninitialisierte Werte (für spekuläres Licht usw), die beliebige Werte haben können. Geh mal sicher, dass die genullt sind, indem du die Deklaration zu D3DMATERIAL9 tmpMat = { 0 }; erweiterst.
Habe ich gemacht, leider hilft das auch nicht weiter.
Krishty hat geschrieben:Zu guter Letzt: Muss es Direct3D 9 ohne Shader sein? Nichts von dem, was du da lernst, wird für dich je wieder von Belang sein.
Muss nicht, aber ich habe keine Ahnung davon.

Ich habe noch einmal Screenshots von zwei "Leveln" gemacht, bei einem funktioniert es, bei dem anderen nicht:
Bild

In der Tat sieht es so aus, als ob der eine Pfeil mit der Rasen-Textur belegt wird.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D9] Problem mit Material

Beitrag von dot »

Ja es liegt wohl offenbar wirklich dran dass deine Materialfarbe mit der Grastextur vermischt wird. Vermutlich hast du eben die Textur noch gesetzt wenn du den Pfeil in deinen gelben Streifen renderst!?
Mr. S
Beiträge: 27
Registriert: 09.06.2011, 09:06

Re: [D3D9] Problem mit Material

Beitrag von Mr. S »

Ich möchte mich erst einmal bei allen Helfern bedanken! So schnell kann ich gar nicht lesen & posten wie hier die guten Ratschläge kommen.
Dirk Schulz hat geschrieben:Ich würde aber auch sagen, dass das Hauptproblem eher die Vermischung zwischen grüner Textur und grüner Material-farbe ist. Vielleicht ist die Textur ja "unabsichtlich" auf dem Pfeil gelandet? :?:

Vielleicht mal beim Pfeil vor dem Rendern mit pDevice->SetTexture(0, NULL); die Textur ausschalten?!
Das funktioniert! Tausend Dank!

Ob jetzt irgendwo Normalenvektoren fehlen, kann ich adhoc nicht sagen, ich lade X-Files mit D3DXLoadMeshFromX und ersetze bei dem Pfeil das einzige Material (ursprünglich weiß) mit der gewünschten Farbe. Alle anderen Materialien (auch die anderer Meshs) bleiben unverändert. Die Meshs habe ich mit Google Sketchup gebaut, daher ist auch die Rasen-Textur. Für den "Straßenbelag" habe ich eine eigene Textur gemacht, die ich einmal angehängt habe.

Die Pfeile funktionieren jetzt, bleibt nur noch die Frage, warum der Untergrund so komisch aussieht.

Vielen Dank
Mr. S
Dateianhänge
tcrossing.jpg
Dirk Schulz
Establishment
Beiträge: 130
Registriert: 01.03.2009, 14:21
Alter Benutzername: frittentuete

Re: [D3D9] Problem mit Material

Beitrag von Dirk Schulz »

@kristhy & dot: ging mir auch eher darum, späteren Problemen vorzubeugen, bzw. anderen die ein ähnliches Problem haben und hier nachlesen, die Problembeseitigung zu erleichten.

@Mr. S: Das Problem mit der Straßentextur ist wahrscheinlich, dass sie das Material des grünen Pfeils bekommt.

DirectX weiß nicht, ab wann ein Material (bzw. Textur, Renderstates etc.) nicht mehr benutzt werden soll. Sobald du ein Material setzt, werden alle Meshes mit diesem Material gerendert.

Deshalb solltest du für jeden Mesh ein Material erstellen und vor dem Rendern setzen. Bei der Straßentextur wäre das wohl ein weißes Material.
Mr. S
Beiträge: 27
Registriert: 09.06.2011, 09:06

Re: [D3D9] Problem mit Material

Beitrag von Mr. S »

Ich lade Meshs so:

Code: Alles auswählen

    if (FAILED(D3DXLoadMeshFromX(strFile,
                                 D3DXMESH_MANAGED,
                                 pDevice,
                                 NULL,
                                 &pMaterialBuffer,
                                 NULL,
                                 &m_dwNumMaterials,
                                 &m_pMesh)))
    {
        SHOWERROR(_T("D3DXLoadMeshFromX() failed"), __FILE__, __LINE__);
        return false;
    }

    // Store material and texture information
    D3DXMATERIAL* pMaterials=(D3DXMATERIAL*)pMaterialBuffer->GetBufferPointer();
    
    m_pMeshMaterials = new D3DMATERIAL9[m_dwNumMaterials];
    m_ppMeshTextures = new LPDIRECT3DTEXTURE9[m_dwNumMaterials];

    // Copy the materials and textures from the buffer to the member arrays
    for (i = 0; i < m_dwNumMaterials; i++)
    {
        m_pMeshMaterials[i] = pMaterials[i].MatD3D;
        m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;
        // Create the texture if it exists
        m_ppMeshTextures[i] = NULL;
        if(pMaterials[i].pTextureFilename)
        {
#if defined(UNICODE) || defined(_UNICODE)
            DWORD dwNum = MultiByteToWideChar(CP_ACP,
                                              0,
                                              pMaterials[i].pTextureFilename,
                                              -1,
                                              NULL,
                                              0);
            strTexturFile = new wchar_t[dwNum + 1];
            MultiByteToWideChar(CP_ACP,
                                0,
                                pMaterials[i].pTextureFilename,
                                -1,
                                strTexturFile,
                                dwNum);
#else
            strTexturFile = pMaterials[i].pTextureFilename;
#endif
            _stprintf_s(strTexturPath,
                        MAX_PATH,
                        _T("%s\\%s"),
                        strPath,
                        strTexturFile);
#if defined(UNICODE) || defined(_UNICODE)
            delete []strTexturFile;
#endif
            if (FAILED(D3DXCreateTextureFromFile(pDevice,
                                                 strTexturPath,
                                                 &m_ppMeshTextures[i])))
            {
                SHOWERROR(_T("Failed to load mesh texture"), __FILE__,__LINE__);
                return true;
            }
        }
    }

    pMaterialBuffer->Release();
Gerendert wird es so:

Code: Alles auswählen

    for (DWORD i = 0; i < dwNumMaterials; i++)
    {
        pDevice->SetMaterial(&m_pMeshMaterials[i]);
        pDevice->SetTexture(0, m_ppMeshTextures[i]);
        m_pMesh->DrawSubset(i);
    }
	pDevice->SetTexture(0, NULL);
Die letzte Zeile ist allerdings neu.
Mr. S
Beiträge: 27
Registriert: 09.06.2011, 09:06

Re: [D3D9] Problem mit Material

Beitrag von Mr. S »

Ich habe das Problem der dunklen Texturen gefunden. Es lag in diesem Fall an dem Export-Plugin für X-Dateien:

Code: Alles auswählen

Material {
0.564706;0.627451;0.356863;1.000000;;
50.000000;
0.000000;0.000000;0.000000;;
0.000000;0.000000;0.000000;;
TextureFilename { "Vegetation_Grass1.jpg"; }
}
Wie zu sehen, ist die Farbe nicht weiß. Das gleiche Problem gilt natürlich auch für alle Straßentexturen. Nachdem ich die Dateien von Hand angepasst habe funktioniert alles einwandfrei.

Vielen Dank für die vielen nützlichen Hinweise!
MfG
S.
Antworten