Buscar..


Introducción

Estos ejemplos demuestran varias formas de cargar y compilar shaders. Todos los ejemplos deben incluir código de manejo de errores .

Observaciones

Los objetos de sombreado, tal como se crean a partir de glCreateShader , no hacen mucho. Contienen el código compilado para una sola etapa, pero ni siquiera tienen que contener el código compilado completo para esa etapa. En muchos sentidos, funcionan como archivos de objetos C y C ++.

Los objetos del programa contienen el programa final vinculado. Pero también tienen el estado para los valores uniformes del programa, así como una serie de otros datos estatales. Tienen API para realizar una introspección de los datos de la interfaz del sombreador (aunque solo se incluyó en GL 4.3). Los objetos de programa son los que definen el código de sombreado que se utiliza al renderizar.

Los objetos Shader, una vez utilizados para vincular un programa, ya no son necesarios a menos que tenga la intención de usarlos para vincular otros programas.

Cargar Shader separable en C ++

4.1

Este código carga, compila y vincula un solo archivo que crea un programa de sombreado separado para una sola etapa . Si hay errores, obtendrá el registro de información para esos errores.

El código utiliza alguna funcionalidad de C ++ 11 comúnmente disponible.

#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;
}

Compilación de objetos Shader individuales en C ++

El modelo de compilación GLSL tradicional implica compilar código para una etapa de sombreado en un objeto de sombreado, luego vincular múltiples objetos de sombreado (que cubren todas las etapas que desea usar) en un solo objeto de programa.

Desde 4.2, se pueden crear objetos de programa que tienen solo una etapa de sombreado. Este método vincula todas las etapas de sombreado en un solo programa.

Compilación de objetos Shader

#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;
}

Programa de enlace de objetos

#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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow