我在Iphone中写了一个2D游戏,它使用纹理作为精灵,我在渲染的一些图像周围出现了有色噪声(但这种噪音从未出现在纹理上本身,只在它周围的透明部分出现)。其余的纹理不会发生问题。这是我用来加载纹理的代码:
- (void)loadTexture:(NSString*)nombre {
CGImageRef textureImage = [UIImage imageNamed:nombre].CGImage;
if (textureImage == nil) {
NSLog(@"Failed to load texture image");
return;
}
textureWidth = NextPowerOfTwo(CGImageGetWidth(textureImage));
textureHeight = NextPowerOfTwo(CGImageGetHeight(textureImage));
imageSizeX= CGImageGetWidth(textureImage);
imageSizeY= CGImageGetHeight(textureImage);
GLubyte *textureData = (GLubyte *)malloc(textureWidth * textureHeight * 4);
CGContextRef textureContext = CGBitmapContextCreate(textureData, textureWidth,textureHeight,8, textureWidth * 4,CGImageGetColorSpace(textureImage),kCGImageAlphaPremultipliedLast);
CGContextDrawImage(textureContext, CGRectMake(0.0, 0.0, (float)textureWidth, (float)textureHeight), textureImage);
CGContextRelease(textureContext);
glGenTextures(1, &textures[0]);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
free(textureData);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
答案 0 :(得分:4)
在您将图像绘制到其中之前,您的记忆不会被清零。您看到的有趣像素是图像透明区域中的旧数据。使用calloc
代替malloc
(calloc
返回归零内存)。
您还可以在绘制图像之前使用CGContextSetBlendMode(textureContext, kCGBlendModeCopy);
。
如果您想了解整个故事:
此问题仅适用于小图像,因为malloc对于小分配大小具有不同的代码路径。它从用户空间中管理的池中返回一个小块。如果请求的大小大于某个阈值(16K,我相信),malloc从内核获取内存。新页面当然已归零。
我花了一段时间才弄明白。