スポンサーリンク

GLSLを試す (8) Index Buffer Object

この図では三角形を2枚書いて、IBOを使わない場合、定義しなければいけない頂点数は6となる。

IBOを使うと共通に使用する頂点をまとめて4個にできる。

基本は以下と同じ:

GLSLを試す (1)

注目すべき点は、

・頂点バッファの定義は普通と同じ形式で良い

・IBOを使うからと言って、バーテクスシェーダ、フラグメントシェーダに変更を加える必要は無い

・頂点バッファなどを準備する時に、一緒にGL_ELEMENT_ARRAY_BUFFERでIBOを作成する

・glDrawArraysではなくglDrawElementsを使用する

バッファの準備

// バッファとデータ
typedef GLfloat points_t[3];
GLuint vertexbuffer;//バッファのIDを格納する変数
GLuint colorbuffer;//バッファのIDを格納する変数

GLuint indexbuffer;//三角形を頂点IDで表現するバッファのIDを格納する変数

//////////////////////////////////////////////////
// データの準備
void prepare_buffers() { points_t position[4]; points_t color[4]; //頂点座標 position[0][0] = 0; position[0][1] = 0.5; position[0][2] = 0; position[1][0] = 0.5; position[1][1] = -0.5; position[1][2] = 0; position[2][0] = -0.5; position[2][1] = -0.5; position[2][2] = 0; position[3][0] = 0; position[3][1] = -1.0; position[3][2] = 0; //色 color[0][0] = 1.0; color[0][1] = 0.0; color[0][2] = 0.0; color[1][0] = 0.0; color[1][1] = 1.0; color[1][2] = 0.0; color[2][0] = 0.0; color[2][1] = 0.0; color[2][2] = 1.0; color[3][0] = 1.0; color[3][1] = 1.0; color[3][2] = 1.0; //頂点座標のバッファ glGenBuffers(1, &vertexbuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); glBufferData( GL_ARRAY_BUFFER, 4 * 3 * sizeof(GLfloat), position, GL_STATIC_DRAW); //頂点カラーのバッファ glGenBuffers(1, &colorbuffer); glBindBuffer(GL_ARRAY_BUFFER, colorbuffer); glBufferData( GL_ARRAY_BUFFER, 4 * 3 * sizeof(GLfloat), color, GL_STATIC_DRAW);
  //頂点Indexで表現した三角形一覧
  // △012,△213 の二つを定義
  GLuint triangle_elements[] = {
    0,1,2 ,
    2,1,3
  };

  //三角形の頂点IDのバッファ
  const size_t triangle_elements_memsize = sizeof(triangle_elements);

glGenBuffers(1, &indexbuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbuffer); glBufferData( GL_ELEMENT_ARRAY_BUFFER, triangle_elements_memsize, // バッファのメモリ上のバイト数を求める triangle_elements, //バッファへのポインタ GL_STATIC_DRAW ); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

レンダリング

void display(void)
{
  glClearColor(0, 0, 0, 1);
  glClear(GL_COLOR_BUFFER_BIT);

  // シェーダを使う
  glUseProgram(ProgramID);

  // 頂点バッファ:頂点
  glEnableVertexAttribArray(0);
  glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
  glVertexAttribPointer(
    0,                  // シェーダ内のlayoutとあわせる
    3,                  // 1要素の要素数(x,y,z)で3要素
    GL_FLOAT,           // タイプ
    GL_FALSE,           // 正規化しない(データが整数型の時)
    0,                  // ストライド
    (void*)0            // 配列バッファオフセット
  );

  // カラーバッファを有効にする
  glEnableVertexAttribArray(1);
  glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
  glVertexAttribPointer(
    1,                  // シェーダ内のlayoutとあわせる
    3,                  // 1要素の要素数(r,g,b)で3要素
    GL_FLOAT,           // タイプ
    GL_FALSE,           // 正規化しない(データが整数型の時)
    0,                  // ストライド
    (void*)0            // 配列バッファオフセット
  );

  // 三角形を描きます!
  glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbuffer);
  //int size;
  //glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);

  glDrawElements(
    GL_TRIANGLES,
    6,  // 頂点数。size / sizeof(GLuint) の式でも頂点数を算出できる。
    GL_UNSIGNED_INT,
    0
  );
  glDisableVertexAttribArray(0);//バッファを無効にする
  glDisableVertexAttribArray(1);

  glFlush();
}

シェーダー

各シェーダはIBOの使用の有無で書き換える必要は無い。

頂点シェーダ

#version 460 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 incolor;

out vec4 vertexColor;

void main()
{
  gl_Position = vec4(aPos, 1.0);
  vertexColor = vec4(incolor, 1.0);
}

フラグメントシェーダ

#version 460 core

out vec4 FragColor;
  
in vec4 vertexColor;

void main()
{
  FragColor = vertexColor;
} 

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: