1

私は、OpenGL ES iPhone シーンで単純なライティングを正しく行うことに取り組んでいます。原点を中心に単純なオブジェクトを表示し、アークボールを使用して画面をタッチして回転させています。これはすべてうまく機能しますが、1 つの固定ライト (目の位置に固定) を追加しようとすると、ひどくねじ込まれます。オブジェクト全体 (この例では 20 面体) が均一に照らされます。つまり、すべてが同じ色で表示されます。

コードを可能な限り単純化したので、スタンドアロンであり、経験したことを再現できます。

    glClearColor (0.25, 0.25, 0.25, 1.);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable (GL_DEPTH_TEST);

    glEnable(GL_LIGHTING);

    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glOrthof(-1, 1, -(float)backingWidth/backingHeight, (float)backingWidth/backingHeight, -10, 10);

    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity ();

    GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
    GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
    GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
    GLfloat position[] = { -1.5f, 1.0f, -400.0f, 0.0f };

    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
    glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
    glLightfv(GL_LIGHT0, GL_POSITION, position);

    glShadeModel(GL_SMOOTH);
    glEnable(GL_NORMALIZE);

    float currRot[4];
    [arcball getCurrentRotation:currRot];
    glRotatef (currRot[0], currRot[1], currRot[2], currRot[3]);

    float f[4];
    f[0] = 0.5; f[1] = 0; f[2] = 0; f[3] = 1;
    glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, f);
    glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, f);

    f[0] = 0.2;     f[1] = 0.2; f[2] = 0.2; f[3] = 1;
    glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, f);

    glEnableClientState (GL_VERTEX_ARRAY);
    drawSphere(0, 0, 0, 1);

drawSphere 関数は実際に 20 面体を描画します。

static void drawSphere (float x, float y, float z, float rad)
{ 
    glPushMatrix ();
    glTranslatef (x, y, z);
    glScalef (rad, rad, rad);

    // Icosahedron
    const float vertices[] =
    { 0., 0., -1., 0., 0., 1., -0.894427, 0., -0.447214, 0.894427, 0.,
            0.447214, 0.723607, -0.525731, -0.447214, 0.723607, 0.525731,
            -0.447214, -0.723607, -0.525731, 0.447214, -0.723607, 0.525731,
            0.447214, -0.276393, -0.850651, -0.447214, -0.276393, 0.850651,
            -0.447214, 0.276393, -0.850651, 0.447214, 0.276393, 0.850651,
            0.447214 };
    const GLubyte indices[] =
    { 1, 11, 7, 1, 7, 6, 1, 6, 10, 1, 10, 3, 1, 3, 11, 4, 8, 0, 5, 4, 0,
            9, 5, 0, 2, 9, 0, 8, 2, 0, 11, 9, 7, 7, 2, 6, 6, 8, 10, 10, 4, 3,
            3, 5, 11, 4, 10, 8, 5, 3, 4, 9, 11, 5, 2, 7, 9, 8, 6, 2 };

    glVertexPointer (3, GL_FLOAT, 0, vertices);
    glDrawElements (GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_BYTE, indices);
    glPopMatrix ();
}

結果として私が見るもののムービーはこちらです。これに光を当てることができる人に感謝します(冗談ではありません!)。誰かにとっては恥ずかしいほど些細なことに見えると確信していますが、これまでに多くの照明チュートリアルを見て行き詰まったことを誓います。

4

1 に答える 1

1

を使用していくつかの頂点法線を追加してみてくださいglNormalPointer()。OpenGL ES は、すべてにデフォルトの法線を使用しているようです。

于 2010-05-12T22:04:19.687 に答える