スポンサーリンク

OpenGL 1.5 相当の機能でVBOありシェーダ指定なしで描画する

Vertex Buffer Objectが導入されたのはOpenGL 1.5からで、この時はシェーダの指定が必要なかったとのこと。別にシェーダを用意するのもテストでは面倒なのでありがたい。

基本的な使い方

glEnableClientStateで使用するバッファの種類を指定。glBindBufferした後glVertexPointerする。

glVertexPointerの最後の「0」はCPUメモリ上のバッファのポインタを入れるが、0を指定すると使用する頂点バッファがバインドしたバッファになる。

#include <Windows.h>
#include <GL/glew.h>

#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/freeglut.h>

#include <vector>
#include <array>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glew32.lib")

//ウィンドウの幅と高さ
int width, height;

double rotate_angle = 0;

// バッファ名
GLuint buffer;

void init_data() {
  glEnableClientState(GL_VERTEX_ARRAY);

  float v = 0.7;
  std::vector< std::array<float,3> > data;
  data.push_back({ 0.f,0.f,0.f });
  data.push_back({ -v,-v,0 });
  data.push_back({ v,-v,0 });

  glGenBuffers(1, &buffer);
  glBindBuffer(GL_ARRAY_BUFFER, buffer);
  glBufferData(
    GL_ARRAY_BUFFER,
    sizeof(GLfloat) * 3 * data.size(),
    data[0].data(),
    GL_STATIC_DRAW);
  glVertexPointer(3, GL_FLOAT, 0, 0);

}

void render_data() {
  glColor3f(1, 0, 0);
  // バッファのデータと関連づけ
  glBindBuffer(GL_ARRAY_BUFFER, buffer);
  glVertexPointer(3, GL_FLOAT, 0, 0);
  // 描画
  glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
}
//描画関数
void disp(void) {

  glClearColor(0.2, 0.2, 0.2, 1);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glViewport(0, 0, width, height);
  //カメラの設定
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(60, width / (double)height, 0.1, 3);
  glMatrixMode(GL_MODELVIEW);//モデルビューの設定
  glLoadIdentity();
  glTranslated(0, 0, -2);
  glRotated(rotate_angle, 0, 1, 0);

  ////////////////////////////////////////////
  render_data();
  ////////////////////////////////////////////


  glFlush();
}

void finalizer() {
  glDeleteBuffers(1, &buffer);
}

//ウィンドウサイズの変化時に呼び出される
void reshape(int w, int h) {
  width = w; height = h;

  disp();
}

void timer(int value)
{
  rotate_angle += 5;

  disp();
  glutTimerFunc(10, timer, 0);
}

//エントリポイント
int main(int argc, char** argv)
{
  glutInit(&argc, argv);
  glutInitWindowPosition(100, 50);
  glutInitWindowSize(500, 500);
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);

  glutCreateWindow("sample");

  glewInit();
  init_data();


  glutDisplayFunc(disp);
  glutReshapeFunc(reshape);
  glutTimerFunc(1000, timer, 0);//タイマー
  glutMainLoop();

finalizer();
return 0; }

頂点色も使用する例

glBindBuffer → glVertexPointer で、バインドしたバッファを頂点座標に使用することを教える。

glBindBuffer → glColorPointer で、バインドしたバッファを頂点色に使用することを教える。

#include <Windows.h>
#include <GL/glew.h>

#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/freeglut.h>

#include <vector>
#include <array>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glew32.lib")

//ウィンドウの幅と高さ
int width, height;

double rotate_angle = 0;

// バッファ名
GLuint buffer[2];
const int VTX = 0;
const int COL = 1;

void init_data() {

  float v = 0.7;
  // 頂点データ
  std::vector< std::array<float,3> > vertex;
  vertex.push_back({ 0,0,0 });
  vertex.push_back({ -v,-v,0 });
  vertex.push_back({ v,-v,0 });

  // 色データ
  std::vector< std::array<float, 4> > color;
  color.push_back({ 1,0,0,1 });
  color.push_back({ 0,1,0,1 });
  color.push_back({ 0,0,1,1 });

  // バッファ作成
  glGenBuffers(2, &buffer[0]);
  ///////////////////////////////////////////
  glBindBuffer(GL_ARRAY_BUFFER, buffer[VTX]);
  glBufferData(
    GL_ARRAY_BUFFER,
    sizeof(GLfloat) * 3 * vertex.size(),
    vertex[0].data(),
    GL_STATIC_DRAW);
  ///////////////////////////////////////////
  glBindBuffer(GL_ARRAY_BUFFER, buffer[COL]);
  glBufferData(
    GL_ARRAY_BUFFER,
    sizeof(GLfloat) * 4 * color.size(),
    color[0].data(),
    GL_STATIC_DRAW);
  ///////////////////////////////////////////

}

void render_data() {
  glEnableClientState(GL_COLOR_ARRAY);  // 色配列を有効化
  glEnableClientState(GL_VERTEX_ARRAY); // 頂点配列を有効化

  // 頂点配列を有効化
  glBindBuffer(GL_ARRAY_BUFFER, buffer[VTX]);
  glVertexPointer(3, GL_FLOAT, 0, 0);

  // 色配列を有効化
  glBindBuffer(GL_ARRAY_BUFFER, buffer[COL]);
  glColorPointer(4, GL_FLOAT, 0, 0);

  // 有効化の設定ここまで
  glBindBuffer(GL_ARRAY_BUFFER, 0);

  // 描画
  glDrawArrays(GL_TRIANGLES, 0, 3);
}

//描画関数
void disp(void) {

  glClearColor(0.2, 0.2, 0.2, 1);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glViewport(0, 0, width, height);
  //カメラの設定
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(60, width / (double)height, 0.1, 3);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslated(0, 0, -2);
  glRotated(rotate_angle, 0, 1, 0);

  ////////////////////////////////////////////
  render_data();
  ////////////////////////////////////////////


  glFlush();
}
void finalizer() {
  glDeleteBuffers(2, buffer);
}

実行するとgluPerspectiveやglTranslated,glRotatedでの指定で三角形が回転する。

参考

算譜記録帳

http://mklearning.blogspot.com/2014/08/opengl.html

床井研究

https://marina.sys.wakayama-u.ac.jp/~tokoi/?date=20080829

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

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


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