スポンサーリンク

GLSLを試す (2) 変換行列の受け渡し

頂点シェーダへの変換行列の受け渡しの方法は二つ。

built-in変数を使う場合

C言語側

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

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(65, 1, 0.1, 10);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslated(0.0, 0.0, -0.8);

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

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

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

  // 三角形を描きます!
  glDrawArrays(GL_TRIANGLES, 0, 3); // 頂点0から始まります。合計3つの頂点です。→1つの三角形です。

  glDisableVertexAttribArray(0);
  glDisableVertexAttribArray(1);

  glFlush();
}

頂点シェーダ側

uniform変数 gl_ModelViewMatrixやgl_ProjectionMatrixでOpenGLの行列にアクセス出来る。これらはglUniformMatrix4fvで設定する必要が無い。

#version 460 core

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

out vec4 vertexColor;

uniform mat4 gl_ModelViewMatrix;
uniform mat4 gl_ProjectionMatrix;

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

この他のBuilt-In-Matrixは以下を参照

https://en.wikibooks.org/wiki/GLSL_Programming/Applying_Matrix_Transformations

glUniformMatrix4fvで共有する場合

C言語側

自分のプログラム内で行列を用意してglUniformMatrix4fvでGPUへ転送する。Projection Matrixを計算するコードを自前で書くのも間抜けなので

https://www.khronos.org/opengl/wiki/GluPerspective_code

などをコピペすると良い。

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

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

  //変換行列を定義
  // uniform mat4がfloatのため、こちらもfloatでないといけない
  GLfloat mfproj[16];
  GLfloat mftran[16];

  mfproj[ 0] = 2.26961231;
  mfproj[ 1] = 0.0;
  mfproj[ 2] = 0.0;
  mfproj[ 3] = 0.0;
  mfproj[ 4] = 0.0;
  mfproj[ 5] = 2.41421366;
  mfproj[ 6] = 0.0;
  mfproj[ 7] = 0.0;
  mfproj[ 8] = 0.0;
  mfproj[ 9] = 0.0;
  mfproj[10] = -1.00020003;
  mfproj[11] = -1.00000000;
  mfproj[12] = 0.0;
  mfproj[13] = 0.0;
  mfproj[14] = -0.0200020000;
  mfproj[15] = 0.0;

  mftran[ 0] = 1.0;
  mftran[ 1] = 0.0;
  mftran[ 2] = 0.0;
  mftran[ 3] = 0.0;
  mftran[ 4] = 0.0;
  mftran[ 5] = 1.0;
  mftran[ 6] = 0.0;
  mftran[ 7] = 0.0;
  mftran[ 8] = 0.0;
  mftran[ 9] = 0.0;
  mftran[10] = 1.0;
  mftran[11] = 0.0;
  mftran[12] = 0.2;
  mftran[13] = 0.0;
  mftran[14] = 0.0;
  mftran[15] = 1.0;


  GLint proj = glGetUniformLocation(ProgramID, "m_projection");
  GLint tran = glGetUniformLocation(ProgramID, "m_transform");
  glUniformMatrix4fv(proj, 1, GL_FALSE, mfproj);
  glUniformMatrix4fv(tran, 1, GL_FALSE, mftran);

  // 最初の属性バッファ:頂点
  glEnableVertexAttribArray(0);
  glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
  glVertexAttribPointer(
    0,                  // 属性0
    3,                  // サイズ
    GL_FLOAT,           // タイプ
    GL_FALSE,           // 正規化しない(データが整数型の時)
    0,                  // ストライド
    (void*)0            // 配列バッファオフセット
  );

  // 2nd attribute buffer : colors
  glEnableVertexAttribArray(1);
  glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
  glVertexAttribPointer(
    1,                  // 属性1
    3,                  // サイズ
    GL_FLOAT,           // タイプ
    GL_FALSE,           // 正規化しない(データが整数型の時)
    0,                  // ストライド
    (void*)0            // 配列バッファオフセット
  );

  // 三角形を描きます!
  glDrawArrays(GL_TRIANGLES, 0, 3);

  glDisableVertexAttribArray(0);
  glDisableVertexAttribArray(1);

  glFlush();
}

頂点シェーダ側

#version 460 core

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

out vec4 vertexColor;

uniform mat4 m_transform;
uniform mat4 m_projection;

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

コメントを残す

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

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


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