Hello GLSL シェーダをテキストファイルから読み込む

hello-glsl-from-file.png
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <filesystem>
using namespace std;
using namespace tr2::sys;
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <GL/freeglut.h>
 
GLuint gProgram;
void GetShaderInfoLog(GLuint shader)
{
    GLsizei bufSize;
 
    /* シェーダのコンパイル時のログの長さを取得する */
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize);
 
    if (bufSize > 1) {
        GLchar *infoLog = (GLchar *)malloc(bufSize);
 
        if (infoLog != NULL) {
            GLsizei length;
 
            /* シェーダのコンパイル時のログの内容を取得する */
            glGetShaderInfoLog(shader, bufSize, &length, infoLog);
            printf("InfoLog:\n%s\n\n", infoLog);
            free(infoLog);
        }
        else
            printf("Could not allocate InfoLog buffer.\n");
    }
}
//引数にはシェーダのコードである文字列を渡す
GLuint createShaderProgram(const char* pVertexSource, const char* pFragmentSource) {
    // シェーダプログラムをロードする
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &pVertexSource, nullptr);
    glCompileShader(vertexShader);//シェーダをコンパイルする。
    GetShaderInfoLog(vertexShader);
    GLuint pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(pixelShader, 1, &pFragmentSource, nullptr);
    glCompileShader(pixelShader);//シェーダをコンパイルする。
    GetShaderInfoLog(pixelShader);
    GLuint program = glCreateProgram();
 
    glAttachShader(program, vertexShader);
    glAttachShader(program, pixelShader);
    glLinkProgram(program);
 
    return program;
}
 
void initShader() {
    ifstream is("shader.vert",ios::ate);//開く時にEOFまで移動する
    int length = int(is.tellg())-1;
    is.seekg(0, is.beg);
    char* vertex_shader_chars = new char[length];
    is.read(vertex_shader_chars, length);
    is.close();
    vertex_shader_chars[length-1] =  '\0';
 
    is.open("shader.frag",ios::ate);
    length = int(is.tellg())-1;
    is.seekg(0, is.beg);
    char* fragment_shader_chars = new char[length];
    is.read(fragment_shader_chars, length);
    is.close();
    fragment_shader_chars[length-1] = '\0';
    gProgram = createShaderProgram(vertex_shader_chars, fragment_shader_chars);
 
}
int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(640, 480, "Hello GLSL", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glewInit();
    initShader();
    while (!glfwWindowShouldClose(window))
    {
        float ratio;
        int width, height;
        glfwGetFramebufferSize(window, &width, &height);
        ratio = width / (float)height;
        glViewport(0, 0, width, height);
        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
 
        glUseProgram(gProgram);
        glutSolidTeapot(0.5);
        glUseProgram(0);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
 
    glfwTerminate();
    return 0;
}

サポートサイト Wikidot.com