Open johngirvin opened 8 years ago
Are you using examples/common/entry code for iOS?
Not sure what you mean, but I'm using something like:
SDL_Window *window = SDL_CreateWindow(...);
bgfx::sdlSetWindow(window);
bgfx::init();
There's no #if BX_PLATFORM_IOS
branch in sdlSetWindow to set up g_platformData.nwh
FWIW I get a similar error running on a Metal capable device at renderer_mtl.mm:356
Instead:
bgfx::sdlSetWindow(window);
Try something like this (GLES2):
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
SDL_GetWindowWMInfo(_window, &wmi);
bgfx::PlatformData pd;
pd.ndt = NULL;
pd.nwh = wmi.info.uikit.window.rootViewController.view.layer;
pd.context = NULL;
pd.backBuffer = NULL;
pd.backBufferDS = NULL;
bgfx::setPlatformData(pd);
It's similar to this code path in entry: https://github.com/bkaradzic/bgfx/blob/master/examples/common/entry/entry_ios.mm#L201
I haven't tested this at all, just going off 2.0.4 docs...
For Metal, you would also need to pass "device" into pd.context
that's create like this:
https://github.com/bkaradzic/bgfx/blob/master/examples/common/entry/entry_ios.mm#L180
@johngirvin Any luck with this?
I tried the above with the addition of:
pd.nwh = (__bridge void *) wmi.info.uikit.window.rootViewController.view.layer;
You need to init the SDL Renderer first otherwise layer contains a standard CALayer.
It gets a little further, but in glcontext_eagl.mm the following returns NO which leads to nothing being rendered:
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];
I've confirmed layer isa CAEAGLLayer and context isa EAGLContext at this point.
bgfx.cpp (2350): BGFX Init... bgfx.cpp (1136): BGFX Creating rendering thread. bgfx_p.h (2099): BGFX render thread start bgfx.cpp (1145): BGFX Running in multi-threaded mode glcontext_eagl.mm (56): BGFX Screen size: 0 x 0 glcontext_eagl.mm (67): BGFX CHECK glCheckFramebufferStatus failed 0x00008cd6
0x00008cd6 is GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
Any progress on this issue? I'm willing to help if there's something I can try. Bgfx is awesome as it is, but with SDL support on all platforms it would be even better.
Yeah, help about this would be appreciated.
Ok, I've got a hacked version working. After SDL_CreateWindow I do this:
SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
SDL_SysWMinfo wmi;
SDL_VERSION(&wmi.version);
SDL_GetWindowWMInfo(window, &wmi);
CALayer* layer = wmi.info.uikit.window.rootViewController.view.layer;
bgfx::PlatformData pd;
pd.ndt = NULL;
pd.nwh = (__bridge void *)layer;
pd.context = NULL;
pd.backBuffer = NULL;
pd.backBufferDS = NULL;
bgfx::setPlatformData(pd);
It seems that the problem is that the render buffers etc gets generated two times once by SDL and once by BGFX, so this disables it in SDL: SDL_uikitopenglview.mm at line 124:
/* Set the appropriate scale (for retina display support) */
self.contentScaleFactor = scale;
return self;
Any ideas how to do this properly?
You can pass context and backbuffers to bgfx via platform data here:
pd.context = <whatever SDL created>;
pd.backBuffer = <whatever SDL created>;
pd.backBufferDS = <whatever SDL created>;
I'm not really sure where to get the info from SDL. But still from what I see bgfx will still try to create context and render buffers by itself.
On desktop, SDL doesn't create context unless you add SDL_INIT_VIDEO
here:
https://github.com/bkaradzic/bgfx/blob/master/examples/common/entry/entry_sdl.cpp#L398
It's the same on iOS, but because I have to call SDL_CreateRenderer, to get the context and backbuffer etc, bgfx IMHO shouldn't re-initialize opengl, but just use the stuff from PlatformData.
So if you don't pass any context to bgfx it should create context, but if you do it should skip it. I was just looking glcontext_eagl.mm and it doesn't handle case when context is passed properly. You can add handling for data passed, follow example here: https://github.com/bkaradzic/bgfx/blob/master/src/glcontext_egl.cpp#L159
Don't create a SDL renderer, it creates an OpenGL ES context of an implementation-dependent version. If you really want to create an OpenGL ES context using SDL, use SDL_GL_CreateContext.
Here's an example of using Metal with SDL on iOS: https://gist.github.com/slime73/12284a8299be857d2581
I started to look on this one (duh, after years in game industry I'm a bit way too lazy to write all entry points myself again every time I decide to prototype a new engine).
So the thing is, at least from looking on sources of SDL 2.0.5 - when one create a SDL window one don't get EAGL enabled UIView. So if one does pd.nwh = wmi.info.uikit.window.rootViewController.view.layer;
without asking SDL to create opengl renderer then everything fails here :
layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys
: [NSNumber numberWithBool:false]
, kEAGLDrawablePropertyRetainedBacking
, kEAGLColorFormatRGBA8
, kEAGLDrawablePropertyColorFormat
, nil
];
Because layer is CALayer
and not CAEAGLLayer
duh. And CALayer
doesn't have drawableProperties
, @bkaradzic consider adding an assert there just to check that layer have a correct class type or at least have drawableProperties
property.
This can/should be fixed in SDL itself by adding + (Class)layerClass {return [CAEAGLLayer class];}
somewhere in SDL_uikitview.m, but for now I guess we can just create a separate UIView instance just for bgfx ...
TBH: I'll probably will give up on SDL for iOS here, because it doesn't really looks like it can deliver proper quality for production ready game - aka how the heck do you plan to integrate ads, gamecenter, etc with it? :/
SDL_GL_CreateContext creates an EAGLLayer-backed UIView and attaches it to the window's view as a subview.
@slime73 yes, and SDL_GL_CreateContext
also creates EAGLContext
and framebuffers, while what we want here is for SDL to create just a UIWindow + UIView and let bgfx create and own EAGLContext
with all buffers.
how the heck do you plan to integrate ads, gamecenter, etc with it? :/
SDL doesn't provide APIs for those itself (that's way outside the scope of the library), but it doesn't stop you from having them.
SDL_GL_CreateContext also creates EAGLContext and framebuffers, while what we want here is for SDL to create just a UIWindow + UIView and let bgfx create and own EAGLContext with all buffers.
From what I understand based on what @bkaradzic wrote, BGFX supports both cases of the platform API (i.e. SDL) creating its own context and backbuffers, and the case where it doesn't. SDL lets you do either as well, by calling or not calling SDL_GL_CreateContext. If BGFX doesn't properly handle the platform layer not creating an EAGLLayer when a platform backbuffer isn't wanted, that sounds like something that should be fixed in BGFX's code.
You can manually add a CAEAGLLayer to a UIView by creating one and calling addSublayer
on the SDL UIView's base CALayer, in BGFX's code (not modifying SDL at all).
I was able to get SDL to work with BGFX, but none of the above worked for me. The overall outline of the solution I used is:
Example code:
#include <video/uikit/SDL_uikitview.h>
#include <SDL_syswm.h>
@interface SDL_openglview : SDL_uikitview
@end
@implementation SDL_openglview
+ (Class)layerClass
{
return [CAEAGLLayer class];
}
@end
SDL_SysWMinfo wmi;
SDL_GetWindowWMInfo(window, &wmi);
SDL_openglview* view = [[SDL_openglview alloc] initWithFrame: CGRectMake(0,0,0,0) ];
// This function will automatically remove the default view created by SDL and
// and attach our newly created view
[view setSDLWindow: window];
float scale = 1.0f;
#ifdef __IPHONE_8_0
if ([ [UIScreen mainScreen] respondsToSelector:@selector(nativeScale)]) {
scale = [UIScreen mainScreen].nativeScale;
} else
#endif
{
scale = [UIScreen mainScreen].scale;
}
[view setContentScaleFactor: scale];
Is this currently being looked into? I'm finding myself unsure whether to use BGFX due to this apparent instability on iOS.
I'm finding myself unsure whether to use BGFX due to this apparent instability on iOS.
This is SDL related issue on iOS, not bgfx iOS issue (there are games that ship on iOS with bgfx). I'm not looking at it. Someone who is using SDL on iOS should submit PR with fix.
I don't think this is a SDL source code issue at all - you just have to (in your code that uses BGFX) create a CAEAGLLayer or a CAEAGLLayer-backed view, and attach it to the SDL window's main UIView obtained via SDL_GetWindowWMInfo
.
This is because SDL doesn't create an OpenGL surface on iOS unless you use SDL_GL_CreateContext, but it still provides you with enough tools to create an OpenGL surface yourself if you don't use CreateContext.
My Metal example in one of my previous replies to this thread does the same thing (sans BGFX API calls), but with Metal instead of OpenGL ES.
SDL 2.0.4 has been released with official support for iOS. However, attempting to use BGFX with SDL on iOS results in an exception in glcontext_eagl.mm at
layer.opaque = true;
Initially it looks like the SDL platform data isn't initialised for iOS but it's not clear to me what needs to be done.