我有一个带有UV贴图的OpenGL纹理。我已经阅读过使用alpha通道存储一些其他值,这样可以节省从某处加载额外地图的费用。例如,您可以在alpha中存储镜面反射信息(光泽)或发射贴图,因为您只需要浮点数并且不使用alpha。
所以我试了一下。编写着色器不是问题。我完成了所有这一部分。问题是只需要将所有4个通道输入到纹理中。
我有所有的地图所以在PSD中我将基本地图放在rgb中,排放地图放在a中。但是当你保存为png时,alpha不会保存(如果你把它添加为新的通道),或者它通过将透明度预乘到rgb来破坏rgb(如果你将地图作为掩码应用)。
显然PNG文件本身支持透明但不支持Alpha通道。所以似乎没有办法控制所有4个频道。
但我已经读过这样做了。那么我可以将哪种格式保存在PSD中,我可以用iPhone中的图像加载器加载它?
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:type];
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
UIImage *image = [[UIImage alloc] initWithData:texData];
此方法是否接受其他文件格式?像TIFF那样可以控制所有4个频道吗?
我可以使用texturetool制作PVR ..但是从文档看来它也是一个PNG作为输入。
编辑:
首先要清楚这是在iPhone中。
这可能是psd的错。就像我说的,有两种方法可以在我的psd版本(cc 14.2 mac)中设置文档,我可以找到它。一种是手动添加新频道并将地图粘贴到那里。它显示为红色叠加层。第二个是添加一个蒙版,选项单击它并将alpha粘贴在那里。在这种情况下,它显示它与alpa作为透明度与棋盘格在alpha零区域。当我保存为png时,alpha选项会变灰。
当我将png重新加载到psd时,它似乎是预乘的。我无法在photoshop中找回我的完整rgb数据。
我是否可以使用不同的工具将两张地图合并为一个png,将其存储为png-32?
TIFF不起作用,因为它也不存储alpha。也许我在考虑TGA。
我在装载机中也注意到了这一点......
GLuint width = CGImageGetWidth(image.CGImage);
GLuint height = CGImageGetHeight(image.CGImage);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
void *imageData = malloc( height * width * 4 );
CGContextRef thisContext = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
if (flipImage)
{
CGContextTranslateCTM (thisContext, 0, height);
CGContextScaleCTM (thisContext, 1.0, -1.0);
}
CGColorSpaceRelease( colorSpace );
CGContextClearRect( thisContext, CGRectMake( 0, 0, width, height ) );
CGContextDrawImage( thisContext, CGRectMake( 0, 0, width, height ), image.CGImage );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
glBindTexture(GL_TEXTURE_2D, textureInfo[texIndex].texture);
当我创建该上下文时,该选项为kCGImageAlphaPremultipliedLast
。
也许我确实需要尝试glkit加载器,但似乎我的png是预乘的。
答案 0 :(得分:0)
可以创建带有Alpha通道的PNG,但是如果没有预乘,您将无法使用内置的iOS API读取该PNG图像。核心问题是CoreGraphics仅出于性能原因支持预乘alpha。您还必须小心禁用Xcode对附加到项目文件的PNG的优化,因为它在编译时进行预乘。您可以做的是在关闭Xcode PNG处理后在您自己的libpng副本中编译和链接,然后直接使用C级别的libpng读取文件。但是,说实话,这是浪费时间。只需使用RGB值保存一个图像,将另一个图像保存为灰度,其中alpha值为0-255灰度值。您可以将这些灰度值表示为您想要的任何内容,并且您不必担心将事情弄得一团糟。你的opengl代码只需要从多个纹理中读取,这不是什么大问题。