みつきんのメモ

組み込みエンジニアです。Interface誌で「Yocto Projectではじめる 組み込みLinux開発入門」連載中

raspberrypiでOpenGLESプログラミング

ラズベリーパイOpenGLのプログラミングをはじめようと思ったが、ラズベリーパイではOpenGLESでプログラムする必要がある。 PCなどではOpenGLプログラミングというとglutやglfwなどが主流のようで、なかなかそのまま動くコードが見つからない。

また、OpenGLESで調べようとするとAndroidiOSの情報ばかりでこれもハードルが高い。 いろいろ調べていくと、OpenGLESの世界では、OpenGL ES 3.0 Programming GuideOpenGL ES 2.0 Programming Guideバイブルとなっているらしく、これらのコードを元にしたサンプルがあちこちで見かけられる。ここが大本か。

ただ、これは純粋にOpenGLESプログラミングの説明に集中するため、Windowsを表示するための最低限の仕組みはesUtil.cというフレームワークの中に隠蔽されており、ラズベリーパイでこれらのコードを動かすにはどうすればよいかがわかりづらい。

中には移植してGitHubにあげている人もいるが、「ラズベリーパイでOpenGLESプログラミングの第一歩」を踏み出すためは最低限何をすればよいかがなかなかわからない。

さらに調べた先にここを見つけた。 ここのrectangle.cがかなり求めていたものに近い。 余談だが、冒頭のコメントの「code stolen from」は面白い表現だと思った。

ただ、rectangle.cではOpenGLESの初期化コードとラズベリーパイのネイティブウィンドウシステムであるdispmanxの初期化コードがごっちゃに書かれているため、整理したものを作成した。

ラズベリーパイでOpenGLESプログラミングを行うにはまず次のキーワードを理解する必要がある。

  • dispmanx
  • EGL

dispmanxはラズベリーパイGPUを操作するためのAPIでローレベルのウィンドウシステムを提供するAPI

EGLはOpenGL(本来はKhronos rendering APIs)の描画周りの抽象化層で、実際に描画を行うネイティブウィンドウシステムとOpenGLとの橋渡しを行う。

そのため、ラズベリーパイではdispmanxとEGLを関連付ける必要がある。

大まかな手順としては次のようになる。

  1. dispmanxの初期化
  2. EGLの初期化
  3. EGLの描画コンテキストを作成
  4. dispmanxでウィンドウを作成
  5. EGLの描画コンテキストにdispmanxのウィンドウを関連付け

first_window.cではcreate_native_windowでdispmanxのウィンドウを作成、 init_oglでEGLの描画コンテキストの作成create_native_windowの呼び出し、 eglCreateWindowSurface関数により描画コンテキストとウィンドウを関連付けしている。

このプログラムを実行すると、画面が真っ赤に塗りつぶされる。

rectangle.cのサイトを作成したJan Newmarchさんがこのような本を書いているので参考になると思う。 OpenGLESのあたりから急にOpenGLES-bookのコードが手元にあることを前提に話が始まるので、それを頭に入れていないと混乱するかもしれない。