   DirectX 9 D3DXAssembleShaderFromFile Error SOLVED
  Hi Everyone,I'm having trouble building a vertex shader using the Function D3DXAssembleShaderFromFile();I've completed a modified version of the ZFX engine that some of you may be familiar with using DX9 and VS2005, but I can't seem to get this shader to be assembled. The manual says that D3DXAssembleShaderFromFile returns one of three values if there's a problem, but I don't get any of them, I just get E_FAIL instead. The debug data is NULL too, so it must be something pretty fundamental.Function in DLL to create Vertex Shader:HRESULT BED3D::CreateVShader( const void *pData, UINT nSize, bool bLoadFromFile,bool bIsCompiled, UINT *pID)// ------------------------------------------------------{   LPD3DXBUFFER  pCode = NULL;   LPD3DXBUFFER  pDebug = NULL;   HRESULT  hrC = BE_OK, hrA = BE_OK;   DWORD   *pVS = NULL;   HANDLE   hFile, hMap;   // do we have space for one more?   if( mNumVShaders >= (MAX_SHADER-1) ) { Log("error: max number of shaders reached in BED3D::CreateVShader"); return BE_OUTOFMEMORY;   }   // (1): ALREADY ASSEMBLED   if( bIsCompiled ) { // already compiled (from file) if( bLoadFromFile ){    hFile = CreateFile((LPCTSTR)pData, GENERIC_READ,   0, 0, OPEN_EXISTING,    FILE_ATTRIBUTE_NORMAL, 0);    if( hFile == INVALID_HANDLE_VALUE ) {  Log("error: CreateFile() in BED3D::CreateVShader failed");  return BE_FILENOTFOUND;    }    hMap = CreateFileMapping(hFile,0,PAGE_READONLY, 0,0,0);    pVS = (DWORD*)MapViewOfFile(hMap,FILE_MAP_READ,0,0,0); } // already compiled (from datapointer) else { pVS = (DWORD*)pData; }   } // if   // (2): STILL NEEDS ASSEMBLING   else { // not yet compiled (from file) if( bLoadFromFile ){hrA = D3DXAssembleShaderFromFile( (LPCWSTR)pData,    NULL, NULL, 0, &pCode, &pDebug ); } // not yet compiled (from datapointer) else{    hrA = D3DXAssembleShader( (LPCSTR)pData, nSize-1,NULL, NULL, 0,&pCode, &pDebug ); } // track errors if any if( SUCCEEDED(hrA) ){    pVS = (DWORD*)pCode->GetBufferPointer(); } else{    Log("error: Assemble[Vertex]Shader[FromFile]() failed");    if (hrA==D3DERR_INVALIDCALL)  Log("INVALID_CALL");    else if (hrA==D3DXERR_INVALIDDATA)  Log("D3DXERR_INVALIDDATA");    else if (hrA==E_OUTOFMEMORY)  Log("E_OUTOFMEMORY");    if (pDebug->GetBufferPointer())  Log("Shader debugger says: %s", (char*)pDebug->GetBufferPointer());    else   Log("no debug infos stored");    return BE_FAIL; }   } // else   // create the shader object   if( FAILED(hrC=mpDevice->CreateVertexShader(pVS,    &mpVShader[mNumVShaders]))) { Log("error: CreateVertexShader() failed"); if (hrC==D3DERR_INVALIDCALL)    Log("INVALID_CALL"); else if (hrC==D3DERR_OUTOFVIDEOMEMORY)    Log("D3DERR_OUTOFVIDEOMEMORY"); else if (hrC==E_OUTOFMEMORY)    Log("E_OUTOFMEMORY"); return BE_FAIL;   }   // store index to this shader   if( pID ) (*pID) = mNumVShaders;   // free resources   if( bIsCompiled && bLoadFromFile ) { UnmapViewOfFile(pVS); CloseHandle(hMap); CloseHandle(hFile);   }   mNumVShaders++;   return BE_OK;} // CreateVShaderDemo Application (Function Call):   if( !g_pDevice->CanDoShaders() ) return S_OK;   if( FAILED(g_pDevice->CreateVShader( "test.vsh", 0, true, false, &nID))) { fprintf(pLog, "CreateVShader failed\n"); fflush(pLog); return BE_FAIL;   } if( FAILED(g_pDevice->ActivateVShader(nID, VID_UU)) ) { fprintf(pLog, "ActivateVShader failed\n"); fflush(pLog); return BE_FAIL;   }Shader test.vsh:vs.1.1dcl_position0 v0dcl_normal0   v3dcl_texcoord0 v6m4x4 oPos, v0, c0mov oD0, c4mov oT0, v6Can anyone see what's missing? This is supposed to be one of the simpler examples!Beefy Elbow[Edited by - BeefyElbow on June 17, 2009 3:13:29 PM]
  If it helps, I'm compiling with Unicode enabled, so all the strings will resolve to wide characters.Is this so obvious that no-one's replying as some form of protest?   ;  Well, as it happens, using Unicode was a hint to the solution.The function call:   if( FAILED(g_pDevice->CreateVShader( "test.vsh", 0, true, false, &nID))) { fprintf(pLog, "CreateVShader failed\n"); fflush(pLog); return BE_FAIL;   }should be changed to include the L Literal identifier before the name of the base shader file as below:   if( FAILED(g_pDevice->CreateVShader( L"test.vsh", 0, true, false, &nID))) { fprintf(pLog, "CreateVShader failed\n"); fflush(pLog); return BE_FAIL;   }Since the 1st parameter to the function CreateVShader() can be passed either an address or a filename, the parameter is a void pointer which is then cast to the correct type in the function body. The VS debugger was displaying the passed value as a string on mouse hover, but garbage data when the cast was applied to the passed value.It made me realise that it wasn't a string in the traditional sense, but a wide-character string. Applying the L before the literal fixed it immediately. Gah!   