个人技术分享

#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代码的私密性