How to fix the DirectX viewer crash bug in the DirectX SDK

by APIJunkie 11/15/2007 6:03:00 AM

 If you came across the infamous DirectX Viewer SDK bug where DXViewer.exe crashes when loading X files or where DXViewer.exe crashes with the following message “This application has failed to start because d3dx10d_33.dll was not found…” then you probably came to the right place.

 The solution is to fix the bugs in the code and project settings and build the DirectX Viewer from source code(found at [install path of DirectXSDK]\Utilities\Source\DxViewer).

 There are 2 problems with the DXViewer.exe executable. Below are the descriptions of the problems and their solutions.

 Both problems stem from the fact that although the code was written to work on both DirectX 9 and 10 the code fails miserably in DirectX 9 environments.

 Problem1:  The executable tries to load a DirectX 10 DLL (d3dx10d_33.dll) which does not necessarily exist on a developer’s machine (For example in the obvious case where the user does not have DirectX 10 installed…). The code actually tries to handle the case where the DLL is missing but because it binds to the DLL at load time it does not help.

 Solution 1: Force the executable to delay load the DirectX 10 DLL. To do that, go to the project properties and then go to the linker/input settings and enter d3dx10d_33.dll in the “Delay Loaded DLLs” edit box.

 

 Problem 2: The code does not properly use the DirectX 9 legacy shader compiler. This causes the program to crash when loading .x files.

 Solution 2: To solve this problem modify the code to force the shader compiler to use the legacy DirectX 9 mode using the D3DXSHADER_USE_LEGACY_D3DX9_31_DLL flag.

 Note below are quick and dirty instructions for fixing the bug in the code. They are only intended to fix the crash on a development environment where the code crashes.

 1. Change the ModelLoader9::CreateMaterial member function in Model9.cpp (changes marked in bold):

 Material* ModelLoader9::CreateMaterial(ModelSubset* pModelSubset, Sas::SourceInfo& si)

{

    HRESULT hr = S_OK;

    std::vector<D3DXMACRO> macroArray;

    ModelLoader9::MakeMacroArray( STATE_GET( Defines ), macroArray );

    Material* pResult = new Material;

    bool dbgVS = STATE_GET( DebugVertexShaders );

    bool dbgPS = STATE_GET( DebugPixelShaders );

    DWORD flags = ((dbgVS|dbgPS)? D3DXSHADER_DEBUG : 0) |

        ((dbgVS)? D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT : 0) |

        ((dbgPS)? D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT : 0) |

        (STATE_GET(OptimizeShaders) ? 0 : D3DXSHADER_SKIPOPTIMIZATION) |

        (STATE_GET(ValidateShaders) ? 0 : D3DXSHADER_SKIPVALIDATION) |

        (STATE_GET(Preshaders) ? 0 : D3DXSHADER_NO_PRESHADER) |

        (STATE_GET(PartialPrecision) ? D3DXSHADER_PARTIALPRECISION : 0) |

        (STATE_GET(PreferDynamicFlow) ? D3DXSHADER_PREFER_FLOW_CONTROL : D3DXSHADER_AVOID_FLOW_CONTROL);

    // begin fix sdk ps1.1 shader bug

    flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL;

    // end fix sdk ps1.1 shader bug

    wstring includes = si.GetDirectoryPath()? si.GetDirectoryPath() : L"";

    includes += L";";

    includes += STATE_GET(Includes);

     V( Sas::Effect9::FromSource(

        DXUTGetD3D9Device(),

        si,

        &macroArray.front(),

        &DXVGetIncludeHandler9(includes.c_str()),

        flags,

        (Sas::Effect9**)&pResult->Effect ) );

     if(SUCCEEDED(hr))

     {

        std::vector<TechniqueInfo>& EffectInfo = DXVGetRender9().GetEffectInfo();

        if(!STATE_GET(FileFX).empty() && EffectInfo.empty() )

        {

            UINT iTec, iPass;

            ID3DXEffect* pEffect = ((Sas::Effect9*)pResult->Effect)->GetD3DXEffect();

            D3DXEFFECT_DESC effectDesc;

            V(pEffect->GetDesc( &effectDesc ));

            EffectInfo.resize( effectDesc.Techniques );

            for(iTec = 0 ; iTec < effectDesc.Techniques ; iTec++ )

            {

                TechniqueInfo& techInfo = EffectInfo[iTec];

                D3DXHANDLE technique = pEffect->GetTechnique(iTec);

                D3DXTECHNIQUE_DESC techniqueDesc;

                V( pEffect->GetTechniqueDesc( technique, &techniqueDesc ) );

                CharToWString( techniqueDesc.Name, techInfo.Name);

                techInfo.Passes.resize(techniqueDesc.Passes);

                for( iPass = 0; iPass < techniqueDesc.Passes; iPass++ )

                {

                    D3DXHANDLE pass = pEffect->GetPass(technique, iPass);

                    D3DXPASS_DESC passDesc;

                    pEffect->GetPassDesc( pass, &passDesc );

                     CharToWString( passDesc.Name, techInfo.Passes[iPass] );

                }

            }

        }

    }

    if( FAILED(hr) )

       SAFE_DELETE( pResult);

    return pResult;

}

 

