GeometryShader 利用時に GLSL のバージョンの違いが問題になったのでまとめてみました。
OpenGL 1.3 ---- OpenGL ES 1.0 ---- OpenGL 1.5 *1 OpenGL ES 1.1 ---- OpenGL 2.0 GLSL 1.1 OpenGL ES 2.0 GLSL ES 1.0 (ESSL) OpenGL 2.1 GLSL 1.2 OpenGL 3.0 GLSL 1.3 OpenGL 3.1 GLSL 1.4 OpenGL 3.2 GLSL 1.5 *1: Shader 対応。Extension で GLSL1.0 も利用可能。Core API になったのは OpenGL 2.0 から。
OpenGL ES 2.0 の GLSL は、GLSL ES または ESSL と呼ばれています。
上の対応表では OpenGL 2.0 / GLSL 1.1 の列にありますが、GLSL ES 1.0 自体は
GLSL 1.2 の機能も含まれています。実際は OpenGL 2.0~2.1 の中間になります。
OpenGL 2.0 で GLSL が core に組み込まれました。
OpenGL 3.0 / GLSL 1.3 で大きな仕様変更があり、シェーダーも固定機能の排除が
進められています。attribute/varying が in/out に変更になったのもここです。
Direct3D との対応付けは難しいですが、おそらく OpenGL 2.0 が Direct3D 9、
OpenGL 3.0 が ShaderModel 4.0 の Direct3D 10 に近い位置づけです。
実際はここまで明確な区別が無く、もっと入り組んでいるし互換性も保たれています。
機能拡張も段階的に進められています。
例えば OpenGL 3.1 で Uniform Block / Uniform Buffer が追加されていて、
これはちょうど Direct3D 10 の ConstantBuffer に相当するものです。
OpenGL 3.2 では Geometry Shader が入りました。
GLES と GLSL ES (ESSL) は「 #ifdef GL_ES 」で区別できます。
昨日はむりやり define して動かしましたが、下記のような定義でシェーダーを共有
することにしました。
// Vertex Shader #ifdef GL_ES # define IN attribute # define OUT varying # define LOWP lowp # define MEDIUMP mediump precision MEDIUMP float; precision MEDIUMP int; #else # define IN in # define OUT out # version 150 # define LOWP # define MEDIUMP #endif
// Fragment Shader #ifdef GL_ES # define IN varying # define LOWP lowp # define MEDIUMP mediump precision MEDIUMP float; precision MEDIUMP int; precision LOWP sampler2D; #else # define IN in # version 150 # define LOWP # define MEDIUMP #endif
OpenGL ES のコンパイラには少々問題があって、ソースの先頭に #version が無いと
エラーになるようです。コンパイルオプションの切り替えのために複数のソースを
渡しているせいか、#version をどこに書いてもエラーとなってしまいました。
上の定義では OpenGL ES 側に #version を書いていないのはそのためです。
関連エントリ
・OpenGL 3.2 の GeometryShader
・OpenGL のはじめ方
・OpenGL ES 2.0 Emulator
・OpenGL ES 2.0
・OpenGLES2.0 DDS テクスチャを読み込む
・OpenGLES2.0 Direct3D とのフォーマット変換
・OpenGLES 2.0 頂点フォーマットの管理
・OpenGLES2.0 の頂点
・OpenGLES2.0 D3D座標系
・OpenGLES2.0 シェーダー管理