문제

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이 제공 할 수없는 특정 수준의 세부 사항이 필요하지 않은 텍스처 만 권장합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top