glMaterialfv не работает для меня - PullRequest
1 голос
/ 01 декабря 2011

Это OpenGL на iPhone 4.

Я рисую сцену, используя свет и материалы.Вот фрагмент моего кода: glMatrixMode (GL_PROJECTION);glLoadIdentity ();glFrustumf (-1, 1, -1, 1, -1, 1);

CGFloat ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
CGFloat diffuseLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };
CGFloat direction[] = { 0.0f, 0.0f, -20.0f, 0 };

glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_POSITION, direction);


glShadeModel(GL_FLAT);
glEnable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);

float blankColor[4] = {0,0,0,1};
float whiteColor[4] = {1,1,1,1};
float blueColor[4] = {0,0,1,1};

glMaterialfv(GL_FRONT, GL_DIFFUSE, blueColor);

glEnable(GL_CULL_FACE);

glVertexPointer(3, GL_FLOAT, 0, verts.pdata);
    glEnableClientState(GL_VERTEX_ARRAY);

glNormalPointer(GL_FLOAT, 0, normals.pdata);
glEnableClientState(GL_NORMAL_ARRAY);

glDrawArrays (GL_TRIANGLES, 0, verts.size/3);

Проблема в том, что вместо того, чтобы видеть СИНИЙ диффузный цвет, я вижу его белым.Он исчезает, если я поворачиваю сторону модели, но не могу понять, почему он не использует мой синий цвет.

Кстати, если я изменю glMaterialfv (GL_FRONT, GL_DIFFUSE, blueColor) на glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, blueColor)Я вижу синий цвет.Если я это сделаю, glMaterialfv (GL_FRONT, GL_DIFFUSE, blueColor);и затем glMaterialfv (GL_BACK, GL_DIFFUSE, blueColor);Я снова вижу белый цвет.Похоже, что GL_FRONT_AND_BACK показывает это, но остальные комбинации показывают белый цвет.Кто-нибудь может мне это объяснить?

1 Ответ

1 голос
/ 01 декабря 2011

Это из-за часовой стрелки

10.090 Как работает отбраковка лица? Почему не используется нормальная поверхность?

При отборе граней OpenGL вычисляется область со знаком заполненного примитива в координатном пространстве окна. Зона со знаком положительна, когда координаты окна расположены против часовой стрелки, и отрицательна, когда по часовой стрелке. Приложение может использовать glFrontFace (), чтобы указать порядок, против часовой стрелки или по часовой стрелке, который будет интерпретироваться как примитив, обращенный вперед или назад. Приложение может указать отбраковку передней или задней граней, вызвав glCullFace (). Наконец, выбор лица должен быть включен с помощью вызова glEnable (GL_CULL_FACE); .

OpenGL использует проекцию пространства окна вашего примитива, чтобы определить выборку лица по двум причинам. Для создания интересных световых эффектов часто желательно указывать нормали, которые не ортогональны аппроксимируемой поверхности. Если эти нормали использовались для отбора лиц, это может привести к ошибочной отбраковке некоторых примитивов. Кроме того, для схемы отбора точечного произведения может потребоваться инверсия матрицы, что не всегда возможно (т. Е. В случае, когда матрица является единственной), тогда как область со знаком в пространстве DC всегда определяется.

Однако некоторые реализации OpenGL поддерживают расширение GL_EXT_ cull_vertex. Если это расширение присутствует, приложение может указать однородное положение глаз в пространстве объектов. Вершины помечены как отбракованные, основываясь на точечном произведении текущей нормали с вектором из вершины в глаз. Если все вершины примитива отбракованы, примитив не отображается. Во многих случаях, используя это расширение

с здесь

Также вы можете прочитать здесь

...