From 4effe027896a64d1db24c46aff96bb5e09b67c8d Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Sun, 11 Feb 2018 22:07:27 -0800 Subject: Enabled iOS build; unified target platform app generation in cmake --- unityplugin/UnityEmulator/CMakeLists.txt | 21 +++- .../include/UnityGraphicsGLCoreES_Emulator.h | 3 + .../src/Android/UnityGraphicsGLESAndroid_Impl.cpp | 14 ++- .../src/Android/UnityGraphicsGLESAndroid_Impl.h | 1 + unityplugin/UnityEmulator/src/IOS/UnityAppIOS.cpp | 77 +++++++++++++ .../src/IOS/UnityGraphicsGLES_IOS_Impl.h | 38 +++++++ .../src/IOS/UnityGraphicsGLES_IOS_Impl.mm | 121 +++++++++++++++++++++ .../src/UnityGraphicsGLCoreES_Emulator.cpp | 9 +- .../UnityEmulator/src/UnityGraphicsGLCore_Impl.h | 1 + .../UnityEmulator/src/UnityGraphicsGL_Impl.h | 2 + 10 files changed, 277 insertions(+), 10 deletions(-) create mode 100644 unityplugin/UnityEmulator/src/IOS/UnityAppIOS.cpp create mode 100644 unityplugin/UnityEmulator/src/IOS/UnityGraphicsGLES_IOS_Impl.h create mode 100644 unityplugin/UnityEmulator/src/IOS/UnityGraphicsGLES_IOS_Impl.mm (limited to 'unityplugin/UnityEmulator') diff --git a/unityplugin/UnityEmulator/CMakeLists.txt b/unityplugin/UnityEmulator/CMakeLists.txt index 4b6eba0..bd6fcc1 100644 --- a/unityplugin/UnityEmulator/CMakeLists.txt +++ b/unityplugin/UnityEmulator/CMakeLists.txt @@ -43,9 +43,16 @@ if(GL_SUPPORTED) list(APPEND INCLUDE src/UnityGraphicsGLCore_Impl.h) endif() -if(GLES_SUPPORTED) - list(APPEND SOURCE src/Android/UnityGraphicsGLESAndroid_Impl.cpp) - list(APPEND INCLUDE src/Android/UnityGraphicsGLESAndroid_Impl.h) +if(GLES_SUPPORTED) + if(PLATFORM_ANDROID) + list(APPEND SOURCE src/Android/UnityGraphicsGLESAndroid_Impl.cpp) + list(APPEND INCLUDE src/Android/UnityGraphicsGLESAndroid_Impl.h) + elseif(PLATFORM_IOS) + list(APPEND SOURCE src/IOS/UnityGraphicsGLES_IOS_Impl.mm) + list(APPEND INCLUDE src/IOS/UnityGraphicsGLES_IOS_Impl.h) + else() + message(FATAL_ERROR Unknown platform) + endif() endif() if(PLATFORM_WIN32) @@ -98,7 +105,13 @@ elseif(PLATFORM_MACOS) ) elseif(PLATFORM_IOS) - + list(APPEND SOURCE + src/IOS/UnityAppIOS.cpp + src/UnityAppBase.cpp + ) + list(APPEND INCLUDE + include/UnityAppBase.h + ) else() message(FATAL_ERROR "Unknown platform") endif() diff --git a/unityplugin/UnityEmulator/include/UnityGraphicsGLCoreES_Emulator.h b/unityplugin/UnityEmulator/include/UnityGraphicsGLCoreES_Emulator.h index fcaf44b..4b14a73 100644 --- a/unityplugin/UnityEmulator/include/UnityGraphicsGLCoreES_Emulator.h +++ b/unityplugin/UnityEmulator/include/UnityGraphicsGLCoreES_Emulator.h @@ -13,6 +13,9 @@ #elif PLATFORM_WIN32 || PLATFORM_UNIVERSAL_WINDOWS || PLATFORM_LINUX || PLATFORM_MACOS class UnityGraphicsGLCore_Impl; using UnityGraphicsGL_Impl = UnityGraphicsGLCore_Impl; +#elif PLATFORM_IOS + class UnityGraphicsGLES_IOS_Impl; + using UnityGraphicsGL_Impl = UnityGraphicsGLES_IOS_Impl; #else # error Unknown Platform #endif diff --git a/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.cpp b/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.cpp index b1a30c4..c3e97df 100644 --- a/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.cpp +++ b/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.cpp @@ -213,6 +213,11 @@ void UnityGraphicsGLESAndroid_Impl::ResizeSwapchain(int new_width, int new_heigh void UnityGraphicsGLESAndroid_Impl::SwapBuffers() { + if(surface_ == EGL_NO_SURFACE) + { + return; + } + bool b = eglSwapBuffers( display_, surface_ ); if( !b ) { @@ -220,7 +225,14 @@ void UnityGraphicsGLESAndroid_Impl::SwapBuffers() if( err == EGL_BAD_SURFACE ) { //Recreate surface - InitEGLSurface(); + try + { + InitEGLSurface(); + } + catch (std::runtime_error &) + { + } + //return EGL_SUCCESS; //Still consider UnityGraphicsGLESAndroid_Impl is valid } else if( err == EGL_CONTEXT_LOST || err == EGL_BAD_CONTEXT ) diff --git a/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.h b/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.h index 9a8251f..1ef33a6 100644 --- a/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.h +++ b/unityplugin/UnityEmulator/src/Android/UnityGraphicsGLESAndroid_Impl.h @@ -54,6 +54,7 @@ public: return 0; } EGLContext GetContext() { return context_; } + GLuint GetDefaultFBO()const{return 0;} bool Invalidate(); diff --git a/unityplugin/UnityEmulator/src/IOS/UnityAppIOS.cpp b/unityplugin/UnityEmulator/src/IOS/UnityAppIOS.cpp new file mode 100644 index 0000000..567e7f6 --- /dev/null +++ b/unityplugin/UnityEmulator/src/IOS/UnityAppIOS.cpp @@ -0,0 +1,77 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "UnityGraphicsEmulator.h" +#include "UnityAppBase.h" +#include "IUnityInterface.h" +#include "Errors.h" + +class UnityAppIOS : public UnityAppBase +{ +public: + UnityAppIOS() + { + m_DeviceType = Diligent::DeviceType::OpenGLES; + } + + virtual void OnGLContextCreated(void *eaglLayer)override final + { + InitGraphics(eaglLayer, 0/*Unused*/, 0/*Unused*/); + InitScene(); + } +}; + +NativeAppBase* CreateApplication() +{ + return new UnityAppIOS(); +} + +// The function must be defined in the plugin +extern void *LoadPluginFunction(const char *name); +void* UnityAppBase::LoadPluginFunction(const char* FunctionName) +{ + return ::LoadPluginFunction(FunctionName); +} + +extern "C" +{ + void __attribute__((visibility("default"))) UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces); + void __attribute__((visibility("default"))) UNITY_INTERFACE_API UnityPluginUnload(); + UnityRenderingEvent __attribute__((visibility("default"))) UNITY_INTERFACE_API GetRenderEventFunc(); +} + +bool UnityAppBase::LoadPlugin() +{ + // Linux automagically sets function pointers + this->UnityPluginLoad = ::UnityPluginLoad; + this->UnityPluginUnload = ::UnityPluginUnload; + this->GetRenderEventFunc = ::GetRenderEventFunc; + return true; +} + +void UnityAppBase::UnloadPlugin() +{ + m_GraphicsEmulator->InvokeDeviceEventCallback(kUnityGfxDeviceEventShutdown); + UnityPluginUnload(); +} + diff --git a/unityplugin/UnityEmulator/src/IOS/UnityGraphicsGLES_IOS_Impl.h b/unityplugin/UnityEmulator/src/IOS/UnityGraphicsGLES_IOS_Impl.h new file mode 100644 index 0000000..a6d885c --- /dev/null +++ b/unityplugin/UnityEmulator/src/IOS/UnityGraphicsGLES_IOS_Impl.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include + +class UnityGraphicsGLES_IOS_Impl +{ +public: + using NativeGLContextType = void*; + + ~UnityGraphicsGLES_IOS_Impl(); + + void InitGLContext(void *eaglLayer, int majorVersion, int minorVersion); + void ResizeSwapchain(int NewWidth, int NewHeight); + + void SwapBuffers(); + + int GetBackBufferWidth()const { return m_BackBufferWidth; } + int GetBackBufferHeight()const { return m_BackBufferHeight; } + GLenum GetBackBufferFormat()const { return GL_RGBA8; } + GLenum GetDepthBufferFormat()const { return GL_DEPTH_COMPONENT32F; } + NativeGLContextType GetContext() { return m_Context; } + GLuint GetDefaultFBO()const{return m_DefaultFBO;} + +private: + void InitRenderBuffers(bool InitFromDrawable); + void ReleaseRenderBuffers(); + + GLint m_BackBufferWidth = 0; + GLint m_BackBufferHeight = 0; + GLuint m_ColorRenderBuffer = 0; + GLuint m_DepthRenderBuffer = 0; + GLuint m_DefaultFBO = 0; + void *m_CALayer; + + NativeGLContextType m_Context; +}; + diff --git a/unityplugin/UnityEmulator/src/IOS/UnityGraphicsGLES_IOS_Impl.mm b/unityplugin/UnityEmulator/src/IOS/UnityGraphicsGLES_IOS_Impl.mm new file mode 100644 index 0000000..e7f9162 --- /dev/null +++ b/unityplugin/UnityEmulator/src/IOS/UnityGraphicsGLES_IOS_Impl.mm @@ -0,0 +1,121 @@ + +#include "UnityGraphicsGLES_IOS_Impl.h" +#include "Errors.h" +#include "DebugUtilities.h" + +#import +#import +#import + + +UnityGraphicsGLES_IOS_Impl::~UnityGraphicsGLES_IOS_Impl() +{ + ReleaseRenderBuffers(); +} + +void UnityGraphicsGLES_IOS_Impl::InitGLContext(void *eaglLayer, int majorVersion, int minorVersion) +{ + m_CALayer = eaglLayer; + + EAGLContext* CurrentCtx = [EAGLContext currentContext]; + m_Context = (__bridge void*)CurrentCtx; + + if (m_Context == nullptr) + { + LOG_ERROR_AND_THROW("No current GL context found!"); + } + + //Checking GL version + const GLubyte *GLVersionString = glGetString( GL_VERSION ); + const GLubyte *GLRenderer = glGetString(GL_RENDERER); + + GLint MajorVersion = 0, MinorVersion = 0; + //Or better yet, use the GL3 way to get the version number + glGetIntegerv( GL_MAJOR_VERSION, &MajorVersion ); + glGetIntegerv( GL_MINOR_VERSION, &MinorVersion ); + LOG_INFO_MESSAGE("Attached to OpenGLES ", MajorVersion, '.', MinorVersion, " context (", GLVersionString, ", ", GLRenderer, ')'); + + InitRenderBuffers(true); +} + +void UnityGraphicsGLES_IOS_Impl::ReleaseRenderBuffers() +{ + if(m_DefaultFBO != 0) + { + glDeleteFramebuffers(1, &m_DefaultFBO); + m_DefaultFBO = 0; + } + + if(m_ColorRenderBuffer != 0) + { + glDeleteRenderbuffers(1, &m_ColorRenderBuffer); + m_ColorRenderBuffer = 0; + } + + if(m_DepthRenderBuffer != 0) + { + glDeleteRenderbuffers(1, &m_DepthRenderBuffer); + m_DepthRenderBuffer = 0; + } +} + +void UnityGraphicsGLES_IOS_Impl::InitRenderBuffers(bool InitFromDrawable) +{ + ReleaseRenderBuffers(); + + EAGLContext* context = [EAGLContext currentContext]; + + glGenFramebuffers(1, &m_DefaultFBO); + VERIFY(glGetError() == GL_NO_ERROR, "Failed to generate default framebuffer"); + glBindFramebuffer(GL_FRAMEBUFFER, m_DefaultFBO); + + glGenRenderbuffers(1, &m_ColorRenderBuffer); + VERIFY(glGetError() == GL_NO_ERROR, "Failed to generate color renderbuffer"); + glBindRenderbuffer(GL_RENDERBUFFER, m_ColorRenderBuffer); + + if(InitFromDrawable) + { + // This call associates the storage for the current render buffer with the + // EAGLDrawable (our CAEAGLLayer) allowing us to draw into a buffer that + // will later be rendered to the screen wherever the layer is (which + // corresponds with our view). + id drawable = (__bridge id)m_CALayer; + [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:drawable]; + } + else + { + CAEAGLLayer* layer = (__bridge CAEAGLLayer*)m_CALayer; + [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer]; + } + + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_ColorRenderBuffer); + + // Get the drawable buffer's width and height so we can create a depth buffer for the FBO + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &m_BackBufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &m_BackBufferHeight); + + // Create a depth buffer to use with our drawable FBO + glGenRenderbuffers(1, &m_DepthRenderBuffer); + glBindRenderbuffer(GL_RENDERBUFFER, m_DepthRenderBuffer); + VERIFY(glGetError() == GL_NO_ERROR, "Failed to generate depth renderbuffer"); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, m_BackBufferWidth, m_BackBufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_DepthRenderBuffer); + + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + { + LOG_ERROR_AND_THROW("Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + } +} + +void UnityGraphicsGLES_IOS_Impl::ResizeSwapchain(int NewWidth, int NewHeight) +{ + InitRenderBuffers(false); +} + +void UnityGraphicsGLES_IOS_Impl::SwapBuffers() +{ + EAGLContext* context = [EAGLContext currentContext]; + glBindRenderbuffer(GL_RENDERBUFFER, m_ColorRenderBuffer); + [context presentRenderbuffer:GL_RENDERBUFFER]; +} + diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsGLCoreES_Emulator.cpp b/unityplugin/UnityEmulator/src/UnityGraphicsGLCoreES_Emulator.cpp index a8b0290..9e8757c 100644 --- a/unityplugin/UnityEmulator/src/UnityGraphicsGLCoreES_Emulator.cpp +++ b/unityplugin/UnityEmulator/src/UnityGraphicsGLCoreES_Emulator.cpp @@ -20,8 +20,7 @@ void UnityGraphicsGLCoreES_Emulator::InitGLContext(void *pNativeWndHandle, #if PLATFORM_LINUX void *pDisplay, #endif - -int MajorVersion, int MinorVersion) + int MajorVersion, int MinorVersion) { m_GraphicsImpl->InitGLContext(pNativeWndHandle, #if PLATFORM_LINUX @@ -80,8 +79,8 @@ UnityGfxRenderer UnityGraphicsGLCoreES_Emulator::GetUnityGfxRenderer() void UnityGraphicsGLCoreES_Emulator::BeginFrame() { - glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); - glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 ); + glBindFramebuffer( GL_DRAW_FRAMEBUFFER, m_GraphicsImpl->GetDefaultFBO() ); + glBindFramebuffer( GL_READ_FRAMEBUFFER, m_GraphicsImpl->GetDefaultFBO() ); glClearDepthf( UsesReverseZ() ? 0.f : 1.f ); static const float ClearColor[4] = { 0, 0, 0.5f, 1 }; glClearColor(ClearColor[0], ClearColor[1], ClearColor[2], ClearColor[3]); @@ -99,4 +98,4 @@ void UnityGraphicsGLCoreES_Emulator::EndFrame() { } -#endif // OPENGL_SUPPORTED \ No newline at end of file +#endif // OPENGL_SUPPORTED diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.h b/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.h index 5abc97e..f6d42ea 100644 --- a/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.h +++ b/unityplugin/UnityEmulator/src/UnityGraphicsGLCore_Impl.h @@ -91,6 +91,7 @@ public: GLenum GetBackBufferFormat()const { return GL_RGBA8; } GLenum GetDepthBufferFormat()const { return GL_DEPTH_COMPONENT32F; } NativeGLContextType GetContext() { return m_Context; } + GLuint GetDefaultFBO()const{return 0;} private: int m_BackBufferWidth = 0; diff --git a/unityplugin/UnityEmulator/src/UnityGraphicsGL_Impl.h b/unityplugin/UnityEmulator/src/UnityGraphicsGL_Impl.h index b87e2a2..46c2c46 100644 --- a/unityplugin/UnityEmulator/src/UnityGraphicsGL_Impl.h +++ b/unityplugin/UnityEmulator/src/UnityGraphicsGL_Impl.h @@ -6,6 +6,8 @@ # include "Android/UnityGraphicsGLESAndroid_Impl.h" #elif PLATFORM_WIN32 || PLATFORM_UNIVERSAL_WINDOWS || PLATFORM_LINUX || PLATFORM_MACOS # include "UnityGraphicsGLCore_Impl.h" +#elif PLATFORM_IOS +# include "IOS/UnityGraphicsGLES_IOS_Impl.h" #else # error Unknown Platform #endif -- cgit v1.2.3