首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >透明OpenGL CAEAGLLayer

透明OpenGL CAEAGLLayer
EN

Stack Overflow用户
提问于 2012-10-18 18:47:21
回答 2查看 2.4K关注 0票数 1

我正在尝试渲染一个透明的opengl视图(CAEAGLLayer),这样我就可以在它后面放置一个UIView。我使用以下设置来实现透明的opengl背景。

代码语言:javascript
复制
CAEAGLLayer* layer = (CAEAGLLayer*)eaglLayer;
layer.opaque = NO;
layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
                            kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
                            nil
                            ];

我的问题是现在我的opengl场景中的对象现在是透明的,我可以透过它们看到它们(大约50%的透明度)。

如何使opengl场景的背景透明,而场景中的对象仍然不透明。

请注意,所有层、UIViews和UIWindows的Alpha值均为1.0,并且场景中的片段着色器不会导致该问题,因为当layer.opaque设定为YES时,所有内容都是纯色。我还应该补充说,这是一个unity项目,如果它有任何帮助的话。

编辑:

一些代码是从单位设置的。

代码语言:javascript
复制
int OpenEAGL_UnityCallback(UIWindow** window, int* screenWidth, int* screenHeight,  int* openglesVersion)
{
    CGRect rect = [[UIScreen mainScreen] bounds];

    // Create a full-screen window
    _window = [[UIWindow alloc] initWithFrame:rect];
    EAGLView* view = [[EAGLView alloc] initWithFrame:rect];
    UnityViewController *controller = [[UnityViewController alloc] init];
    sGLViewController = controller;

#if defined(__IPHONE_3_0)
    if( _ios30orNewer )
        controller.wantsFullScreenLayout = TRUE;
#endif

    controller.view = view;

    CreateSplashView( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ? (UIView*)_window : (UIView*)view );
    CreateActivityIndicator(_splashView);

    // add only now so controller have chance to reorient *all* added views
    [_window addSubview:view];
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
        [_window bringSubviewToFront:_splashView];

    if( !UnityUseOSAutorotation() )
    {
        _autorotEnableHandling = true;
        [[NSNotificationCenter defaultCenter] postNotificationName: UIDeviceOrientationDidChangeNotification object: [UIDevice currentDevice]];
    }

    // reposition activity indicator after we rotated views
    if (_activityIndicator)
        _activityIndicator.center = CGPointMake([_splashView bounds].size.width/2, [_splashView bounds].size.height/2);

    int openglesApi =
#if defined(__IPHONE_3_0) && USE_OPENGLES20_IF_AVAILABLE
    kEAGLRenderingAPIOpenGLES2;
#else
    kEAGLRenderingAPIOpenGLES1;
#endif

    for (; openglesApi >= kEAGLRenderingAPIOpenGLES1 && !_context; --openglesApi)
    {
        if (!UnityIsRenderingAPISupported(openglesApi))
            continue;

        _context = [[EAGLContext alloc] initWithAPI:openglesApi];
    }

    if (!_context)
        return false;

    if (![EAGLContext setCurrentContext:_context]) {
        _context = 0;
        return false;
    }

    const GLuint colorFormat = UnityUse32bitDisplayBuffer() ? GL_RGBA8_OES : GL_RGB565_OES;

    if (!CreateWindowSurface(view, colorFormat, GL_DEPTH_COMPONENT16_OES, UnityGetDesiredMSAASampleCount(MSAA_DEFAULT_SAMPLE_COUNT), NO, &_surface)) {
        return false;
    }

    glViewport(0, 0, _surface.w, _surface.h);
    [_window makeKeyAndVisible];
    [view release];

    *window = _window;
    *screenWidth = _surface.w;
    *screenHeight = _surface.h;
    *openglesVersion = _context.API;

    _glesContextCreated = true;

    return true;
}

void PresentSurface(EAGLSurfaceDesc* surface)
{
    if(_skipPresent)
    {
        UNITY_DBG_LOG ("SKIP PresentSurface:\n");
        return;
    }
    UNITY_DBG_LOG ("PresentSurface:\n");

    EAGLContext *oldContext = [EAGLContext currentContext];
    if (oldContext != _context)
        [EAGLContext setCurrentContext:_context];

    PreparePresentSurfaceGLES(surface);

    // presentRenderbuffer presents currently bound RB, so make sure we have the correct one bound
    GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer) );
    if(![_context presentRenderbuffer:GL_RENDERBUFFER_OES])
        printf_console("failed to present renderbuffer (%s:%i)\n", __FILE__, __LINE__ );

    AfterPresentSurfaceGLES(surface);

    if(oldContext != _context)
        [EAGLContext setCurrentContext:oldContext];
}


bool CreateSurface(EAGLView *view, EAGLSurfaceDesc* surface)
{
    CAEAGLLayer* eaglLayer = (CAEAGLLayer*)surface->eaglLayer;
    assert(eaglLayer == [view layer]);

    CGSize newSize = [eaglLayer bounds].size;
    newSize.width  = roundf(newSize.width);
    newSize.height = roundf(newSize.height);

#ifdef __IPHONE_4_0
    int resolution = UnityGetTargetResolution();

    if (    (resolution == kTargetResolutionNative || resolution == kTargetResolutionHD)
         && [view respondsToSelector:@selector(setContentScaleFactor:)]
         && [[UIScreen mainScreen] respondsToSelector:@selector(scale)]
       )
    {
            CGFloat scaleFactor = [UIScreen mainScreen].scale;
            [view setContentScaleFactor:scaleFactor];
            newSize.width = roundf(newSize.width * scaleFactor);
            newSize.height = roundf(newSize.height * scaleFactor);
            UnitySetInputScaleFactor(scaleFactor);
    }
#endif

    surface->w = newSize.width;
    surface->h = newSize.height;

    UNITY_DBG_LOG ("CreateWindowSurface: FBO\n");
    CreateSurfaceGLES(surface);
    GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer) );

    return true;
}

extern "C" bool AllocateRenderBufferStorageFromEAGLLayer(void* eaglLayer)
{
    return [_context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)eaglLayer];
}

extern "C" void InitEAGLLayer(void* eaglLayer, bool use32bitColor)
{
    CAEAGLLayer* layer = (CAEAGLLayer*)eaglLayer;

    const NSString* colorFormat = use32bitColor ? kEAGLColorFormatRGBA8 : kEAGLColorFormatRGB565;

    layer.opaque = NO;
    layer.drawableProperties =  [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
                                    colorFormat, kEAGLDrawablePropertyColorFormat,
                                    nil
                                ];
}
EN

回答 2

Stack Overflow用户

发布于 2012-10-18 18:52:14

使用alpha < 1清除帧缓冲区,即

代码语言:javascript
复制
glClearColor(r, g, b, alpha); // where alpha < 1
glClear(GL_COLOR_BUFFER_BIT | … );

对于完全透明,您需要alpha = 0。

票数 0
EN

Stack Overflow用户

发布于 2012-10-18 21:15:42

好的,问题似乎出在psd的问题上。Unity可以让你加载psd的纹理。他们制造了一个奇怪的透明度问题。我把它们换成了jpegs,这个问题就解决了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12952896

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档