Redbook Triangles

redbook-triangles.png

頂点シェーダ

#version 420 core
layout(location = 0) in vec4 vPosition;
void main()
{
    gl_Position = vPosition;
}

フラグメントシェーダ

#version 420 core
out vec4 fColor;
void
main()
{
    fColor = vec4(157.0/255.0, 217.0/255.0, 221.0/255.0, 1.0);
}

cpp

#include <iostream>
#include <fstream>   // ifstream, ofstream
#include <filesystem>//tr2::sys::pathに必要
#include <cassert>
using namespace std;
#include <GL/glew.h>
#include <GL/freeglut.h>
 
enum VAO_IDs { Triangles, NumVAOs };
enum Buffer_IDs { ArrayBuffer, NumBuffers };
enum Attrib_IDs { vPosition = 0 };
GLuint VAOs[NumVAOs];
GLuint Buffers[NumBuffers];
const GLuint NumVertices = 6;
/*
* @return シェーダIDを返す
*/
GLuint loadShader(const string& _shaderfilepath)
{
    //テキストファイルの読み込み
    tr2::sys::path path(_shaderfilepath);
    GLenum shadartype;
    string extention = path.extension().string();
    if (extention == ".vert") { shadartype = GL_VERTEX_SHADER; }
    else if (extention == ".frag") { shadartype = GL_FRAGMENT_SHADER; }
    else { shadartype = GL_GEOMETRY_SHADER_EXT; }
    GLuint shaderid = glCreateShader(shadartype);
    ifstream is(_shaderfilepath,ios::in);
    if (!is.is_open()) {
        tr2::sys::path mypath;
        cout << "現在のディレクトリ" << tr2::sys::current_path().string() << endl;
        cout << "開こうとしたファイル:" << _shaderfilepath << endl;
        assert(!"シェーダファイルが存在しません。");
        return 0;
    }
    //ファイルの長さを調べる
    is.seekg(0, ios::end);
    int filebytes = is.tellg();
    is.seekg(0, ios::beg);//先頭まで移動
    char* pSource = new char[filebytes];
 
    is.read(pSource, filebytes);
    is.close();
    pSource[filebytes - 1] = '\0';
 
    GLuint shader = glCreateShader(shadartype);
    glShaderSource(shader, 1, &pSource, NULL);
    delete[] pSource;
 
    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);
        cerr << "Shader compilation failed: " << log << endl;
        delete[] log;
#endif /* DEBUG */
        return 0;
    }
    return shader;
}
/**
* @return シェーダID
*/
GLuint loadShaders(const string& _vertexpath, const string& _fragmentpath)
{
    // シェーダプログラムをロードする
    GLuint vertexShader = loadShader(_vertexpath);
    if (!vertexShader) { return -1; }
    GLuint fragmentShader = loadShader(_fragmentpath);
    if (!fragmentShader) { return -2; }
 
    GLuint program = glCreateProgram();
    if (!program) { return -3; }
 
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);
 
    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);
        cerr << "Shader linking failed: " << log << endl;
        delete[] log;
#endif /* DEBUG */
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
        return 0;
    }
    return program;
}
void init(void)
{
    glGenVertexArrays(NumVAOs, VAOs);
    glBindVertexArray(VAOs[Triangles]);
    GLfloat vertices[NumVertices][2] = {
        { -0.90, -0.90 }, // Triangle 1
        { 0.85, -0.90 },
        { -0.90, 0.85 },
        { 0.90, -0.85 }, // Triangle 2
        { 0.90, 0.90 },
        { -0.85, 0.90 }
    };
    glGenBuffers(NumBuffers, Buffers);
    glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices),vertices, GL_STATIC_DRAW);
    GLuint program = loadShaders("triangles.vert", "triangles.frag");
    glUseProgram(program);
    glVertexAttribPointer(vPosition, 2, GL_FLOAT,GL_FALSE, 0, (GLvoid*)0);
    glEnableVertexAttribArray(vPosition);
}
void display(void)
{
    glClearColor(83.0 / 255.0, 62.0 / 255.0, 37.0 / 255.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
 
    glBindVertexArray(VAOs[Triangles]);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices);
    glFlush();
}
 
int main(int argc, char** argv)
{
 
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA);
    glutInitWindowSize(200, 200);
    glutInitContextVersion(4, 2);
    glutInitContextProfile(GLUT_CORE_PROFILE);
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE | GLUT_DEBUG);
 
    glutCreateWindow(argv[0]);
    glutSetWindowTitle("triangles");
    if (glewInit()) {
        cerr << "Unable to initialize GLEW ... exiting" << endl;
        exit(EXIT_FAILURE);
    }
    init();
    glutDisplayFunc(display);
    glutMainLoop();
}

サポートサイト Wikidot.com