着色器加载

头定义

#ifndef __LOAD_SHADERS_H__
#define __LOAD_SHADERS_H__

#include 

#ifdef __cpluscplus
extern "C" {
#endif

typedef struct {
    GLenum type;
    const char* filename;
    GLuint shader;
} ShaderInfo;

GLuint LoadShaders(ShaderInfo*);

#ifdef __cpluscplus
};
#endif

#endif

实现

#include 
#include 

#include 
#include "LoadShaders.h"

#ifdef __cpluscplus
extern "C" {
#endif

static const GLchar* ReadShader(const char* filename) {
    FILE* infile = fopen(filename, "rb");
    if (!infile) {
#ifdef _DEBUG
        std::cerr << "unable to open file " << filename << std::endl;
#endif
        return NULL;
    }

    fseek(infile, 0, SEEK_END);
    int len = ftell(infile);
    fseek(infile, 0, SEEK_SET);

    GLchar* source = new GLchar[len+1];
    fread(source, 1, len, infile);
    fclose(infile);
    source[len] = 0;
    return const_cast(source);
}

GLuint LoadShaders(ShaderInfo* shaders) {
    if (shaders == NULL) {
        return 0;
    }

    GLuint program = glCreateProgram();

    ShaderInfo* entry = shaders;
    while (entry->type != GL_NONE) {
        GLuint shader = glCreateShader(entry->type);
        entry->shader = shader;
        const GLchar* source = ReadShader(entry->filename);
        if (source == NULL) {
            for (entry = shaders; entry->type != GL_NONE; ++entry) {
                glDeleteShader(entry->shader);
                entry->shader = 0;
            }
            return 0;
        }
        glShaderSource(shader, 1, &source, NULL);
        delete[] source;
        glCompileShader(shader);
        GLint compiled;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        if (!compiled) {
#ifdef _DEBUG
            GLsizei len;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
            GLchar* log = new GLchar[len+1];
            glGetShaderInfoLog(shader, len, &len, log);
            std::cerr << "shader compilation failed:" << log << std::endl;
            delete[] log;
#endif
            return 0;
        }
        glAttachShader(program, shader);
        ++entry;
    }
    glLinkProgram(program);
    GLint linked;
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    if (!linked) {
#ifdef _DEBUG
        GLsizei len;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
        GLchar* log = new GLchar[len+1];
        glGetProgramInfoLog(program, len, &len, log);
        std::cerr << "shader linking failed:" << log << std::endl;
        delete[] log;
#endif
        for (entry = shaders; entry->type != GL_NONE; ++entry) {
            glDeleteShader(entry->shader);
            entry->shader = 0;
        }
        return;
    }
    return program;
}

#ifdef __cpluscplus
}
#endif

你可能感兴趣的:(着色器加载)