更新:このようなもののほとんどがなくなったようです。OpenGL ES 2.0 で適切にライティングを行う方法は、独自のシェーダーを作成し、任意の方法で法線を渡し、シェーダーでライティングを行うことだと思います。特に、OpenGL ES 2.0 のドキュメントによると、glMaterialFv、glLightFv などはもうありません (glNormalPointer とその友人は言うまでもありません)。ただし、ドロップインの代替品としてそのままでは機能しないようです。ただし、GLKit には、OpenGL ES 1.1 のライティング機能を模倣する標準シェーダーがいくつか用意されています。
誰かがさらに情報を持っていれば、私はそれを感謝しますが、それが答えだと思います.
私は OpenGL を初めて使用するので、事前に混乱をお詫びします。iOS で OpenGL ES 2.0 を使用しています。インターネットで見つけた例の多くは時代遅れのようです。たとえば、glBegin(GL_POLYGON) 方法論は廃止されたようです。そのため、古い例のほとんどがそうであるように、glNormal3f を使用できないと思います。
Ray Wenderlich の素敵なチュートリアルから始めて、作成中のゲームに統合し、いくつかの部屋の基本的なジオメトリを正常にレンダリングしました。今、私は照明を追加したいだけです。何が機能していないのかわかりませんが、法線に関係していると思われます。
私はGL_LIGHT0を有効にしようと混乱した試みをしました.
//* Some attempts at lighting
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shininess[] = { 50.0 };
GLfloat light0_position[] = { 0.0, 0.0, 7.99, 0.0 };
GLfloat light0_ambience[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat light0_specular[] = { 1.0, 1.0, 1.0, 1.0 };
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambience);
glLightfv(GL_LIGHT0, GL_SPECULAR, light0_specular);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//*/
glEnable(GL_DEPTH_TEST);
VBOS を使用して、頂点の位置と色を単純なシェーダーのペアに渡しています。以下はチュートリアルからです。
_positionSlot = glGetAttribLocation(programHandle, "Position");
_colorSlot = glGetAttribLocation(programHandle, "SourceColor");
次に、render: メソッドで (位置と色の位置の間に法線を含めるように Vertex 構造を変更しました)。
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE,
sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (GLvoid*) (sizeof(float) * 6));
照明を除いて、これはすべて非常にうまく機能します。法線を計算して再計算しました。X 軸と Y 軸に平行な垂直の長方形の壁の場合、これは簡単なことです。これらは、GL_ARRAY_BUFFER にバインドされたバッファーの一部であり、位置と色の情報も含まれています。
glNormalPointer を使用するために繰り返し試みました。
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), (GLvoid*)(sizeof(float)*3));
チュートリアルの頂点構造は次のようになります。
typedef struct {
float Position[3];
float Normal[3];
float Color[4];
} Vertex;
上記の呼び出しは成功しますが、照明効果は表示されません。一部の情報源は、法線にも glVertexAttribPointer を使用する必要があることを示唆しています。このために、チュートリアルの頂点シェーダーを次のように変更しました。
attribute vec4 Position;
attribute vec4 SourceColor;
attribute vec3 Normal;
varying vec4 DestinationColor;
uniform mat4 Projection;
uniform mat4 Modelview;
void main(void) {
DestinationColor = SourceColor;
gl_Position = Projection * Modelview * Position;
}
そして、そのNormal変数を使用できるようになると思った呼び出しを追加しました(OpenGLがそれをどうするかをどのように知っているかはわかりませんが):
// just before glLinkProgram()
glBindAttribLocation(programHandle, 1, "Normal");
GLuint _normalSlot = glGetAttribLocation(programHandle, "Normal");
glVertexAttribPointer(_normalSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(float)*3));
GLSL ファイルのどこに Normal 変数を配置しても、glBindAttribLocation はその属性に対して常に失敗し、glGetAttribLocation は常にその属性に対して -1 を返します。(glBindAttribLocation を使用して SourceColor 属性の場所を正常に変更できますが、Normal は受け入れられません。) 以前のバージョンの OpenGL/GLSL には gl_Normal 変数がありましたが、明らかにそれ以上はありません。
私は途方に暮れていて、私に起こることは何でも試し続けています. 私の次のステップは、glInterleavedArrays です。可動部分が多すぎて、問題を見つけるのが大変です。私の法線は最初から大丈夫だったのかもしれませんが、代わりにライトに問題があります。照明以外に、法線が正しいことを確認する方法はありますか? または、法線が間違っている場合、ライトから何かを見ることができるはずですか?
したがって、この投稿の長さと混乱をお詫びしますが、この状況で法線がどのように指定されているかについての詳細な説明は大歓迎です。OpenGL ES 2.0 では状況が異なるという意見に繰り返し出くわしますが、詳細な例はありません。前もって感謝します。