// HLSL2GLSLConverterImpl.cpp : Defines the entry point for the console application. // #include #include #include "Errors.h" #include "HLSL2GLSLConverterImpl.h" #include "RefCntAutoPtr.h" #include "Errors.h" #include "EngineFactoryOpenGL.h" #include "BasicShaderSourceStreamFactory.h" #include "RefCntAutoPtr.h" #include "DataBlobImpl.h" using namespace Diligent; // Called every time the application receives a message LRESULT CALLBACK MessageProc(HWND wnd, UINT message, WPARAM wParam, LPARAM lParam) { // Send event message to AntTweakBar switch (message) { case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(wnd, &ps); EndPaint(wnd, &ps); return 0; } case WM_SIZE: // Window size has been changed return 0; case WM_CHAR: if (wParam == VK_ESCAPE) PostQuitMessage(0); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(wnd, message, wParam, lParam); } } void PrintHelp() { LOG_INFO_MESSAGE("Command line arguments:\n"); LOG_INFO_MESSAGE("-h Print help message\n"); LOG_INFO_MESSAGE("-i Input file path (relative to the search directories)\n"); LOG_INFO_MESSAGE("-d Search directory to look for input file path as well as all #include files"); LOG_INFO_MESSAGE(" Every search directory should be specified using -d argument\n"); LOG_INFO_MESSAGE("-o Output file to write converted GLSL source to\n"); LOG_INFO_MESSAGE("-e Shader entry point\n"); LOG_INFO_MESSAGE("-c Compile converted GLSL shader\n"); LOG_INFO_MESSAGE("-t Shader type. Allowed values:"); LOG_INFO_MESSAGE(" vs - vertex shader"); LOG_INFO_MESSAGE(" ps - pixel shader"); LOG_INFO_MESSAGE(" gs - geometry shader"); LOG_INFO_MESSAGE(" ds - domain shader"); LOG_INFO_MESSAGE(" hs - domain shader"); LOG_INFO_MESSAGE(" cs - domain shader\n"); LOG_INFO_MESSAGE("-noglsldef Do not include glsl definitions into the converted source\n"); LOG_INFO_MESSAGE("-nolocations Do not use shader input/output locations qualifiers.\n" " Shader stage interface linking will rely on exact name matching.\n"); } // Main int main(int argc, char** argv) { #if defined(_DEBUG) || defined(DEBUG) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif if (argc == 1) { PrintHelp(); return 0; } std::string InputPath, OutputPath, SearchDirectories, EntryPoint("main"); SHADER_TYPE ShaderType = SHADER_TYPE_UNKNOWN; bool CompileShader = false; bool IncludeGLSLDefintions = true; bool UseInOutLocations = true; for (int a = 1; a < argc; ++a) { if (_stricmp(argv[a], "-h") == 0) { PrintHelp(); } else if (_stricmp(argv[a], "-i") == 0 && a + 1 < argc) { InputPath = argv[++a]; } else if (_stricmp(argv[a], "-o") == 0 && a + 1 < argc) { OutputPath = argv[++a]; } else if (_stricmp(argv[a], "-d") == 0 && a + 1 < argc) { if(!SearchDirectories.empty()) SearchDirectories.push_back(';'); SearchDirectories += argv[++a]; } else if (_stricmp(argv[a], "-e") == 0 && a + 1 < argc) { EntryPoint = argv[++a]; } else if (_stricmp(argv[a], "-c") == 0) { CompileShader = true; } else if (_stricmp(argv[a], "-t") == 0 && a + 1 < argc) { ++a; if (_stricmp(argv[a], "vs")==0)ShaderType = SHADER_TYPE_VERTEX; else if (_stricmp(argv[a], "gs")==0)ShaderType = SHADER_TYPE_GEOMETRY; else if (_stricmp(argv[a], "ps")==0)ShaderType = SHADER_TYPE_PIXEL; else if (_stricmp(argv[a], "hs")==0)ShaderType = SHADER_TYPE_HULL; else if (_stricmp(argv[a], "ds")==0)ShaderType = SHADER_TYPE_DOMAIN; else if (_stricmp(argv[a], "cs")==0)ShaderType = SHADER_TYPE_COMPUTE; else { LOG_ERROR_MESSAGE("Unknow shader type ", argv[a],"; Allowed values: vs,gs,ps,ds,hs,cs"); return -1; } } else if (_stricmp(argv[a], "-noglsldef") == 0) { IncludeGLSLDefintions = false; } else if (_stricmp(argv[a], "-nolocations") == 0) { UseInOutLocations = false; } else { LOG_ERROR_MESSAGE("Unknow command line option ", argv[a]); return -1; } } if (InputPath.length() == 0) { LOG_ERROR_MESSAGE("Input file path not specified; use -i command line option"); return -1; } if(ShaderType == SHADER_TYPE_UNKNOWN) { LOG_ERROR_MESSAGE("Shader type not specified; use -t [vs;ps;gs;ds;hs;cs] command line option"); return -1; } LOG_INFO_MESSAGE("Converting \'", InputPath, "\' to GLSL..."); #if EXPLICITLY_LOAD_ENGINE_GL_DLL // Declare function pointer GetEngineFactoryOpenGLType GetEngineFactoryOpenGL = nullptr; if( !LoadGraphicsEngineOpenGL(GetEngineFactoryOpenGL) ) { LOG_ERROR_MESSAGE("Failed to load OpenGL engine implementation"); return -1; } #endif IEngineFactoryOpenGL *pFactory = GetEngineFactoryOpenGL(); BasicShaderSourceStreamFactory BasicSSSFactory(SearchDirectories.c_str()); RefCntAutoPtr pInputFileStream; BasicSSSFactory.CreateInputStream(InputPath.c_str(), &pInputFileStream); if (!pInputFileStream) { return -1; } RefCntAutoPtr pHLSLSourceBlob( MakeNewRCObj()(0) ); pInputFileStream->Read(pHLSLSourceBlob); auto *HLSLSource = reinterpret_cast(pHLSLSourceBlob->GetDataPtr()); auto SourceLen = static_cast( pHLSLSourceBlob->GetSize() ); const auto &Converter = HLSL2GLSLConverterImpl::GetInstance(); RefCntAutoPtr pStream; Converter.CreateStream(InputPath.c_str(), &BasicSSSFactory, HLSLSource, SourceLen, &pStream); RefCntAutoPtr pGLSLSourceBlob; pStream->Convert(EntryPoint.c_str(), ShaderType, IncludeGLSLDefintions, "_sampler", UseInOutLocations, &pGLSLSourceBlob); if(!pGLSLSourceBlob)return -1; LOG_INFO_MESSAGE("Done"); if (OutputPath.length() != 0) { FileWrapper pOutputFile( OutputPath.c_str(), EFileAccessMode::Overwrite ); if (pOutputFile != nullptr) { if( !pOutputFile->Write(pGLSLSourceBlob->GetDataPtr(), pGLSLSourceBlob->GetSize()) ) { LOG_ERROR_MESSAGE("Failed to write converted source to output file ", OutputPath); } } else { LOG_ERROR_MESSAGE("Failed to open output file ", OutputPath); } } if(CompileShader) { LOG_INFO_MESSAGE("Compiling entry point \'", EntryPoint, "\' in converted file \'", InputPath, '\''); // Register window cla ss WNDCLASSEX wcex = { sizeof(WNDCLASSEX), CS_HREDRAW|CS_VREDRAW, MessageProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L"HLSL2GLSLConverter", NULL }; RegisterClassEx(&wcex); // Create dummy window RECT rc = { 0, 0, 512, 512 }; AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, FALSE); HWND wnd = CreateWindow(L"HLSL2GLSLConverter", L"HLSL2GLSL Converter", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, wcex.hInstance, NULL); if (!wnd) { LOG_ERROR_MESSAGE("Failed to create window"); return -1; } RefCntAutoPtr pDevice; RefCntAutoPtr pContext; RefCntAutoPtr pSwapChain; EngineGLCreateInfo EngineCI; SwapChainDesc SCDesc; SCDesc.SamplesCount = 1; EngineCI.pNativeWndHandle = wnd; pFactory->CreateDeviceAndSwapChainGL( EngineCI, &pDevice, &pContext, SCDesc, &pSwapChain ); if (!pDevice) { LOG_ERROR_MESSAGE("Failed to create render device"); return -1; } ShaderCreateInfo ShaderCI; ShaderCI.EntryPoint = EntryPoint.c_str(); ShaderCI.Desc.ShaderType = ShaderType; ShaderCI.Desc.Name = "Test shader"; ShaderCI.Source = reinterpret_cast(pGLSLSourceBlob->GetDataPtr()); ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_GLSL; ShaderCI.UseCombinedTextureSamplers = true; RefCntAutoPtr pTestShader; pDevice->CreateShader(ShaderCI, &pTestShader); if(!pTestShader) { LOG_ERROR_MESSAGE("Failed to compile converted source \'", InputPath, '\''); return -1; } LOG_INFO_MESSAGE("Done"); } return 0; }