OpenGL ES 1.1 2D кольцо с текстурой iPhone - PullRequest
1 голос
/ 14 сентября 2011

Буду признателен за помощь в следующем. Я пытаюсь отобразить форму кольца поверх другого объекта в OpenGL ES 1.1 для игры для iPhone. Кольцо - это, по сути, разница между двумя кружками.

У меня есть изображение, подготовленное для самого кольца, которое прозрачно в центре.

Я надеялся просто создать круг и применить к нему текстуру. Текстура представляет собой изображение кольца, которое занимает полный размер текстуры (то есть внешняя сторона кольца касается четырех сторон текстуры). Центр кольца прозрачен на используемом графике.

Он должен быть прозрачным в центре, чтобы позволить объекту снизу просвечивать. Кольцо отрисовывается правильно, но представляет собой сплошную черную массу в центре, а не прозрачную. Буду признателен за любую помощь, чтобы решить эту проблему.

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

if (!m_circleEffects.empty())
{
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);

    int segments = 360;
    for (int i = 0; i < m_circleEffects.size(); i++)
    {            
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glTranslatef(m_circleEffects[i].position.x, m_circleEffects[i].position.y, 0);

        glBindTexture(GL_TEXTURE_2D, m_Texture);

        float radius = 1.764706;

        GLfloat circlePoints[segments * 3];
        GLfloat textureCoords[segments * 2];

        int circCount = 3;
        int texCount = 2;

        for (GLfloat i = 0; i < 360.0f; i += (360.0f / segments))
        {
            GLfloat pos1 = cosf(i * M_PI / 180);
            GLfloat pos2 = sinf(i * M_PI / 180);

            circlePoints[circCount] = pos1 * radius;
            circlePoints[circCount+1] = pos2 * radius;
            circlePoints[circCount+2] = (float)z + 5.0f;

            circCount += 3;

            textureCoords[texCount] = pos1 * 0.5 + 0.5;
            textureCoords[texCount+1] = pos2 * 0.5 + 0.5;

            texCount += 2;
        }

        glVertexPointer(3, GL_FLOAT, 0, circlePoints);
        glTexCoordPointer(2, GL_FLOAT, 0, textureCoords);

        glDrawArrays(GL_TRIANGLE_FAN, 0, segments);  
    }

    m_circleEffects.clear();  

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

Я экспериментировал с попыткой создать кольцо, а не круг, но я пока не смог сделать это правильно.

Я полагаю, что на самом деле лучший подход - не создавать круг, а кольцо, а затем получать эквивалентные координаты текстуры. Я все еще экспериментирую с шириной кольца, но, вероятно, радиус кольца равен 1/4 ширины всего круга.

Все еще новичок в OpenGL и пытаюсь обернуть голову вокруг него. Заранее благодарим за любые указатели / фрагменты, которые могут помочь.

Спасибо.

1 Ответ

1 голос
/ 14 сентября 2011

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

glEnable(GL_BLEND);

и установите стандартные функции наложения для использования альфа-компонента цвета в качестве непрозрачности:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Но всегда имейте в виду, что для того, чтобы увидеть, как прозрачный объект правильно наложен на объект позади, вам нужно визуализировать ваши объекты в обратном порядке.

Но если вы используете альфу только в качестве индикатора объекта / без объекта (только значения 0 или 1) и не нуждаетесь в частично прозрачных цветах (например, в стекле), вам не нужно сортировать ваши объекты. В этом случае вы должны использовать альфа-тест для отбрасывания фрагментов на основе их альфа-значений, чтобы они не загрязняли буфер глубины и не позволяли визуализировать лежащий позади объект. Альфа-тестовый набор с

glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.5f);

будет отображать только фрагменты (~ пиксели), которые имеют альфа более 0,5, и полностью отбрасывает все остальные фрагменты. Если у вас есть только альфа-значения 0 (нет объекта) или 1 (объект), это именно то, что вам нужно, и в этом случае вам на самом деле не нужно включать смешивание или даже сортировать ваши объекты обратно на фронт.

...