如何裁剪带有遮罩的图像并将其与iPhone上的另一个图像(背景)组合?(首选OpenGL ES 1.1)
我需要以我在附件中表示的方式组合三幅图像: 1) 一个图像是背景。它是“实心”的,因为它没有阿尔法通道 2) 另一个是雪碧。精灵躺在背景上。精灵可能有自己的阿尔法通道,背景必须在精灵透明的地方可见 3) 有许多遮罩:我在每一帧中应用新的遮罩。面具不是长方形的 换句话说,可见像素= 背景像素,如果裁剪遮罩对应的颜色是白色或精灵是透明的; 否则为精灵像素(例如,对应遮罩的像素为黑色) 我正在使用cocos2d iphone。我可以与cocos2d iphone或OpenGL ES 1.1进行这样的组合吗?如果答案是肯定的,工作代码将不胜感激。如果两个答案都是否定的,那么iOS上是否有其他技术可以满足我的需求(可能是Quartz2d或OpenGL ES 2.0) 遮罩格式对于精灵不是强制性的黑色,对于背景不是强制性的白色。我可以制作所需格式的遮罩,如背景的透明度和雪碧的白色,如果需要的话 还有一个同样的问题没有回答:如何裁剪带有遮罩的图像并将其与iPhone上的另一个图像(背景)组合?(首选OpenGL ES 1.1),iphone,objective-c,ios,opengl-es,cocos2d-iphone,Iphone,Objective C,Ios,Opengl Es,Cocos2d Iphone,我需要以我在附件中表示的方式组合三幅图像: 1) 一个图像是背景。它是“实心”的,因为它没有阿尔法通道 2) 另一个是雪碧。精灵躺在背景上。精灵可能有自己的阿尔法通道,背景必须在精灵透明的地方可见 3) 有许多遮罩:我在每一帧中应用新的遮罩。面具不是长方形的 换句话说,可见像素= 背景像素,如果裁剪遮罩对应的颜色是白色或精灵是透明的; 否则为精灵像素(例如,对应遮罩的像素为黑色) 我正在使用cocos2d iphone。我可以与cocos2d iphone或OpenGL ES 1.1进行这样的
以下是我对OpenGL的回答。对于石英,程序将非常不同。 实际的代码非常简单,但要完全正确地编写代码是一件棘手的事情。我使用的GL上下文是1024X1024,原点在左下角。我不会发布我的代码,因为它使用OpenGL | ES中不可用的即时模式。如果你想要我的绘图代码,请告诉我,我会更新我的答案
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;
}
这显示了我正常绘制的三种纹理(裁剪、出血和背景),然后在下面组合
似乎不起作用:(想象一下雪碧上的黑点:2)我们会得到两种类型的黑色-雪碧上的黑点的黑色和无遮罩区域的黑色。在3)背景将出现在DST_颜色为黑色的所有地方。我的意思是,如果sprite的黑色像素在遮罩内,则应保持黑色,而不是背景。遮罩需要在出血的地方保持白色。步骤2中的混合将“遮罩颜色”值乘以“穿透出血”纹理的值。如果掩码为黑色(0,0,0),则乘法结果为零。所以你的cropping_mask.png在五角大楼内必须是白色的,在五角大楼外必须是透明的。我知道,在第二步之后,我会得到我的精灵,在黑色背景上用蒙版裁剪,是吗?对不起,但是如果精灵有一个黑色像素,蒙版覆盖,那么在2)之后,我会在黑色背景上裁剪精灵,对吗?3)之后,我在黑色像素上到处都有背景,对吗?在那之后,我的精灵的黑色像素变成了彩色。它就是不起作用,我尝试了很多混合方案,但它们似乎都不适合我的情况。问题是glBlend总是结合两种纹理,但我需要三种。还有其他的东西吗?或者任何读过这个问题的人。这是很好的认识到,有一个日常技术可以完全和完全做到这一点,而不使用OpenGL的任何方式。。。