игра для iPhone 2d тени - PullRequest
       48

игра для iPhone 2d тени

2 голосов
/ 17 октября 2010

Мы находимся в процессе создания игры для iPhone, используя cocos2d . Мы пытаемся наложить несколько спрайтов друг на друга и заставить их отбрасывать тени.

Прямо сейчас тени отображаются как спрайты, которые по большей части работают нормально. Но мы хотим, чтобы тени попали в ближайший слой.

Я создал изображение, которое, мы надеемся, объясняет, чего мы пытаемся достичь:

image

А вот что мы имеем на данный момент:

image

По сути, мы хотим, чтобы спрайт отображал только ту часть тени, которая находится на той же глубине, что и z-буфер.

Мы поиграли с glDepthFunc и GL_DEPTH_TEST, но, похоже, ничего не работает.

Вот как мы рендерим теневой спрайт (CCSprite в подклассе):

- (void)draw {

    glDisable( GL_BLEND );

    glEnable( GL_DEPTH_TEST );
    glDepthFunc( GL_LESS );

    glDepthMask( GL_FALSE );
    [super draw];
    glDepthMask( GL_TRUE );

    glDisable( GL_DEPTH_TEST );

    glEnable( GL_BLEND );
}

GL_BLEND вызовы только там, поэтому мы можем видеть спрайт всегда.

Все спрайты, которые не являются тенями, используют glDepthMask( GL_TRUE ), и мы очищаем буфер глубины для каждого кадра.

Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 18 октября 2010
glDepthFunc(GL_LESS)

на самом деле значение по умолчанию; это означает «рисовать пиксель, только если объект, находящийся в данный момент в буфере глубины, находится дальше». Если бы вы хотели в точности равных, вы бы использовали glDepthFunc (GL_EQUAL), но на практике вы получите все виды странностей округления, если вы сделаете это.

Предполагая, что вы можете использовать значения глубины для этой цели, если у вас есть десять объектов, я бы предложил вам:

  1. установите glClearDepth на 0, прежде чем glClear; это заполнит буфер глубины ближайшим сохраняемым значением, чтобы при нормальной буферизации глубины больше ничего не рисовалось.
  2. отключите глубину и нарисуйте тени так, чтобы они падали на заднюю плоскость; в этот момент ваш буфер глубины будет по-прежнему заполнен ближайшим возможным значением.
  3. включить проверку глубины, но установить glDepthFunc в GL_ALWAYS. Затем нарисуйте все ваши сплошные прямоугольники в обратном порядке с соответствующими значениями глубины.
  4. установите для glDepthFunc значение GL_LESS и нарисуйте тени, которые должны падать на другие спрайты, каждая из которых расположена дальше, чем спрайт, с которым они связаны, но перед спрайтом позади.

К тому времени, как вы перейдете к шагу 4, вы будете иметь правильную информацию о глубине везде, где был нарисован спрайт, и у вас будет установлено максимально близкое значение, где бы ни была фоновая плоскость. Поэтому обычное тестирование глубины будет работать с промежуточными тенями - они будут рисовать поверх всего, что нарисовано на шаге 3, но не поверх всего, что нарисовано на шаге 2.

Вы как бы используете буфер глубины в качестве суррогатного трафарета, который старые айфоны не поддерживают.

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

...