void AfterPresentSurfaceGLES(EAGLSurfaceDesc* surface) { if(surface->use32bitColor != UnityUse32bitDisplayBuffer()) { surface->use32bitColor = UnityUse32bitDisplayBuffer(); CreateSurfaceGLES(surface); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer) ); } #if GL_APPLE_framebuffer_multisample if (_supportsMSAA) { const int desiredMSAASamples = UnityGetDesiredMSAASampleCount(MSAA_DEFAULT_SAMPLE_COUNT); if (surface->msaaSamples != desiredMSAASamples) { surface->msaaSamples = desiredMSAASamples; CreateSurfaceMultisampleBuffersGLES(surface); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer) ); } if (surface->msaaSamples > 1) { UNITY_DBG_LOG (" glBindFramebufferOES (GL_FRAMEBUFFER_OES, %i); // PresentSurface\n", surface->msaaFramebuffer); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->msaaFramebuffer) ); gDefaultFBO = surface->msaaFramebuffer; } } #endif }
void DestroySurfaceMultisampleBuffersGLES(EAGLSurfaceDesc* surface) { if(surface->depthbuffer) { GLES_CHK( glDeleteRenderbuffersOES(1, &surface->depthbuffer) ); } surface->depthbuffer = 0; if(surface->msaaDepthbuffer) { GLES_CHK( glDeleteRenderbuffersOES(1, &surface->msaaDepthbuffer) ); } surface->msaaDepthbuffer = 0; if(surface->msaaRenderbuffer) { GLES_CHK( glDeleteRenderbuffersOES(1, &surface->msaaRenderbuffer) ); } surface->msaaRenderbuffer = 0; if (surface->msaaFramebuffer) { GLES_CHK( glDeleteFramebuffersOES(1, &surface->msaaFramebuffer) ); } surface->msaaFramebuffer = 0; }
void DestroySurfaceGLES(EAGLSurfaceDesc* surface) { if( surface->systemRenderbuffer ) { GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->systemRenderbuffer) ); DeallocateRenderBufferStorageFromEAGLLayer(); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0) ); GLES_CHK( glDeleteRenderbuffersOES(1, &surface->systemRenderbuffer) ); surface->systemRenderbuffer = 0; } if( surface->systemFramebuffer ) { GLES_CHK( glDeleteFramebuffersOES(1, &surface->systemFramebuffer) ); surface->systemFramebuffer = 0; } DestroyRenderingSurfaceGLES(surface); if(surface->depthbuffer) { GLES_CHK( glDeleteRenderbuffersOES(1, &surface->depthbuffer) ); surface->depthbuffer = 0; } }
void DestroyRenderingSurfaceGLES(EAGLSurfaceDesc* surface) { if( (surface->msaaFramebuffer || surface->targetFramebuffer) && surface->depthbuffer ) { GLES_CHK( glDeleteRenderbuffersOES(1, &surface->depthbuffer) ); surface->depthbuffer = 0; } if(surface->targetRT) { GLES_CHK( glDeleteTextures(1, &surface->targetRT) ); surface->targetRT = 0; } if(surface->targetFramebuffer) { GLES_CHK( glDeleteFramebuffersOES(1, &surface->targetFramebuffer) ); surface->targetFramebuffer = 0; } if(surface->msaaRenderbuffer) { GLES_CHK( glDeleteRenderbuffersOES(1, &surface->msaaRenderbuffer) ); surface->msaaRenderbuffer = 0; } if(surface->msaaFramebuffer) { GLES_CHK( glDeleteFramebuffersOES(1, &surface->msaaFramebuffer) ); surface->msaaFramebuffer = 0; } }
void CreateSurfaceGLES(EAGLSurfaceDesc* surface) { GLuint oldRenderbuffer; GLES_CHK( glGetIntegerv(GL_RENDERBUFFER_BINDING_OES, (GLint *) &oldRenderbuffer) ); DestroySurfaceGLES(surface); InitEAGLLayer(surface->eaglLayer, surface->use32bitColor); GLES_CHK( glGenRenderbuffersOES(1, &surface->renderbuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer) ); if( !AllocateRenderBufferStorageFromEAGLLayer(surface->eaglLayer) ) { GLES_CHK( glDeleteRenderbuffersOES(1, &surface->renderbuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_BINDING_OES, oldRenderbuffer) ); printf_console("FAILED allocating render buffer storage from gles context\n"); return; } GLES_CHK( glGenFramebuffersOES(1, &surface->framebuffer) ); UNITY_DBG_LOG ("glBindFramebufferOES(GL_FRAMEBUFFER_OES, %d) :: AppCtrl\n", surface->framebuffer); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->framebuffer) ); gDefaultFBO = surface->framebuffer; UNITY_DBG_LOG ("glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, %d) :: AppCtrl\n", surface->renderbuffer); GLES_CHK( glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, surface->renderbuffer) ); CreateSurfaceMultisampleBuffersGLES(surface); }
void DestroySurfaceGLES(EAGLSurfaceDesc* surface) { if( surface->renderbuffer ) { GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer) ); DeallocateRenderBufferStorageFromEAGLLayer(); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, 0) ); GLES_CHK( glDeleteRenderbuffersOES(1, &surface->renderbuffer) ); surface->renderbuffer = 0; } if( surface->framebuffer ) { GLES_CHK( glDeleteFramebuffersOES(1, &surface->framebuffer) ); surface->framebuffer = 0; } DestroySurfaceMultisampleBuffersGLES(surface); }
void AfterPresentSurfaceGLES(EAGLSurfaceDesc* surface) { if(surface->use32bitColor != UnityUse32bitDisplayBuffer()) { surface->use32bitColor = UnityUse32bitDisplayBuffer(); CreateSurfaceGLES(surface); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->systemRenderbuffer) ); } if(NeedRecreateRenderingSurfaceGLES(surface)) { UnityGetRenderingResolution(&surface->targetW, &surface->targetH); surface->msaaSamples = UnityGetDesiredMSAASampleCount(MSAA_DEFAULT_SAMPLE_COUNT); CreateRenderingSurfaceGLES(surface); } }
extern "C" bool UnityResolveMSAA(GLuint destFBO, GLuint colorTex, GLuint colorBuf, GLuint depthTex, GLuint depthBuf) { #if GL_APPLE_framebuffer_multisample if (_surface.msaaSamples > 0 && _supportsMSAA && destFBO!=_surface.msaaFramebuffer && destFBO!=_surface.framebuffer) { Profiler_StartMSAAResolve(); GLint oldFBO; GLES_CHK( glGetIntegerv (GL_FRAMEBUFFER_BINDING_OES, &oldFBO) ); UNITY_DBG_LOG ("UnityResolveMSAA: samples=%i msaaFBO=%i destFBO=%i colorTex=%i colorRB=%i depthTex=%i depthRB=%i\n", _surface.msaaSamples, _surface.msaaFramebuffer, destFBO, colorTex, colorBuf, depthTex, depthBuf); UNITY_DBG_LOG (" bind dest as DRAW FBO and textures/buffers into it\n"); GLES_CHK( glBindFramebufferOES (GL_DRAW_FRAMEBUFFER_APPLE, destFBO) ); if (colorTex) GLES_CHK( glFramebufferTexture2DOES( GL_DRAW_FRAMEBUFFER_APPLE, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0 ) ); else if (colorBuf) GLES_CHK( glFramebufferRenderbufferOES (GL_DRAW_FRAMEBUFFER_APPLE, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuf) ); if (depthTex) GLES_CHK( glFramebufferTexture2DOES( GL_DRAW_FRAMEBUFFER_APPLE, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0 ) ); else if (depthBuf) GLES_CHK( glFramebufferRenderbufferOES (GL_DRAW_FRAMEBUFFER_APPLE, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuf) ); UNITY_DBG_LOG (" bind msaa as READ FBO\n"); GLES_CHK( glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, _surface.msaaFramebuffer) ); UNITY_DBG_LOG (" glResolveMultisampleFramebufferAPPLE ();\n"); GLES_CHK( glResolveMultisampleFramebufferAPPLE() ); GLES_CHK( glBindFramebufferOES (GL_FRAMEBUFFER_OES, oldFBO) ); Profiler_EndMSAAResolve(); return true; } #endif return false; }
void PreparePresentSurfaceGLES(EAGLSurfaceDesc* surface) { #if GL_APPLE_framebuffer_multisample if( surface->msaaSamples > 0 && _supportsMSAA ) { Profiler_StartMSAAResolve(); UNITY_DBG_LOG (" ResolveMSAA: samples=%i msaaFBO=%i destFBO=%i\n", surface->msaaSamples, surface->msaaFramebuffer, surface->framebuffer); GLES_CHK( glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, surface->msaaFramebuffer) ); GLES_CHK( glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, surface->framebuffer) ); GLES_CHK( glResolveMultisampleFramebufferAPPLE() ); Profiler_EndMSAAResolve(); } #endif // update screenshot here if( UnityIsCaptureScreenshotRequested() ) { GLint curfb = 0; GLES_CHK( glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curfb) ); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->framebuffer) ); UnityCaptureScreenshot(); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, curfb) ); } #if GL_EXT_discard_framebuffer if( _supportsDiscard ) { GLenum attachments[3]; int discardCount = 0; if (surface->msaaSamples > 1 && _supportsMSAA) attachments[discardCount++] = GL_COLOR_ATTACHMENT0_OES; if (surface->depthFormat) attachments[discardCount++] = GL_DEPTH_ATTACHMENT_OES; attachments[discardCount++] = GL_STENCIL_ATTACHMENT_OES; GLenum target = (surface->msaaSamples > 1 && _supportsMSAA) ? GL_READ_FRAMEBUFFER_APPLE: GL_FRAMEBUFFER_OES; if (discardCount > 0) { GLES_CHK( glDiscardFramebufferEXT(target, discardCount, attachments) ); } } #endif }
void CreateSurfaceMultisampleBuffersGLES(EAGLSurfaceDesc* surface) { UNITY_DBG_LOG ("CreateSurfaceMultisampleBuffers: samples=%i\n", surface->msaaSamples); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer) ); UNITY_DBG_LOG ("glBindFramebufferOES(GL_FRAMEBUFFER_OES, %d) :: AppCtrl\n", surface->framebuffer); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->framebuffer) ); gDefaultFBO = surface->framebuffer; DestroySurfaceMultisampleBuffersGLES(surface); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->renderbuffer) ); UNITY_DBG_LOG ("glBindFramebufferOES(GL_FRAMEBUFFER_OES, %d) :: AppCtrl\n", surface->framebuffer); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->framebuffer) ); #if GL_APPLE_framebuffer_multisample if(surface->msaaSamples > 1) { GLES_CHK( glGenRenderbuffersOES(1, &surface->msaaRenderbuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->msaaRenderbuffer) ); GLES_CHK( glGenFramebuffersOES(1, &surface->msaaFramebuffer) ); UNITY_DBG_LOG ("glBindFramebufferOES(GL_FRAMEBUFFER_OES, %d) :: AppCtrl\n", surface->msaaFramebuffer); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->msaaFramebuffer) ); gDefaultFBO = surface->msaaFramebuffer; GLES_CHK( glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, surface->msaaSamples, surface->format, surface->w, surface->h) ); GLES_CHK( glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, surface->msaaRenderbuffer) ); if(surface->depthFormat) { GLES_CHK( glGenRenderbuffersOES(1, &surface->msaaDepthbuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->msaaDepthbuffer) ); GLES_CHK( glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, surface->msaaSamples, GL_DEPTH_COMPONENT16_OES, surface->w, surface->h) ); GLES_CHK( glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, surface->msaaDepthbuffer) ); } } else #endif { if(surface->depthFormat) { GLES_CHK( glGenRenderbuffersOES(1, &surface->depthbuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->depthbuffer) ); GLES_CHK( glRenderbufferStorageOES(GL_RENDERBUFFER_OES, surface->depthFormat, surface->w, surface->h) ); UNITY_DBG_LOG ("glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, %d) :: AppCtrl\n", surface->depthbuffer); GLES_CHK( glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, surface->depthbuffer) ); } } }
void PreparePresentSurfaceGLES(EAGLSurfaceDesc* surface) { #if GL_APPLE_framebuffer_multisample if( surface->msaaSamples > 1 && _supportsMSAA ) { Profiler_StartMSAAResolve(); GLuint drawFB = surface->targetFramebuffer ? surface->targetFramebuffer : surface->systemFramebuffer; GLES_CHK( glBindFramebufferOES(GL_READ_FRAMEBUFFER_APPLE, surface->msaaFramebuffer) ); GLES_CHK( glBindFramebufferOES(GL_DRAW_FRAMEBUFFER_APPLE, drawFB) ); GLES_CHK( glResolveMultisampleFramebufferAPPLE() ); Profiler_EndMSAAResolve(); } #endif // update screenshot from target FBO to get requested resolution if( UnityIsCaptureScreenshotRequested() ) { GLint target = surface->targetFramebuffer ? surface->targetFramebuffer : surface->systemFramebuffer; GLint curfb = 0; GLES_CHK( glGetIntegerv(GL_FRAMEBUFFER_BINDING, &curfb) ); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, target) ); UnityCaptureScreenshot(); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, curfb) ); } if( surface->targetFramebuffer ) { gDefaultFBO = surface->systemFramebuffer; GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, gDefaultFBO) ); UnityBlitToSystemFB(surface->targetRT, surface->targetW, surface->targetH, surface->systemW, surface->systemH); gDefaultFBO = surface->msaaFramebuffer ? surface->msaaFramebuffer : surface->targetFramebuffer; GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, gDefaultFBO) ); } #if GL_EXT_discard_framebuffer if( _supportsDiscard ) { GLenum discardAttach[] = {GL_COLOR_ATTACHMENT0_OES, GL_DEPTH_ATTACHMENT_OES, GL_STENCIL_ATTACHMENT_OES}; if( surface->msaaFramebuffer ) GLES_CHK( glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 3, discardAttach) ); if(surface->targetFramebuffer) { GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->targetFramebuffer) ); GLES_CHK( glDiscardFramebufferEXT(GL_FRAMEBUFFER_OES, 3, discardAttach) ); } GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->systemFramebuffer) ); GLES_CHK( glDiscardFramebufferEXT(GL_FRAMEBUFFER_OES, 2, &discardAttach[1]) ); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, gDefaultFBO) ); } #endif }
void CreateRenderingSurfaceGLES(EAGLSurfaceDesc* surface) { gDefaultFBO = surface->systemFramebuffer; GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->systemFramebuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->systemRenderbuffer) ); DestroyRenderingSurfaceGLES(surface); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->systemFramebuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->systemRenderbuffer) ); if( surface->targetW != surface->systemW || surface->targetH != surface->systemH ) { GLES_CHK( glGenTextures(1, &surface->targetRT) ); GLES_CHK( glBindTexture(GL_TEXTURE_2D, surface->targetRT) ); GLES_CHK( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GLES_UPSCALE_FILTER) ); GLES_CHK( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GLES_UPSCALE_FILTER) ); GLES_CHK( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) ); GLES_CHK( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ); GLenum fmt = surface->use32bitColor ? GL_RGBA : GL_RGB; GLenum type = surface->use32bitColor ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5; GLES_CHK( glTexImage2D(GL_TEXTURE_2D, 0, fmt, surface->targetW, surface->targetH, 0, fmt, type, 0) ); GLES_CHK( glGenFramebuffersOES(1, &surface->targetFramebuffer) ); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->targetFramebuffer) ); GLES_CHK( glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, surface->targetRT, 0) ); GLES_CHK( glBindTexture(GL_TEXTURE_2D, 0) ); gDefaultFBO = surface->targetFramebuffer; } #if GL_APPLE_framebuffer_multisample if(_supportsMSAA && surface->msaaSamples > 1) { GLES_CHK( glGenRenderbuffersOES(1, &surface->msaaRenderbuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->msaaRenderbuffer) ); GLES_CHK( glGenFramebuffersOES(1, &surface->msaaFramebuffer) ); GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, surface->msaaFramebuffer) ); GLES_CHK( glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, surface->msaaSamples, surface->format, surface->targetW, surface->targetH) ); GLES_CHK( glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, surface->msaaRenderbuffer) ); gDefaultFBO = surface->msaaFramebuffer; } #endif GLES_CHK( glBindFramebufferOES(GL_FRAMEBUFFER_OES, gDefaultFBO) ); if(surface->depthFormat != 0) { GLES_CHK( glGenRenderbuffersOES(1, &surface->depthbuffer) ); GLES_CHK( glBindRenderbufferOES(GL_RENDERBUFFER_OES, surface->depthbuffer) ); bool needMSAA = GL_APPLE_framebuffer_multisample && (surface->msaaSamples > 1); #if GL_APPLE_framebuffer_multisample if(needMSAA) GLES_CHK( glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER_OES, surface->msaaSamples, surface->depthFormat, surface->targetW, surface->targetH) ); #endif if(!needMSAA) GLES_CHK( glRenderbufferStorageOES(GL_RENDERBUFFER_OES, surface->depthFormat, surface->targetW, surface->targetH) ); GLES_CHK( glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, surface->depthbuffer) ); } }