如何使用蒙版裁剪图像并将其与iPhone上的其他图像(背景)合并?(OpenGL ES 1.1是首选)

Ole*_*man 6 iphone opengl-es objective-c cocos2d-iphone ios

我需要按照我在附件中表示的方式组合三个图像:

在此输入图像描述

1)一张图片是背景.它没有alpha通道意义上的"稳固".

2)另一个是精灵.雪碧躺在背景上.Sprite可能有自己的alpha通道,背景必须在sprite透明的地方可见.

3)有许多掩码:我每帧都对Sprite应用新的掩码.面具不是长方形.

换句话说,可见像素=背景像素,如果裁剪蒙版对应颜色为白色或精灵是透明的; 否则为精灵的像素(例如,相应的掩模的像素为黑色).

我正在使用cocos2d-iphone.我可以使用cocos2d-iphone或OpenGL ES 1.1进行组合吗?如果答案是肯定的,那么工作代码将不胜感激.如果两个答案都是NO,iOS上是否有其他技术可以制作我想要的东西(可能是Quartz2d或OpenGL ES 2.0)?

对于Sprite,蒙版格式不是强制性黑色,对于背景则是白色.我可以制作所需格式的蒙版,例如背景的透明度和Sprite的白色(如果需要).

PS还有另一个同样没有答案的问题: 可以改变iPhone上某些像素的alpha值吗?

Mar*_*ark 8

这是我对OpenGL的回答.Quartz的程序非常不同.实际的代码非常简单,但是完全正确的代码是棘手的部分.我使用的GL上下文是1024X1024,左下角是原点.我没有发布我的代码,因为它使用了OpenGL | ES中没有的立即模式.如果你想要我的绘图代码,请告诉我,我会更新我的答案.

  1. 在禁用混合的情况下绘制蒙版.
  2. 启用混合,设置GLBlendFunc(GL_DST_COLOR,GL_ZERO)并通过纹理绘制出血.我的面具是白色的,它应该渗透.在你的问题中它是黑色的.
  3. 现在绘制背景,将blend函数设置为glBlendFunc(GL_ONE_MINUS_DST_COLOR,GL_DST_COLOR)并绘制背景纹理.

编辑这是我上面描述的代码.请注意,这不适用于iOS,因为没有立即模式,但您应该能够在Macintosh项目中使用它.一旦它工作,您可以将其转换为Macintosh项目中的iOS兼容,然后将该代码移动到您的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;
}
Run Code Online (Sandbox Code Playgroud)

这显示我正常绘制的三个纹理(裁剪,渗透和背景),然后合并到下面.

图片