417 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			417 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C++
		
	
	
	
#include <GL/glew.h>
 | 
						|
 | 
						|
#include <fstream>
 | 
						|
#include <iostream>
 | 
						|
#include <cstring>
 | 
						|
using namespace std;
 | 
						|
 | 
						|
//Adapted from Edward Angels InitShader code
 | 
						|
 | 
						|
// Create a NULL-terminated string by reading the provided file
 | 
						|
static char* readShaderSource(const char* shaderFile)
 | 
						|
{
 | 
						|
    ifstream ifs(shaderFile, ios::in | ios::binary | ios::ate);
 | 
						|
    if (ifs.is_open())
 | 
						|
    {
 | 
						|
        unsigned int filesize = static_cast<unsigned int>(ifs.tellg());
 | 
						|
        ifs.seekg(0, ios::beg);
 | 
						|
        char* bytes = new char[filesize + 1];
 | 
						|
        memset(bytes, 0, filesize + 1);
 | 
						|
        ifs.read(bytes, filesize);
 | 
						|
        ifs.close();
 | 
						|
        return bytes;
 | 
						|
    }
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
void printShaderCompileError(GLuint shader)
 | 
						|
{
 | 
						|
    GLint  logSize;
 | 
						|
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
 | 
						|
    char* logMsg = new char[logSize];
 | 
						|
    glGetShaderInfoLog(shader, logSize, NULL, logMsg);
 | 
						|
    std::cerr << logMsg << std::endl;
 | 
						|
    delete[] logMsg;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
void printProgramLinkError(GLuint program)
 | 
						|
{
 | 
						|
    GLint  logSize;
 | 
						|
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logSize);
 | 
						|
    char* logMsg = new char[logSize];
 | 
						|
    glGetProgramInfoLog(program, logSize, NULL, logMsg);
 | 
						|
    std::cerr << logMsg << std::endl;
 | 
						|
    delete[] logMsg;
 | 
						|
}
 | 
						|
 | 
						|
GLuint InitShader(const char* computeShaderFile)
 | 
						|
{
 | 
						|
    bool error = false;
 | 
						|
    struct Shader
 | 
						|
    {
 | 
						|
        const char*  filename;
 | 
						|
        GLenum       type;
 | 
						|
        GLchar*      source;
 | 
						|
    }  shaders[1] =
 | 
						|
    {
 | 
						|
        { computeShaderFile, GL_COMPUTE_SHADER, NULL }
 | 
						|
    };
 | 
						|
 | 
						|
    GLuint program = glCreateProgram();
 | 
						|
 | 
						|
    for (int i = 0; i < 1; ++i)
 | 
						|
    {
 | 
						|
        Shader& s = shaders[i];
 | 
						|
        s.source = readShaderSource(s.filename);
 | 
						|
        if (shaders[i].source == NULL)
 | 
						|
        {
 | 
						|
            std::cerr << "Failed to read " << s.filename << std::endl;
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        GLuint shader = glCreateShader(s.type);
 | 
						|
        glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
 | 
						|
        glCompileShader(shader);
 | 
						|
 | 
						|
        GLint  compiled;
 | 
						|
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
 | 
						|
        if (!compiled)
 | 
						|
        {
 | 
						|
            std::cerr << s.filename << " failed to compile:" << std::endl;
 | 
						|
            printShaderCompileError(shader);
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        delete[] s.source;
 | 
						|
 | 
						|
        glAttachShader(program, shader);
 | 
						|
    }
 | 
						|
 | 
						|
    /* link  and error check */
 | 
						|
    glLinkProgram(program);
 | 
						|
 | 
						|
    GLint  linked;
 | 
						|
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
 | 
						|
    if (!linked)
 | 
						|
    {
 | 
						|
        std::cerr << "Shader program failed to link" << std::endl;
 | 
						|
        printProgramLinkError(program);
 | 
						|
 | 
						|
        error = true;
 | 
						|
    }
 | 
						|
 | 
						|
    if (error == true)
 | 
						|
    {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* use program object */
 | 
						|
    glUseProgram(program);
 | 
						|
 | 
						|
    return program;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
// Create a GLSL program object from vertex and fragment shader files
 | 
						|
GLuint InitShader(const char* vShaderFile, const char* fShaderFile)
 | 
						|
{
 | 
						|
 | 
						|
    bool error = false;
 | 
						|
    struct Shader
 | 
						|
    {
 | 
						|
        const char*  filename;
 | 
						|
        GLenum       type;
 | 
						|
        GLchar*      source;
 | 
						|
    }  shaders[2] =
 | 
						|
    {
 | 
						|
        { vShaderFile, GL_VERTEX_SHADER, NULL },
 | 
						|
        { fShaderFile, GL_FRAGMENT_SHADER, NULL }
 | 
						|
    };
 | 
						|
 | 
						|
    GLuint program = glCreateProgram();
 | 
						|
 | 
						|
    for (int i = 0; i < 2; ++i)
 | 
						|
    {
 | 
						|
        Shader& s = shaders[i];
 | 
						|
        s.source = readShaderSource(s.filename);
 | 
						|
        if (shaders[i].source == NULL)
 | 
						|
        {
 | 
						|
            std::cerr << "Failed to read " << s.filename << std::endl;
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        GLuint shader = glCreateShader(s.type);
 | 
						|
        glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
 | 
						|
        glCompileShader(shader);
 | 
						|
 | 
						|
        GLint  compiled;
 | 
						|
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
 | 
						|
        if (!compiled)
 | 
						|
        {
 | 
						|
            std::cerr << s.filename << " failed to compile:" << std::endl;
 | 
						|
            printShaderCompileError(shader);
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        delete[] s.source;
 | 
						|
 | 
						|
        glAttachShader(program, shader);
 | 
						|
    }
 | 
						|
 | 
						|
    //set shader attrib locations
 | 
						|
    const int posLoc = 0;
 | 
						|
    const int texCoordLoc = 1;
 | 
						|
    const int normalLoc = 2;
 | 
						|
 | 
						|
    glBindAttribLocation(program, posLoc, "posAttrib");
 | 
						|
    glBindAttribLocation(program, texCoordLoc, "texCoordAttrib");
 | 
						|
    glBindAttribLocation(program, normalLoc, "normalAttrib");
 | 
						|
 | 
						|
    /* link  and error check */
 | 
						|
    glLinkProgram(program);
 | 
						|
 | 
						|
    GLint  linked;
 | 
						|
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
 | 
						|
    if (!linked)
 | 
						|
    {
 | 
						|
        std::cerr << "Shader program failed to link" << std::endl;
 | 
						|
        printProgramLinkError(program);
 | 
						|
 | 
						|
        error = true;
 | 
						|
    }
 | 
						|
 | 
						|
    if (error == true)
 | 
						|
    {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* use program object */
 | 
						|
    glUseProgram(program);
 | 
						|
    return program;
 | 
						|
}
 | 
						|
 | 
						|
// Create a GLSL program object from vertex and fragment shader files
 | 
						|
GLuint InitShader(const char* vShaderFile, const char* gShaderFile, const char* fShaderFile)
 | 
						|
{
 | 
						|
    bool error = false;
 | 
						|
    struct Shader
 | 
						|
    {
 | 
						|
        const char*  filename;
 | 
						|
        GLenum       type;
 | 
						|
        GLchar*      source;
 | 
						|
    }  shaders[3] =
 | 
						|
    {
 | 
						|
        { vShaderFile, GL_VERTEX_SHADER, NULL },
 | 
						|
        { gShaderFile, GL_GEOMETRY_SHADER, NULL },
 | 
						|
        { fShaderFile, GL_FRAGMENT_SHADER, NULL }
 | 
						|
    };
 | 
						|
 | 
						|
    GLuint program = glCreateProgram();
 | 
						|
 | 
						|
    for (int i = 0; i < 3; ++i)
 | 
						|
    {
 | 
						|
        Shader& s = shaders[i];
 | 
						|
        s.source = readShaderSource(s.filename);
 | 
						|
        if (shaders[i].source == NULL)
 | 
						|
        {
 | 
						|
            std::cerr << "Failed to read " << s.filename << std::endl;
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        GLuint shader = glCreateShader(s.type);
 | 
						|
        glShaderSource(shader, 1, (const GLchar**)&s.source, NULL);
 | 
						|
        glCompileShader(shader);
 | 
						|
 | 
						|
        GLint  compiled;
 | 
						|
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
 | 
						|
        if (!compiled)
 | 
						|
        {
 | 
						|
            std::cerr << s.filename << " failed to compile:" << std::endl;
 | 
						|
            printShaderCompileError(shader);
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        delete[] s.source;
 | 
						|
 | 
						|
        glAttachShader(program, shader);
 | 
						|
    }
 | 
						|
 | 
						|
    //set shader attrib locations
 | 
						|
    const int posLoc = 0;
 | 
						|
    const int texCoordLoc = 1;
 | 
						|
    const int normalLoc = 2;
 | 
						|
 | 
						|
    glBindAttribLocation(program, posLoc, "posAttrib");
 | 
						|
    glBindAttribLocation(program, texCoordLoc, "texCoordAttrib");
 | 
						|
    glBindAttribLocation(program, normalLoc, "normalAttrib");
 | 
						|
 | 
						|
    /* link  and error check */
 | 
						|
    glLinkProgram(program);
 | 
						|
 | 
						|
    GLint  linked;
 | 
						|
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
 | 
						|
    if (!linked)
 | 
						|
    {
 | 
						|
        std::cerr << "Shader program failed to link" << std::endl;
 | 
						|
        printProgramLinkError(program);
 | 
						|
 | 
						|
        error = true;
 | 
						|
    }
 | 
						|
 | 
						|
    if (error == true)
 | 
						|
    {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* use program object */
 | 
						|
    glUseProgram(program);
 | 
						|
 | 
						|
    return program;
 | 
						|
}
 | 
						|
 | 
						|
GLuint InitShader( const char* vShaderFile, const char* tcShader, const char* teShader, const char* fShaderFile )
 | 
						|
{
 | 
						|
    bool error = false;
 | 
						|
    struct Shader 
 | 
						|
    {
 | 
						|
        const char*  filename;
 | 
						|
        GLenum       type;
 | 
						|
        std::string  source;
 | 
						|
    }  shaders[4] = 
 | 
						|
    {
 | 
						|
        { vShaderFile, GL_VERTEX_SHADER, "" },
 | 
						|
        { tcShader, GL_TESS_CONTROL_SHADER, "" },
 | 
						|
        { teShader, GL_TESS_EVALUATION_SHADER, "" },
 | 
						|
        { fShaderFile, GL_FRAGMENT_SHADER, "" }
 | 
						|
    };
 | 
						|
 | 
						|
    GLuint program = glCreateProgram();
 | 
						|
    
 | 
						|
    for ( int i = 0; i < 4; ++i ) 
 | 
						|
    {
 | 
						|
        Shader& s = shaders[i];
 | 
						|
        s.source = readShaderSource(s.filename);
 | 
						|
        if ( shaders[i].source.length() == 0 ) 
 | 
						|
        {
 | 
						|
            std::cerr << "Failed to read " << s.filename << std::endl;
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        GLuint shader = glCreateShader( s.type );
 | 
						|
        const char *c_str = s.source.c_str();
 | 
						|
        glShaderSource(shader, 1, (const GLchar**)&c_str, NULL);
 | 
						|
        glCompileShader( shader );
 | 
						|
 | 
						|
        GLint  compiled;
 | 
						|
        glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
 | 
						|
        if ( !compiled ) 
 | 
						|
        {
 | 
						|
            std::cerr << s.filename << " failed to compile:" << std::endl;
 | 
						|
            printShaderCompileError(shader);
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        glAttachShader( program, shader );
 | 
						|
    }
 | 
						|
 | 
						|
    //set shader attrib locations
 | 
						|
    const int posLoc = 0;
 | 
						|
    const int texCoordLoc = 1;
 | 
						|
 | 
						|
    glBindAttribLocation(program, posLoc, "posAttrib");
 | 
						|
    glBindAttribLocation(program, texCoordLoc, "texCoordAttrib");
 | 
						|
 | 
						|
    /* link  and error check */
 | 
						|
    glLinkProgram(program);
 | 
						|
 | 
						|
    GLint  linked;
 | 
						|
    glGetProgramiv( program, GL_LINK_STATUS, &linked );
 | 
						|
    if ( !linked ) 
 | 
						|
    {
 | 
						|
        std::cerr << "Shader program failed to link" << std::endl;
 | 
						|
        printProgramLinkError(program);
 | 
						|
 | 
						|
        error = true;
 | 
						|
    }
 | 
						|
 | 
						|
    if(error == true)
 | 
						|
    {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* use program object */
 | 
						|
    glUseProgram(program);
 | 
						|
 | 
						|
    return program;
 | 
						|
}
 | 
						|
 | 
						|
GLuint InitShader( const char* vShaderFile, const char* tcShader, const char* teShader, const char* gShaderFile, const char* fShaderFile )
 | 
						|
{
 | 
						|
    bool error = false;
 | 
						|
    struct Shader 
 | 
						|
    {
 | 
						|
        const char*  filename;
 | 
						|
        GLenum       type;
 | 
						|
        std::string      source;
 | 
						|
    }  shaders[5] = 
 | 
						|
    {
 | 
						|
        { vShaderFile, GL_VERTEX_SHADER, "" },
 | 
						|
        { tcShader, GL_TESS_CONTROL_SHADER, "" },
 | 
						|
        { teShader, GL_TESS_EVALUATION_SHADER, "" },
 | 
						|
        { gShaderFile, GL_GEOMETRY_SHADER, "" },
 | 
						|
        { fShaderFile, GL_FRAGMENT_SHADER, "" }
 | 
						|
    };
 | 
						|
 | 
						|
    GLuint program = glCreateProgram();
 | 
						|
        
 | 
						|
    for ( int i = 0; i < 5; ++i ) 
 | 
						|
    {
 | 
						|
        Shader& s = shaders[i];
 | 
						|
        s.source = readShaderSource(s.filename);
 | 
						|
        if ( shaders[i].source.length() == 0 ) 
 | 
						|
        {
 | 
						|
            std::cerr << "Failed to read " << s.filename << std::endl;
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        GLuint shader = glCreateShader( s.type );
 | 
						|
        const char *c_str = s.source.c_str();
 | 
						|
        glShaderSource( shader, 1, (const GLchar**) &c_str, NULL );
 | 
						|
        glCompileShader( shader );
 | 
						|
 | 
						|
        GLint  compiled;
 | 
						|
        glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled );
 | 
						|
        if ( !compiled ) 
 | 
						|
        {
 | 
						|
            std::cerr << s.filename << " failed to compile:" << std::endl;
 | 
						|
            printShaderCompileError(shader);
 | 
						|
            error = true;
 | 
						|
        }
 | 
						|
 | 
						|
        glAttachShader( program, shader );
 | 
						|
    }
 | 
						|
 | 
						|
    /* link  and error check */
 | 
						|
    glLinkProgram(program);
 | 
						|
 | 
						|
    GLint  linked;
 | 
						|
    glGetProgramiv( program, GL_LINK_STATUS, &linked );
 | 
						|
    if ( !linked ) 
 | 
						|
    {
 | 
						|
        std::cerr << "Shader program failed to link" << std::endl;
 | 
						|
        printProgramLinkError(program);
 | 
						|
 | 
						|
        error = true;
 | 
						|
    }
 | 
						|
 | 
						|
    if(error == true)
 | 
						|
    {
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    /* use program object */
 | 
						|
    glUseProgram(program);
 | 
						|
 | 
						|
    return program;
 | 
						|
} |