2. Change the CShowBounds9::SetBounds member function in ShowBounds9.cpp (changes marked in bold):

 

void CShowBounds9::SetBounds(const D3DXVECTOR3& minVec, const D3DXVECTOR3& maxVec)

{

    HRESULT hr = S_OK;

    IDirect3DDevice9* device = DXUTGetD3D9Device();

    // begin fix sdk ps1.1 shader bug

    DWORD flags = 0;

    flags |= D3DXSHADER_USE_LEGACY_D3DX9_31_DLL;

    // end fix sdk ps1.1 shader bug

    {//EFFECT

        LPD3DXBUFFER pErrorsAndWarnings= NULL;

        if(FAILED( D3DXCreateEffectFromResource( device, NULL, MAKEINTRESOURCE(IDR_SHOWLINES9FX),

    // begin fix sdk ps1.1 shader bug

                                                NULL, NULL, flags, NULL, &Effect, &pErrorsAndWarnings )) )

    // end fix sdk ps1.1 shader bug

        {

            MessageBoxA(NULL, (LPCSTR)(!pErrorsAndWarnings?"":pErrorsAndWarnings->GetBufferPointer()), "ShowBounds: Error loading Effect", 0 );

        }

        SAFE_RELEASE(pErrorsAndWarnings);

    }//EFFECT

    V( device->CreateVertexDeclaration( Elements, &Declaration ) );

    V( device->CreateIndexBuffer( 12*2*sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &IB, NULL) );

    WORD* pSrcIB=NULL;

    V( IB->Lock(0, 0, (void**)&pSrcIB, 0 ) );

    pSrcIB[0*2+0] = 0; pSrcIB[0*2+1] = 1;

    pSrcIB[1*2+0] = 1; pSrcIB[1*2+1] = 2;

    pSrcIB[2*2+0] = 2; pSrcIB[2*2+1] = 3;

    pSrcIB[3*2+0] = 3; pSrcIB[3*2+1] = 0;

    pSrcIB[4*2+0] = 4; pSrcIB[4*2+1] = 5;

    pSrcIB[5*2+0] = 5; pSrcIB[5*2+1] = 6;

    pSrcIB[6*2+0] = 6; pSrcIB[6*2+1] = 7;

    pSrcIB[7*2+0] = 7; pSrcIB[7*2+1] = 4;

    pSrcIB[8*2+0] = 0; pSrcIB[8*2+1] = 4;

    pSrcIB[9*2+0] = 1; pSrcIB[9*2+1] = 5;

    pSrcIB[10*2+0] = 2; pSrcIB[10*2+1] = 6;

    pSrcIB[11*2+0] = 3; pSrcIB[11*2+1] = 7;

    V( IB->Unlock() );

    V( device->CreateVertexBuffer( 8*Stride , D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &VB, NULL) );

    Vertex* pSrcVB=NULL;

    V( VB->Lock(0, 0, (void**)&pSrcVB, 0 ) );

    GetBox(&pSrcVB[0].Position, sizeof(Vertex), minVec, maxVec);

    V( VB->Unlock() );

}

 

That’s it you should be good to go…

 

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

DirectX | SDK

Comments

7/13/2009 6:18:23 AM

pingback

Pingback from answerspluto.com

list of links 3 « Answers Pluto

answerspluto.com

Comments are closed

Powered by BlogEngine.NET 1.2.0.0
Theme by Mads Kristensen

About the author

Name of author

My name is Bacon…James Bacon.

I am an API wars veteran I was wounded by x86 assembly, recovered and moved on to C. Following a long addiction to C++ and a short stint at rehab I decided to switch to a healthier addiction so I am now happily sniffing .NET and getting hooked on Silverlight.

I am mainly here to ramble about coding, various API’s, Junkies(me especially) and everything else that happens between coders and their significant other.

E-mail me Send mail


Calendar

<<  March 2010  >>
MoTuWeThFrSaSu
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar

Recent comments

Authors

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

Sign in