mirror of https://github.com/bkaradzic/bgfx
Merge pull request #716 from pacemakermusic/master
iOS SwapChain support
This commit is contained in:
commit
c6d31f28a2
|
@ -15,7 +15,11 @@ namespace bgfx { namespace gl
|
|||
struct GlContext
|
||||
{
|
||||
GlContext()
|
||||
: m_context(0)
|
||||
: m_current(0)
|
||||
, m_context(0)
|
||||
, m_fbo(0)
|
||||
, m_colorRbo(0)
|
||||
, m_depthStencilRbo(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -41,7 +45,7 @@ namespace bgfx { namespace gl
|
|||
return 0 != m_context;
|
||||
}
|
||||
|
||||
void* m_view;
|
||||
SwapChainGL* m_current;
|
||||
void* m_context;
|
||||
|
||||
GLuint m_fbo;
|
||||
|
|
|
@ -17,6 +17,142 @@ namespace bgfx { namespace gl
|
|||
|
||||
static void* s_opengles = NULL;
|
||||
|
||||
struct SwapChainGL
|
||||
{
|
||||
SwapChainGL(EAGLContext *_context, CAEAGLLayer *_layer)
|
||||
: m_context(_context)
|
||||
, m_fbo(0)
|
||||
, m_colorRbo(0)
|
||||
, m_depthStencilRbo(0)
|
||||
{
|
||||
_layer.contentsScale = [UIScreen mainScreen].scale;
|
||||
|
||||
_layer.opaque = true;
|
||||
|
||||
_layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys
|
||||
: [NSNumber numberWithBool:false]
|
||||
, kEAGLDrawablePropertyRetainedBacking
|
||||
, kEAGLColorFormatRGBA8
|
||||
, kEAGLDrawablePropertyColorFormat
|
||||
, nil
|
||||
];
|
||||
|
||||
|
||||
[EAGLContext setCurrentContext:_context];
|
||||
|
||||
GL_CHECK(glGenFramebuffers(1, &m_fbo) );
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) );
|
||||
|
||||
GL_CHECK(glGenRenderbuffers(1, &m_colorRbo) );
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) );
|
||||
|
||||
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_layer];
|
||||
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorRbo) );
|
||||
|
||||
GLint width;
|
||||
GLint height;
|
||||
GL_CHECK(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width) );
|
||||
GL_CHECK(glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height) );
|
||||
BX_TRACE("Screen size: %d x %d", width, height);
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
m_layer = _layer;
|
||||
|
||||
createFrameBuffers(m_width, m_height);
|
||||
}
|
||||
|
||||
~SwapChainGL()
|
||||
{
|
||||
destroyFrameBuffers();
|
||||
}
|
||||
|
||||
void destroyFrameBuffers()
|
||||
{
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) );
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0) );
|
||||
if (0 != m_fbo)
|
||||
{
|
||||
GL_CHECK(glDeleteFramebuffers(1, &m_fbo) );
|
||||
m_fbo = 0;
|
||||
}
|
||||
|
||||
if (0 != m_colorRbo)
|
||||
{
|
||||
GL_CHECK(glDeleteRenderbuffers(1, &m_colorRbo) );
|
||||
m_colorRbo = 0;
|
||||
}
|
||||
|
||||
if (0 != m_depthStencilRbo)
|
||||
{
|
||||
GL_CHECK(glDeleteRenderbuffers(1, &m_depthStencilRbo) );
|
||||
m_depthStencilRbo = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void createFrameBuffers(GLint _width, GLint _height)
|
||||
{
|
||||
GL_CHECK(glGenRenderbuffers(1, &m_depthStencilRbo) );
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_depthStencilRbo) );
|
||||
GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, _width, _height) ); // from OES_packed_depth_stencil
|
||||
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRbo) );
|
||||
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRbo) );
|
||||
|
||||
BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_FRAMEBUFFER)
|
||||
, "glCheckFramebufferStatus failed 0x%08x"
|
||||
, glCheckFramebufferStatus(GL_FRAMEBUFFER)
|
||||
);
|
||||
|
||||
makeCurrent();
|
||||
GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) );
|
||||
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) );
|
||||
swapBuffers();
|
||||
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) );
|
||||
swapBuffers();
|
||||
}
|
||||
|
||||
void makeCurrent()
|
||||
{
|
||||
[EAGLContext setCurrentContext:m_context];
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) );
|
||||
|
||||
GLint newWidth = m_layer.bounds.size.width*[UIScreen mainScreen].scale;
|
||||
GLint newHeight = m_layer.bounds.size.height*[UIScreen mainScreen].scale;
|
||||
resize(newWidth, newHeight);
|
||||
}
|
||||
|
||||
void resize(GLint _width, GLint _height)
|
||||
{
|
||||
if(m_width == _width && m_height == _height)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
destroyFrameBuffers();
|
||||
|
||||
m_width = _width;
|
||||
m_height = _height;
|
||||
|
||||
createFrameBuffers(m_width, m_height);
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
{
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) );
|
||||
[m_context presentRenderbuffer:GL_RENDERBUFFER];
|
||||
}
|
||||
|
||||
EAGLContext* m_context;
|
||||
|
||||
CAEAGLLayer *m_layer;
|
||||
GLuint m_fbo;
|
||||
GLuint m_colorRbo;
|
||||
GLuint m_depthStencilRbo;
|
||||
GLint m_width;
|
||||
GLint m_height;
|
||||
};
|
||||
|
||||
void GlContext::create(uint32_t _width, uint32_t _height)
|
||||
{
|
||||
s_opengles = bx::dlopen("/System/Library/Frameworks/OpenGLES.framework/OpenGLES");
|
||||
|
@ -65,6 +201,13 @@ namespace bgfx { namespace gl
|
|||
, glCheckFramebufferStatus(GL_FRAMEBUFFER)
|
||||
);
|
||||
|
||||
makeCurrent();
|
||||
GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 0.0f) );
|
||||
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) );
|
||||
swap(NULL);
|
||||
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT) );
|
||||
swap(NULL);
|
||||
|
||||
import();
|
||||
|
||||
g_internalData.context = m_context;
|
||||
|
@ -148,30 +291,51 @@ namespace bgfx { namespace gl
|
|||
|
||||
uint64_t GlContext::getCaps() const
|
||||
{
|
||||
return 0;
|
||||
return BGFX_CAPS_SWAP_CHAIN;
|
||||
}
|
||||
|
||||
SwapChainGL* GlContext::createSwapChain(void* /*_nwh*/)
|
||||
SwapChainGL* GlContext::createSwapChain(void* _nwh)
|
||||
{
|
||||
BX_CHECK(false, "Shouldn't be called!");
|
||||
return NULL;
|
||||
return BX_NEW(g_allocator, SwapChainGL)(/*m_display, m_config,*/ (EAGLContext*)m_context, (CAEAGLLayer*)_nwh);
|
||||
}
|
||||
|
||||
void GlContext::destroySwapChain(SwapChainGL* /*_swapChain*/)
|
||||
void GlContext::destroySwapChain(SwapChainGL* _swapChain)
|
||||
{
|
||||
BX_CHECK(false, "Shouldn't be called!");
|
||||
BX_DELETE(g_allocator, _swapChain);
|
||||
}
|
||||
|
||||
void GlContext::swap(SwapChainGL* _swapChain)
|
||||
{
|
||||
BX_CHECK(NULL == _swapChain, "Shouldn't be called!"); BX_UNUSED(_swapChain);
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) );
|
||||
EAGLContext* context = (EAGLContext*)m_context;
|
||||
[context presentRenderbuffer:GL_RENDERBUFFER];
|
||||
makeCurrent(_swapChain);
|
||||
|
||||
if (NULL == _swapChain)
|
||||
{
|
||||
GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, m_colorRbo) );
|
||||
EAGLContext* context = (EAGLContext*)m_context;
|
||||
[context presentRenderbuffer:GL_RENDERBUFFER];
|
||||
}
|
||||
else
|
||||
{
|
||||
_swapChain->swapBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
void GlContext::makeCurrent(SwapChainGL* /*_swapChain*/)
|
||||
void GlContext::makeCurrent(SwapChainGL* _swapChain)
|
||||
{
|
||||
if (m_current != _swapChain)
|
||||
{
|
||||
m_current = _swapChain;
|
||||
|
||||
if (NULL == _swapChain)
|
||||
{
|
||||
[EAGLContext setCurrentContext:(EAGLContext*)m_context];
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo) );
|
||||
}
|
||||
else
|
||||
{
|
||||
_swapChain->makeCurrent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlContext::import()
|
||||
|
|
|
@ -2562,16 +2562,7 @@ namespace bgfx { namespace gl
|
|||
{
|
||||
FrameBufferGL& frameBuffer = m_frameBuffers[_fbh.idx];
|
||||
_height = frameBuffer.m_height;
|
||||
if (UINT16_MAX != frameBuffer.m_denseIdx)
|
||||
{
|
||||
m_glctx.makeCurrent(frameBuffer.m_swapChain);
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_glctx.makeCurrent(NULL);
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer.m_fbo[0]) );
|
||||
}
|
||||
m_glctx.makeCurrent(frameBuffer.m_swapChain);
|
||||
}
|
||||
|
||||
m_fbh = _fbh;
|
||||
|
|
Loading…
Reference in New Issue