[Gelöst] Effects11 CompileEffectFromFile im Release funktioniert nicht
-
Hallo alle zusammen,
heute habe ich die Konfiguration von Debug auf Release geschalten und musste dabei feststellen dass mein Projekt plötzlich nicht mehr funktioniert.
Ich habe mir einen Basis Shader Klasse erstellt welche die grundlegenden Pointer hält und eine virtuelle Funktion hat die den Shader compilieren soll.
So weit so gut. Im Debug funktioniert alles wunderbar, doch im Release ist mein m_effect Pointer immer null und ich komme einfach nicht drauf woran das liegen könnte.
Genau so seltsam ist aber auch dass ich im Debug ein "warning X4717" erhalte und im Release nicht.So erstelle compiliere ich den Shader:
#ifndef __SHADER_H__ #define __SHADER_H__ //... class Shader { public: //... virtual bool CreateShaderFromFile( ID3D11Device* _device, std::wstring _shaderFile ) { ID3D10Blob* errorMsgs = 00; HR( D3DX11CompileEffectFromFile( _shaderFile.c_str(), 00, 00, 1 << 15, 0, _device, &m_effect, &errorMsgs ) ); if(errorMsgs != 00) { MessageBoxA( 0, static_cast<char*>(errorMsgs->GetBufferPointer()), 0, MB_OK ); Memory::ReleaseCom( errorMsgs ); } if(m_effect == 00) { return false; } return true; } //... protected: ID3DX11Effect* m_effect; //... }; #endif //__SHADER_H__
Falls ich irgendwas wichtiges vergessen habe einfach bescheid geben und ich werde es hinzufügen.
Gruß BlackArma
-
Wie ist das HR Makro in einem Release Build definiert?
-
Ist so definiert:
#if defined ( _DEBUG ) #ifndef HR #define HR(x) \ { \ HRESULT hr = ( x ); \ if(FAILED( hr )) \ { \ DXTrace( __FILEW__, (DWORD)__LINE__, hr, L#x, true ); \ } \ } #endif #else #define HR(x) #endif
-
BlackArma schrieb:
Ist so definiert:
#if defined ( _DEBUG ) #ifndef HR #define HR(x) \ { \ HRESULT hr = ( x ); \ if(FAILED( hr )) \ { \ DXTrace( __FILEW__, (DWORD)__LINE__, hr, L#x, true ); \ } \ } #endif #else #define HR(x) #endif
Also werden alle x, welche als HR(x) aufgerufen werden, im Release Modus ignoriert. Hier liegt die Antwort.
-
OK.
Das ist ein reichlich furchtbares Makro. Ich würde das nicht verwenden.
Und zwar weil
a) Ich den Namen schrecklich finde (=man kann daraus nicht ableiten was das Ding macht) und
b) Es eine lokale Variable mit genau dem Namen verwendet den man oft auch selbst für HRESULT verwendet und
c) Es in Release Builds einfach *nichts* macht - was das Makro mMn. kaum sinnvoll anwendbar macht.Wobei sich letzteres leicht beheben liesse indem man es einfach als
#if defined ( _DEBUG ) // ... #else #define HR(x) ((void)(x)) #endif
definiert.
Wenn du dir dann noch einen besseren Namen für das Makro ausdenkst und den darin verwendeten Variablennamen in z.B.hr_CF63361A567D447EA643CA1887CD20E8
änderst, dann wäre das schonmal besser.Dann würde nur noch fehlen den darin enthaltenen Scope in ein
do { ... } while (false)
zu verwandeln.BTW: Wo ist dieses
HR
Makro her?
Microsoft Header?
Microsoft Beispielcode?
Code den du von sonst wo übernommen hast?
-
hustbaer schrieb:
a) Ich den Namen schrecklich finde (=man kann daraus nicht ableiten was das
Ding macht) undNicht nur das. Er ist auch kurz und erhöht später die Wahrscheinichkeit von Namenskonflikten. Sag jemand der gerade wieder arglos "windows.h" eingebunden hat, und daraufhin seinen eigenen Code bös vor die Wand gefahren hat (
std::max()
und#define max ...
in Windows-Headern lassen grüssen, ein Klassiker! :D).hustbaer schrieb:
b) Es eine lokale Variable mit genau dem Namen verwendet den man oft auch selbst für HRESULT verwendet und
Jo, das ist nicht schön, wenn es sich vermeiden lässt. Aber hat der Code-Block des Makros nicht seinen eigenen Scope und sollte das dort lokale
hr
nicht dennoch eine eigene lokale Variable sein (Shadowing... wie auch immer der deutsche Ausdruck dafür lauten mag)?hustbaer schrieb:
c) Es in Release Builds einfach *nichts* macht - was das Makro mMn. kaum sinnvoll anwendbar macht.
Es ist sicherlich auch für den Release sinnvoll das
HRESULT
auf Fehler zu überprüfen und diese einigermassen zu behandeln (in diesem Fall: "Shader-Datei fehlt/Kann nicht" gelesen werden, oder sowas wie "Shader Model blablub wird von Grafikkarte nicht unterstützt").Und noch eine Anregung an BlackArma zu dem
Memory::ReleaseCom
. Ich weiss zwar nicht, was das für eine Funktion ist, aber vielleicht schaust du dir mal die KlasseMicrosoft::WRL:ComPtr
an, das ist ein relativ sorgenfreier Smart Pointer für COM-Objekte. Damit kann man sich die ganzen manuellen Release()-Aufrufe sparen, zusammen mit all den Problemen, die damit einhergeben (Exception safety et al.).Finnegan
-
hustbaer schrieb:
OK.
Das ist ein reichlich furchtbares Makro. Ich würde das nicht verwenden.
Und zwar weil
a) Ich den Namen schrecklich finde (=man kann daraus nicht ableiten was das Ding macht) und
b) Es eine lokale Variable mit genau dem Namen verwendet den man oft auch selbst für HRESULT verwendet und
c) Es in Release Builds einfach *nichts* macht - was das Makro mMn. kaum sinnvoll anwendbar macht.Mit deiner Erklärung kann ich das wundervoll nachvollziehen.
hustbaer schrieb:
Wobei sich letzteres leicht beheben liesse indem man es einfach als
#if defined ( _DEBUG ) // ... #else #define HR(x) ((void)(x)) #endif
definiert.
Vielen dank, so funktioniert es!
hustbaer schrieb:
Wenn du dir dann noch einen besseren Namen für das Makro ausdenkst und den darin verwendeten Variablennamen in z.B.
hr_CF63361A567D447EA643CA1887CD20E8
änderst, dann wäre das schonmal besser.Werde ich machen.
hustbaer schrieb:
BTW: Wo ist dieses
HR
Makro her?
Microsoft Header?
Microsoft Beispielcode?
Code den du von sonst wo übernommen hast?Das Makro habe ich aus dem Buch "Introduction to 3D Game Programming with Direct3D 11.0" von Frank Luna. Mir fällt auch erst jetzt auf dass ich einfach einen Copy&Past Fehler gemacht habe weshalb es nicht funktionierte.
Nochmals vielen Dank hustbaer und Finnegan, werde mir eure Ratschläge zu Herzen nehmen!
-
hustbaer schrieb:
hustbaer schrieb:
b) Es eine lokale Variable mit genau dem Namen verwendet den man oft auch selbst für HRESULT verwendet und
Jo, das ist nicht schön, wenn es sich vermeiden lässt. Aber hat der Code-Block des Makros nicht seinen eigenen Scope und sollte das dort lokale
hr
nicht dennoch eine eigene lokale Variable sein (Shadowing... wie auch immer der deutsche Ausdruck dafür lauten mag)?Das Problem ist, dass das Makro beim Aufruf
HR(hr)
dann zu...{ HRESULT hr = ( hr ); // <--------- if(FAILED( hr )) { DXTrace( __FILEW__, (DWORD)__LINE__, hr, L#x, true ); } }
...erweitert wird.
Dummerweise compiliert das, führt aber nicht zu dem Ergebnis das man haben möchte, da dashr
bei der Initialisierung der lokalen Variable bereits auf die lokale Variablehr
verweist. Man initialisiert die lokale Variable also "mit sich selbst".