Du bist nicht angemeldet.

Werbeanzeige

1

01.04.2017, 17:54

D3DX11CompileFromFile / D3DCompileFromFile findet die Shader-Datei nicht.

Hallo zusammen,
ich versuche seit ca. einer Woche herauszufinden, warum die beiden, in der Überschrift genannten, Funktionen die, jeweils mit dem ersten Parameter übergebene Datei nicht finden können.
Obwohl ich die Datei im Explorer sehen und auch bearbeiten kann und der Dateipfad sowohl von mir als auch der Funktion PathFileExists überprüft wurde und er somit existiert, geben beide Funktionen Fehler wie
-Das System konnte die angegebene Datei nicht finden.
-ERROR_FILE_NOT_FOUND
-ERROR_PATH_NOT_FOUND
zurück.
Das Kompilieren des Shaders habe ich in eine externe Funktion verlegt, um nur noch die nötigsten Parameter übergeben zu müssen, wobei die Pfadübergabe hier problem- und fehlerlos abläuft.
Sobald dieser Pfad aber über D3DX11CompileFromFile / D3DCompileFromFile 'geöffnet' werden soll, also der Shader kompiliert werden soll, scheint der Pfad ungültig zu werden.
Hier die externe Funktion und der Aufruf:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
//.hpp
virtual bool CompileD3DShader(char* filePath, char* entry, char* shaderModel, ID3D10Blob **buffer);

//.cpp
bool Dx11DemoBase::CompileD3DShader(char * filePath, char * entry, char * shaderModel, ID3D10Blob ** buffer)
{
    DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

#if defined (DEBUG) || defined (_DEBUG)
    shaderFlags |= D3DCOMPILE_DEBUG;
#endif

    ID3D10Blob* errorBuffer = 0;
    HRESULT res;

    res = D3DCompileFromFile((LPCWSTR)(filePath), 0, 0, entry, shaderModel, shaderFlags, 0, buffer, &errorBuffer);

    if (FAILED(res))
    {
        if (errorBuffer != 0)
        {
            OutputDebugString((char*)errorBuffer->GetBufferPointer());
            errorBuffer->Release();
        }
        return false;
    }

    if (errorBuffer != 0) errorBuffer->Release();

    return true;
}

//.cpp; Der Aufruf der obigen Funktion
ID3D10Blob * vsBuffer = 0;

    //Shader kompilieren
    bool compileres = CompileD3DShader("data/Shader.fx", "vs_Main", "vs_5_0", &vsBuffer);
    if (compileres == false)
    {
        MessageBox(NULL, TEXT("Error while creating the vertexshader!"), TEXT("Error"), MB_OK | MB_ICONERROR);
        return false;
    }


Vielen Dank im Voraus für eure Hilfe :)

PS.: Ja der Ordner "data" befindet sich im selben Verzeichnis wie die .exe und in diesem Ordner ist auch "Shader.fx"...bevor jemand fragt ;)

2

01.04.2017, 18:36

Wenn du das Ganze über VS selbst startest, ist das aktuelle Verzeichnis nicht zwingend das der exe.
Ich würde es mal mit einem absoluten Pfad probieren, rein testweise. Ansonsten, musst du in den Projekteinstellungen nach der Property "Debugging/Arbeitsverzeichnis" alias "Debugging/Working directory" schauen und den Pfad auf den Ordner mit der exe einstellen.
Natürlich kannst du auch versuchen, die exe mal nicht über VS zu starten, dann sollte das aktuelle Verzeichnis ja stimmen.
Besucht mich und meinen Blog unter:
www.simple-world.org

Du magst Tower Defense?
Dann probier doch mal Coregrounds aus ;)

3

02.04.2017, 14:59

Hi,
erstmal danke für die schnelle Antwort, aber statt dem relativen Pfad einen Absoluten zu setzen funktioniert nicht, das habe ich auch schon versucht.
Dann lautet der Fehlercode einfach nur noch E_FAIL.
Außerhalb von VS zu starten bringt auch nichts, das Programm beendet sich, bzw. zeigt erst noch die MessageBox angezeigt.
Ich probier jetzt aber mal aus, ob es was bringt den Pfad auf den, in den Projektproperties angegebenen, einzustellen.
Ich sag dann heute Abend Bescheid, ob funktioniert hat.

BlueCobold

Community-Fossil

Beiträge: 10 888

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

02.04.2017, 15:32

Statt den Pfad aus den Projekt-Properties zu nehmen, wäre es sinnvoller die Projekt-Properties anzupassen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

5

03.04.2017, 15:08

Also ich habe jetzt beides ausprobiert, den Pfad im Code auf die Properties angepasst und als das nicht funktioniert hat den Pfad in den Properties auf das .exe Verzeichnis gelegt.
Das hat laut PathFileExists auch funktioniert, aber D3DX11CompileFromFile / D3DCompileFromFile nimmt es immer noch nicht an.
Jetzt kommt aber immer E_FAIL als Fehler. ?(

BlueCobold

Community-Fossil

Beiträge: 10 888

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

03.04.2017, 15:41

Dann ist wohl in deinem Shader was falsch oder die Karte unterstützt ihn nicht. Jedenfall wird das File ja nun gefunden. Für Details wirst du wohl mal nachfragen müssen, was genau fehlgeschlagen ist und warum.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

birdfreeyahoo

Alter Hase

Beiträge: 766

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

7

03.04.2017, 15:54

Also einen char* in ein LPCWSTR zu konvertieren ergibt bei mir keine sinnvollen Zeichenfolgen. Versuche folgendes:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
bool Dx11DemoBase::CompileD3DShader(char * filePath, char * entry, char * shaderModel, ID3D10Blob ** buffer)
{
    DWORD shaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;

#if defined (DEBUG) || defined (_DEBUG)
    shaderFlags |= D3DCOMPILE_DEBUG;
#endif

    ID3D10Blob* errorBuffer = 0;
    HRESULT res;
    const size_t filePathMax = 512;

    wchar_t wFilePath[filePathMax];
    size_t outSize;                              // Wieviele Zeichen konvertiert wurden
    mbstowcs_s(&outSize, wFilePath, filePath, filePathMax);

    res = D3DCompileFromFile((LPCWSTR)wFilePath, 0, 0, entry, shaderModel, shaderFlags, 0, buffer, &errorBuffer);

    if (FAILED(res))
    {
        if (errorBuffer != 0)
        {
            OutputDebugString((char*)errorBuffer->GetBufferPointer());
            errorBuffer->Release();
        }
        return false;
    }

    if (errorBuffer != 0) errorBuffer->Release();

    return true;
}


Durch den Aufruf von mbstowcs_s konvertierst du den Multi-Byte C-String in einen Wide-String (Unicode).

8

04.04.2017, 16:27

Aber ich habe in den Properties den Zeichensatz ja auf Multi-Byte laufen.
Soll ich das mal umändern, oder macht das im Endeffekt nichts aus?

David Scherfgen

Administrator

Beiträge: 10 197

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

9

04.04.2017, 16:31

Deine Funktion erwartet aber char*. Richtig wäre die Signatur:

CompileD3DShader(wchar_t* filePath, ...)

Dann beim Parameter ein L davor schreiben:

L"data/Shader.fx"

So müsstest du auch nicht den expliziten (und semantisch falschen) Cast nach LPCWSTR machen.

birdfreeyahoo

Alter Hase

Beiträge: 766

Wohnort: Schorndorf

Beruf: Junior Software Engineer

  • Private Nachricht senden

10

04.04.2017, 18:12

@David Kannst du das "semantisch falsch" genauer erläutern?

Werbeanzeige