Поиск…


Вступление

Эти примеры демонстрируют различные способы загрузки и компиляции шейдеров. Все примеры должны включать код обработки ошибок .

замечания

Объекты Shader, созданные из glCreateShader , мало что делают. Они содержат скомпилированный код для одного этапа, но они даже не должны содержать полный скомпилированный код для этого этапа. Во многих отношениях они работают как объектные файлы C и C ++.

Объекты программы содержат окончательную связанную программу. Но они также содержат состояние для равномерных значений программы, а также ряд других данных состояния. У них есть API для интроспекции данных интерфейса шейдера (хотя он только стал всеобъемлющим в GL 4.3). Объекты программы - это то, что определяет код шейдера, который вы используете при рендеринге.

Объекты Shader, когда-то используемые для связи программы, больше не нужны, если вы не собираетесь использовать их для соединения других программ.

Загружать разделяемый шейдер в C ++

4,1

Этот код загружает, компилирует и связывает один файл, который создает отдельную шейдерную программу для одного этапа . Если есть ошибки, он получит информационный журнал для этих ошибок.

Код использует некоторые общедоступные возможности C ++ 11.

#include <string>
#include <fstream>

//In C++17, we could take a `std::filesystem::path` instead of a std::string
//for the filename.
GLuint CreateSeparateProgram(GLenum stage, const std::string &filename)
{
    std::ifstream input(filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
    
    //Figure out how big the file is.
    auto fileSize = input.tellg();
    input.seekg(0, ios::beg);
    
    //Read the whole file.
    std::string fileData(fileSize);
    input.read(&fileData[0], fileSize);
    input.close();
    
    //Compile&link the file
    auto fileCstr = (const GLchar *)fileData.c_str();
    auto program = glCreateShaderProgramv(stage, 1, &fileCstr);

    //Check for errors
    GLint isLinked = 0;
    glGetProgramiv(program, GL_LINK_STATUS, &isLinked);
    if(isLinked == GL_FALSE)
    {
        //Note: maxLength includes the NUL terminator.
        GLint maxLength = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);        

        //C++11 does not permit you to overwrite the NUL terminator,
        //even if you are overwriting it with the NUL terminator.
        //C++17 does, so you could subtract 1 from the length and skip the `pop_back`.
        std::basic_string<GLchar> infoLog(maxLength);
        glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
        infoLog.pop_back();

        //The program is useless now. So delete it.
        glDeleteProgram(program);

        //Use the infoLog in whatever manner you deem best.

        //Exit with failure.
        return 0;
    }
    
    return program;
}

Индивидуальная компоновка объектов Shader в C ++

Традиционная модель компиляции GLSL включает компиляцию кода для этапа шейдера в шейдерный объект, а затем связывание нескольких объектов шейдера (охватывающих все этапы, которые вы хотите использовать) в один программный объект.

Начиная с 4.2, могут быть созданы программные объекты, имеющие только один этап шейдера. Этот метод связывает все стадии шейдера в одну программу.

Компиляция объектов шейдеров

#include <string>
#include <fstream>

//In C++17, we could take a `std::filesystem::path` instead of a std::string
//for the filename.
GLuint CreateShaderObject(GLenum stage, const std::string &filename)
{
    std::ifstream input(filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
    
    //Figure out how big the file is.
    auto fileSize = input.tellg();
    input.seekg(0, ios::beg);
    
    //Read the whole file.
    std::string fileData(fileSize);
    input.read(&fileData[0], fileSize);
    input.close();
    
    //Create a shader name
    auto shader = glCreateShader(stage);

    //Send the shader source code to GL
    auto fileCstr = (const GLchar *)fileData.c_str();
    glShaderSource(shader, 1, &fileCstr, nullptr);

    //Compile the shader
    glCompileShader(shader);

    GLint isCompiled = 0;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
    if(isCompiled == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);

        //C++11 does not permit you to overwrite the NUL terminator,
        //even if you are overwriting it with the NUL terminator.
        //C++17 does, so you could subtract 1 from the length and skip the `pop_back`.
        std::basic_string<GLchar> infoLog(maxLength);
        glGetShaderInfoLog(shader, maxLength, &maxLength, &infoLog[0]);
        infoLog.pop_back();

        //We don't need the shader anymore.
        glDeleteShader(shader);

        //Use the infoLog as you see fit.
        
        //Exit with failure.
        return 0;
    }

    return shader;
}

Связывание объектов программы

#include <string>

GLuint LinkProgramObject(vector<GLuint> shaders)
{
    //Get a program object.
    auto program = glCreateProgram();

    //Attach our shaders to our program
    for(auto shader : shaders)
        glAttachShader(program, shader);

    //Link our program
    glLinkProgram(program);

    //Note the different functions here: glGetProgram* instead of glGetShader*.
    GLint isLinked = 0;
    glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
    if(isLinked == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

        //C++11 does not permit you to overwrite the NUL terminator,
        //even if you are overwriting it with the NUL terminator.
        //C++17 does, so you could subtract 1 from the length and skip the `pop_back`.
        std::basic_string<GLchar> infoLog(maxLength);
        glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
        infoLog.pop_back();
        
        //We don't need the program anymore.
        glDeleteProgram(program);

        //Use the infoLog as you see fit.
        
        //Exit with failure
        return 0;
    }

    //Always detach shaders after a successful link.
    for(auto shader : shaders)
        gldetachShader(program, shader);
        
    return program;
}


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow