코코아로 알파로 PNG를로드하는 방법은 무엇입니까?
-
10-07-2019 - |
문제
iPhone OpenGL 애플리케이션을 개발하고 있으며 투명성이있는 텍스처를 사용해야합니다. 이미지를 PNG로 저장했습니다. 이미 PNG를 OpenGL 텍스처로로드하여 렌더링하는 모든 코드가 있습니다. 이것은 투명성이없는 모든 이미지에 대해 잘 작동합니다 (모든 알파 값은 1.0). 그러나 이제 투명성 (알파 값이 다양 해짐)을 가진 일부 PNG를로드하고 사용하려고 했으므로 데이터가 잘못로드 된 것처럼 내 텍스처가 엉망이됩니다.
나는 이것이 코코아 API의 일부를 사용하는 로딩 코드 때문이라고 확신합니다. 그래도 여기에 관련 코드를 게시하겠습니다.
OSX/iPhone에서 PNG 또는 투명성을 지원하는 이미지 형식을로드하는 가장 좋은 방법은 무엇입니까? 이 방법은 원형 교차로를 느낍니다. CGContext로 렌더링하고 데이터를 얻는 것이 이상해 보입니다.
*로드 *
CGImageRef CGImageRef_load(const char *filename) {
NSString *path = [NSString stringWithFormat:@"%@/%s",
[[NSBundle mainBundle] resourcePath],
filename];
UIImage *img = [UIImage imageWithContentsOfFile:path];
if(img) return [img CGImage];
return NULL;
}
unsigned char* CGImageRef_data(CGImageRef image) {
NSInteger width = CGImageGetWidth(image);
NSInteger height = CGImageGetHeight(image);
unsigned char *data = (unsigned char*)malloc(width*height*4);
CGContextRef context = CGBitmapContextCreate(data,
width, height,
8, width * 4,
CGImageGetColorSpace(image),
kCGImageAlphaPremultipliedLast);
CGContextDrawImage(context,
CGRectMake(0.0, 0.0, (float)width, (float)height),
image);
CGContextRelease(context);
return data;
}
* 업로드 *
(define (image-opengl-upload data width height)
(let ((tex (alloc-opengl-image)))
(glBindTexture GL_TEXTURE_2D tex)
(glTexEnvi GL_TEXTURE_ENV GL_TEXTURE_ENV_MODE GL_DECAL)
(glTexImage2D GL_TEXTURE_2D
0
GL_RGBA
width
height
0
GL_RGBA
GL_UNSIGNED_BYTE
(->void-array data))
(glTexParameteri GL_TEXTURE_2D
GL_TEXTURE_MIN_FILTER
GL_LINEAR)
(glTexParameteri GL_TEXTURE_2D
GL_TEXTURE_MAG_FILTER
GL_LINEAR)
(glTexParameteri GL_TEXTURE_2D
GL_TEXTURE_WRAP_S
GL_CLAMP_TO_EDGE)
(glTexParameteri GL_TEXTURE_2D
GL_TEXTURE_WRAP_T
GL_CLAMP_TO_EDGE)
(glBindTexture GL_TEXTURE_2D 0)
tex))
해결책
핵심 그래픽 표면은 렌더링하기 전에 모든 제로에 지워야하므로 Malloc 대신 Calloc을 사용하거나 Malloc 이후에 밈을 추가하는 것이 좋습니다.
또한 Texenv가 gl_decal. 기본값으로 설정하고 싶을 수도 있습니다 (gl_modulate).
PNG 이미지를 디코딩하기위한 핵심 그래픽을 피하려면 대신 PVR 파일로로드하는 것이 좋습니다. PVR은 매우 간단한 파일 형식입니다. 호출 된 앱 pvrtextool 상상력 SDK에 포함되어 PNG에서 PVR로 쉽게 변환 할 수 있습니다. SDK에는 파일 형식을 구문 분석하는 방법을 보여주는 샘플 코드도 포함되어 있습니다.
다른 팁
명시 적으로…
핵심 이미지를 사용하여 텍스처를로드하는 데있어 가장 일반적인 문제는 데이터를 소형화 된 알파 형식으로 변환해야한다는 것입니다. 번들에 포함 된 PNG의 경우 실제로 빌드 프로세스의 전처리 단계에서 수행됩니다. 이것을 고려하지 않으면 혼합 된 물체 주위에 어두운 밴딩이 발생합니다.
그것을 고려하는 방법은 사용하는 것입니다. glBlendMode(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
대신에 glBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
. 일반 블렌딩 이외의 알파 채널을 사용하려면 유일한 옵션은 다른 형식과 로더로 전환하는 것입니다 (PrideOut이 제안한 것처럼 다른 이유로).
ETA : Mac OS X에도 적절한 문제가 존재하지만 전처리는 iPhone에 따라 다릅니다.
나는 OpenGL에 대해 아무것도 모르지만 Cocoa는 NSIMAGE/UIIMAGE 로이 기능을 추상화합니다.
PVR을 사용할 수 있지만 약간의 압축 아티팩트가 있으므로 3D 객체 텍스처에 대해서만 권장하거나 PVR이 제공 할 수없는 특정 수준의 세부 사항이 필요하지 않은 텍스처 만 권장합니다.