Как я могу обрезать изображение с маской и объединить его с другим изображением (фоном) на iPhone?(OpenGL ES 1.1 является предпочтительным) - PullRequest
6 голосов
/ 14 марта 2011

Мне нужно объединить три изображения, как я представляю в прикрепленном файле:

enter image description here

1) Одно изображение является фоновым. Он «твердый» в том смысле, что не имеет альфа-канала.

2) Еще один спрайт. Спрайт лежит на заднем плане. У спрайта может быть собственный альфа-канал, фон должен быть виден в местах, где спрайт прозрачен.

3) Существует несколько масок: я применяю новую маску для спрайта каждого кадра. Маска не прямоугольная.

Другими словами, видимый пиксель = пиксель фона, если цвет обрезки соответствует белому ИЛИ спрайт прозрачен; в противном случае пиксель спрайта (например, соответствующий пиксель маски черный).

Я работаю с cocos2d-iphone. Можно ли сделать такую ​​комбинацию с cocos2d-iphone или с OpenGL ES 1.1? Если какой-либо ответ ДА, рабочий код будет оценен. Если оба ответа НЕТ, есть ли в iOS другая технология для создания того, что я хочу (возможно, Quartz2d или OpenGL ES 2.0)?

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

P.S. Есть еще один вопрос такого же типа без ответа: Можно ли изменить значение альфа-канала определенных пикселей на iPhone?

1 Ответ

8 голосов
/ 14 марта 2011

Вот мой ответ для OpenGL.Процедура была бы совсем другой для Кварца.Фактический код довольно прост, но получить его правильно - сложная часть.Я использую контекст GL, который является 1024X1024 с источником в левом нижнем углу.Я не публикую свой код, потому что он использует немедленный режим, который недоступен в OpenGL | ES.Если вам нужен мой код для рисования, дайте мне знать, и я обновлю свой ответ.

  1. Рисуем маску с отключенным смешиванием.
  2. Включите смешивание, установите GLBlendFunc (GL_DST_COLOR, GL_ZERO) и нарисуйте кровоточащую текстуру.Моя маска белая, где она должна пролиться.В вашем вопросе это было черным.
  3. Теперь, чтобы нарисовать фон, установите функцию смешивания на glBlendFunc (GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR) и нарисуйте текстуру фона.

EDIT Вот код, который я описал выше.Обратите внимание, что это не будет работать на iOS, так как нет немедленного режима, но вы должны быть в состоянии заставить это работать в проекте Macintosh.Как только это сработает, вы можете преобразовать его во что-то совместимое с iOS в проекте Macintosh, а затем перенести этот код в свой проект iOS.

Вызов renderMask () - это то, где самая интересная часть.renderTextures () рисует образцы текстур в верхнем ряду.

static GLuint color_texture;
static GLuint mask_texture;
static GLuint background_texture;

static float window_size[2];

void renderMask()
{
float texture_x=0, texture_y=0;
float x=0, y=0;

{
    glBindTexture(GL_TEXTURE_2D, mask_texture);

    glDisable(GL_BLEND);
    glBegin(GL_QUADS);
        glTexCoord2f(texture_x,texture_y);
        glVertex2f(x,y);

        glTexCoord2f(texture_x+1.0,texture_y);
        glVertex2f(x+512.0,y);

        glTexCoord2f(texture_x+1.0,texture_y+1.0);
        glVertex2f(x+512.0,y+512.0);

        glTexCoord2f(texture_x,texture_y+1.0);
        glVertex2f(x,y+512.0);
    glEnd();
}

{
    glBindTexture(GL_TEXTURE_2D, color_texture);
    glEnable(GL_BLEND);
    glBlendFunc(GL_DST_COLOR, GL_ZERO);
    glBegin(GL_QUADS);
        glTexCoord2f(texture_x,texture_y);
        glVertex2f(x,y);

        glTexCoord2f(texture_x+1.0,texture_y);
        glVertex2f(x+512.0,y);

        glTexCoord2f(texture_x+1.0,texture_y+1.0);
        glVertex2f(x+512.0,y+512.0);

        glTexCoord2f(texture_x,texture_y+1.0);
        glVertex2f(x,y+512.0);
    glEnd();
}

{   
    glBindTexture(GL_TEXTURE_2D, background_texture);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR);
    glBegin(GL_QUADS);
        glTexCoord2f(texture_x,texture_y);
        glVertex2f(x,y);

        glTexCoord2f(texture_x+1.0,texture_y);
        glVertex2f(x+512.0,y);

        glTexCoord2f(texture_x+1.0,texture_y+1.0);
        glVertex2f(x+512.0,y+512.0);

        glTexCoord2f(texture_x,texture_y+1.0);
        glVertex2f(x,y+512.0);
    glEnd();
}
}

// Draw small versions of the textures.
void renderTextures()
{
float texture_x=0, texture_y=0;
float x=0, y=532.0;
float size = 128;

{
    glBindTexture(GL_TEXTURE_2D, mask_texture);

    glDisable(GL_BLEND);
    glBegin(GL_QUADS);
        glTexCoord2f(texture_x,texture_y);
        glVertex2f(x,y);

        glTexCoord2f(texture_x+1.0,texture_y);
        glVertex2f(x+size,y);

        glTexCoord2f(texture_x+1.0,texture_y+1.0);
        glVertex2f(x+size,y+size);

        glTexCoord2f(texture_x,texture_y+1.0);
        glVertex2f(x,y+size);
    glEnd();
}

{
    glBindTexture(GL_TEXTURE_2D, color_texture);
    x = size + 16;

    glBegin(GL_QUADS);
        glTexCoord2f(texture_x,texture_y);
        glVertex2f(x,y);

        glTexCoord2f(texture_x+1.0,texture_y);
        glVertex2f(x+size,y);

        glTexCoord2f(texture_x+1.0,texture_y+1.0);
        glVertex2f(x+size,y+size);

        glTexCoord2f(texture_x,texture_y+1.0);
        glVertex2f(x,y+size);
    glEnd();
}

{
    glBindTexture(GL_TEXTURE_2D, background_texture);
    x = size*2 + 16*2;
    glBegin(GL_QUADS);
        glTexCoord2f(texture_x,texture_y);
        glVertex2f(x,y);

        glTexCoord2f(texture_x+1.0,texture_y);
        glVertex2f(x+size,y);

        glTexCoord2f(texture_x+1.0,texture_y+1.0);
        glVertex2f(x+size,y+size);

        glTexCoord2f(texture_x,texture_y+1.0);
        glVertex2f(x,y+size);
    glEnd();
}
}

void init()
{
GLdouble bounds[4];

glGetDoublev(GL_VIEWPORT, bounds);

window_size[0] = bounds[2];
window_size[1] = bounds[3];

glClearColor(0.0, 0.0, 0.0, 1.0);

glShadeModel(GL_SMOOTH);

// Load our textures...
color_texture = [[NSImage imageNamed:@"colors"] texture];
mask_texture = [[NSImage imageNamed:@"mask"] texture];
background_texture = [[NSImage imageNamed:@"background"] texture];


// Enable alpha blending.  We'll learn more about this later
glEnable(GL_BLEND);

glEnable(GL_TEXTURE_2D);
}

void draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(1.0, 1.0, 1.0);

renderMask();
renderTextures();
}

void reshape(int width, int height)
{
glViewport(0, 0, width, height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, width, 0.0, height);
glMatrixMode(GL_MODELVIEW);

window_size[0] = width;
window_size[1] = height;
}

Здесь показаны мои три текстуры, нарисованные нормально (обрезка, обрезка и фон), а затем объединены ниже.

image

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...