bambooflow Note

EmptyProject

最終更新:

Bot(ページ名リンク)

- view
メンバー限定 登録/ログイン

ここでは、OpenGL Shader Languageを使うための準備を行います.

作成に用いた環境
  • OpenGL3.2
  • GLUT(freeglut) - 2.6.0
  • GLEW - 1.5.7

GLSLの手続き


  1. バーテックスシェーダとフラグメントシェーダのシェーダオブジェクトを(glCreateShader)
  2. ソースプログラム読み込み(glShaderSource)
  3. 読み込んだソースプログラムをコンパイル (glCompileShader)
  4. プログラムオブジェクト作成 (glCreateProgram)
  5. プログラムオブジェクトにシェーダオブジェクト接続 (glAttachShader)
  6. シェーダプログラムをリンク(glLinkProgram)
  7. シェーダプログラム適用(glUseProgram)

  • シェーダプログラムオブジェクト作成の流れ

シェーダプログラム作成用関数の準備


シェーダプログラムを作成する手順は、基本的に同じです。
なので、関数化して共通ファイルにしておきます。


  • load_shader.h
#ifndef __LOAD_SHADER_H_
#define __LOAD_SHADER_H_
 
#include <GL/glew.h>
#include <GL/gl.h>
 
GLuint loadShaderFromFile(GLenum type, const char *fileName);
GLuint loadShader(GLenum type, const char *str, const char* fileName="");
GLuint createProgram(const char* vsName, const char* fsName);
 
#endif // __LOAD_SHADER_H_
 

  • load_shader.cpp
#include <iostream>
#include <fstream>
#include "load_shader.h"
 
GLuint createProgram(const char* vsName, const char* fsName)
{
  GLuint programObject;
  GLuint vertexShader;
  GLuint fragmentShader;
 
  programObject = glCreateProgram();
  if (programObject == 0) return 0;
 
  vertexShader = loadShaderFromFile(GL_VERTEX_SHADER, vsName);
  glAttachShader(programObject, vertexShader);
 
  fragmentShader = loadShaderFromFile(GL_FRAGMENT_SHADER, fsName);
  glAttachShader(programObject, fragmentShader);
 
  GLint linked;
  glLinkProgram(programObject);
  glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
  if (!linked) {
    GLint infoLen = 0;
 
    glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
    if (infoLen > 1) {
      char *infoLog = new char[sizeof(char)*infoLen];
 
      glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
      std::cerr << "Error linking program:\n" << infoLog << "\n";
      delete [] infoLog;
    }
    glDeleteProgram(programObject);
    return 0;
  }
 
  glDeleteShader(vertexShader);
  glDeleteShader(fragmentShader);
 
  return programObject;
}
 
 
 
GLuint loadShaderFromFile(GLenum type, const char *fileName)
{
  std::fstream inputFile(fileName);
  std::istreambuf_iterator<char> dataBegin(inputFile);
  std::istreambuf_iterator<char> dataEnd;
  std::string fileData(dataBegin, dataEnd);
  const char *str = fileData.c_str();
 
  return loadShader(type, str, fileName);
}
 
GLuint loadShader(GLenum type, const char *str, const char *fileName)
{
  GLuint shader;
  GLint compiled;
 
  shader = glCreateShader(type);
  if (shader == 0)
    return 0;
 
  glShaderSource(shader, 1, &str, NULL);
  glCompileShader(shader);
  glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  if (!compiled) {
    GLint infoLen = 0;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
    if (infoLen > 1 ) {
      char* infoLog = new char[sizeof(char)*infoLen];
      glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
      std::cerr << "Error compiling shader: " << fileName << "\n" << infoLog << "\n";
      delete [] infoLog;
    }
    glDeleteShader(shader);
    return 0;
  }
  return shader;
}
 


使うAPIは次の1つだけ。
createProgram( "頂点シェーダファイル名", "フラグメントシェーダファイル名" );
戻り値:GLuint シェーダプログラムオブジェクト





GLSLの空プロジェクト(GLUT版)


まずは空のプロジェクトを作ってみます。
ここではGLUTを使っています。

#include <iostream>
#include <fstream>
#include <cstdlib>
 
#include "load_shader.h"
#include <GL/glew.h>
#include <GL/glut.h>
 
GLuint programObject;
 
void init();
void reshape(int w, int h);
void timer(int t);
void display();
 
 
void init()
{
    glClearColor(0.5, 0.5, 0.5, 1.0);
    glClearDepth(1.0f);
 
    programObject = createProgram("simple.vert", "simple.frag");
}
 
 
void reshape(int w, int h)
{
    glViewport(0, 0, w, h); 
}
 
void timer(int t)
{
    glutPostRedisplay();
    glutTimerFunc(t, timer, 17);
}
 
void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
    glUseProgram(programObject);
 
    /* ここに描画記述 */
 
    glUseProgram(0);
 
    glutSwapBuffers();
}
 
 
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitWindowSize(600, 400);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("test");
 
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutTimerFunc(100, timer, 17);
 
    GLenum err;
    //glewExperimental = GL_TRUE; // 有効なエントリーポイントを持つ全ての拡張の公開が保証
    err = glewInit();
    if (err != GLEW_OK) {
        std::cerr << "GLEW error : " << glewGetErrorString(err) << "\n";
        std::exit(1);
    }   
    if (!glewIsSupported("GL_VERSION_3_2"))
    {
        printf("OpenGL 3.2 not supported.");
        std::exit(1);
    }
 
    init();
 
    glutMainLoop();
 
    return 0;
}
 

  • simple.vert
void main(void)
{
  gl_Position = vec4(0.0, 0.0, 0.0, 0.0);
}
 

シェーダでは、必ずgl_Positionが必要のようです。


  • simple.frag
void main(void)
{
}
 


ダウンロード


glsl_empty00.tgz

タグ:

OpenGL GLSL
記事メニュー
ウィキ募集バナー