glsl文件转二进制文件
- 2024-06-05 20:21
- 9人 已看
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <spirv_cross/spirv_cross.hpp>
#include <spirv_cross/spirv_glsl.hpp>
#include <glslang/Public/ShaderLang.h>
#include <SPIRV/GlslangToSpv.h>
#include <glslang/Public/ShaderLang.h>
#include <SPIRV/GlslangToSpv.h>
std::vector<uint32_t> read_spirv_file(const char* path)
{
std::vector<uint32_t> buffer;
std::ifstream file(path, std::ios::binary | std::ios::ate);
if (!file.is_open()) {
std::cerr << "Failed to open SPIR-V file\n";
return std::move(buffer);
}
// Get the size of the file
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
// Read the file content into a buffer
buffer.resize(size);
if (!file.read(reinterpret_cast<char*>(buffer.data()), size)) {
std::cerr << "Failed to read SPIR-V file\n";
buffer.clear();
return std::move(buffer);
}
// Close the file
file.close();
return std::move(buffer);
}
std::string ReadFile(const std::string& filename) {
std::ifstream file(filename);
if (!file.is_open()) {
throw std::runtime_error("Failed to open GLSL file.");
}
return std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
}
// Compile GLSL to SPIR-V
std::vector<uint32_t> CompileGLSLToSPIRV(const std::string& glslSource, EShLanguage shaderType) {
const char* shaderStrings[1];
shaderStrings[0] = glslSource.c_str();
glslang::TShader shader(shaderType);
shader.setStrings(shaderStrings, 1);
shader.setEnvInput(glslang::EShSourceGlsl, shaderType, glslang::EShClientOpenGL, glslang::EShTargetSpv_1_0);
shader.setEnvClient(glslang::EShClientOpenGL, glslang::EShTargetOpenGL_450);
shader.setEnvTarget(glslang::EShTargetNone, glslang::EShTargetSpv_1_0);
TBuiltInResource DefaultTBuiltInResource;
// Parse GLSL shader
if (!shader.parse(&DefaultTBuiltInResource, 100, false, EShMsgSpvRules)) {
std::cerr << "GLSL Parsing Failed: " << shader.getInfoLog() << std::endl;
std::cerr << "GLSL Parsing Debug Info: " << shader.getInfoDebugLog() << std::endl;
throw std::runtime_error("GLSL Parsing Failed.");
}
glslang::TProgram program;
program.addShader(&shader);
// Link program
if (!program.link(EShMsgSpvRules)) {
std::cerr << "GLSL Linking Failed: " << program.getInfoLog() << std::endl;
std::cerr << "GLSL Linking Debug Info: " << program.getInfoDebugLog() << std::endl;
throw std::runtime_error("GLSL Linking Failed.");
}
// SPIR-V generation
std::vector<uint32_t> spirv;
glslang::TIntermediate *intermediate = program.getIntermediate(shaderType);
glslang::GlslangToSpv(*intermediate, spirv);
return std::move(spirv);
}
void SaveSPIRV(const std::vector<uint32_t>& spirv, const std::string& filename) {
std::ofstream file(filename, std::ios::binary | std::ios::out);
if (!file.is_open()) {
throw std::runtime_error("Failed to open SPIR-V output file.");
}
file.write(reinterpret_cast<const char*>(spirv.data()), spirv.size() * sizeof(uint32_t));
file.close();
}
int main(int, char* [])
{
glslang::InitializeProcess();
// Read GLSL code
std::string glslSource = ReadFile("F:/test.glsl");
// Compile GLSL to SPIR-V
std::vector<uint32_t> spirv = CompileGLSLToSPIRV(glslSource, EShLangFragment);
SaveSPIRV(spirv,"E:/test.sprv");
std::vector<uint32_t> spirv1 = read_spirv_file("E:/test.sprv");
glslang::FinalizeProcess();
std::string glsl;
try
{
spirv_cross::CompilerGLSL glslCompiler(spirv);
// Set GLSL options if needed
spirv_cross::CompilerGLSL::Options options;
options.version = 330; // Set GLSL version
glslCompiler.set_common_options(options);
// Convert SPIR-V to GLSL
glsl = glslCompiler.compile();
}
catch (const std::exception&e)
{
std::cout<<e.what()<<std::endl;
}
return EXIT_SUCCESS;
}
总结:不公开,内部实现,有利于GLSL代码的私密性