diff --git a/lib/irrlicht/CMakeLists.txt b/lib/irrlicht/CMakeLists.txt index ac3e0d49c..8fe03e683 100644 --- a/lib/irrlicht/CMakeLists.txt +++ b/lib/irrlicht/CMakeLists.txt @@ -67,6 +67,7 @@ source/Irrlicht/CAttributes.cpp source/Irrlicht/CBillboardSceneNode.cpp source/Irrlicht/CBoneSceneNode.cpp source/Irrlicht/CCameraSceneNode.cpp +source/Irrlicht/CContextEGL.cpp source/Irrlicht/CColorConverter.cpp source/Irrlicht/CCubeSceneNode.cpp source/Irrlicht/CDefaultGUIElementFactory.cpp @@ -199,6 +200,7 @@ source/Irrlicht/CBillboardSceneNode.h source/Irrlicht/CBlit.h source/Irrlicht/CBoneSceneNode.h source/Irrlicht/CCameraSceneNode.h +source/Irrlicht/CContextEGL.h source/Irrlicht/CColorConverter.h source/Irrlicht/CCubeSceneNode.h source/Irrlicht/CDefaultGUIElementFactory.h diff --git a/lib/irrlicht/include/IrrCompileConfig.h b/lib/irrlicht/include/IrrCompileConfig.h index 1c5c02985..30fc5695e 100644 --- a/lib/irrlicht/include/IrrCompileConfig.h +++ b/lib/irrlicht/include/IrrCompileConfig.h @@ -117,6 +117,10 @@ #define _IRR_COMPILE_ANDROID_ASSET_READER_ #endif +#if defined(_IRR_COMPILE_WITH_OGLES2_) && !defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) +#define _IRR_COMPILE_WITH_EGL_ +#endif + #if !defined(_IRR_WINDOWS_API_) && !defined(_IRR_OSX_PLATFORM_) && !defined(_IRR_ANDROID_PLATFORM_) #ifndef _IRR_SOLARIS_PLATFORM_ #define _IRR_LINUX_PLATFORM_ diff --git a/lib/irrlicht/source/Irrlicht/CContextEGL.cpp b/lib/irrlicht/source/Irrlicht/CContextEGL.cpp new file mode 100644 index 000000000..fd68b92e3 --- /dev/null +++ b/lib/irrlicht/source/Irrlicht/CContextEGL.cpp @@ -0,0 +1,571 @@ +// Copyright (C) 2013 Patryk Nadrowski +// Copyright (C) 2016-2017 Dawid Gan +// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt +// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0 +// driver implemented by Amundis. +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#include "IrrCompileConfig.h" + +#if defined(_IRR_COMPILE_WITH_EGL_) + +#include +#include +#include +#include + +#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_ +#include +#endif + +#include "CContextEGL.h" +#include "os.h" + +using namespace irr; + +ContextManagerEGL::ContextManagerEGL() +{ + m_egl_window = 0; + m_egl_display = EGL_NO_DISPLAY; + m_egl_surface = EGL_NO_SURFACE; + m_egl_context = EGL_NO_CONTEXT; + m_egl_config = 0; + m_egl_version = 0; + m_is_legacy_device = false; + m_initialized = false; + + memset(&m_creation_params, 0, sizeof(ContextEGLParams)); +} + + +ContextManagerEGL::~ContextManagerEGL() +{ + close(); +} + + +bool ContextManagerEGL::init(const ContextEGLParams& params) +{ + if (m_initialized) + return false; + + m_creation_params = params; + m_egl_window = m_creation_params.window; + + bool success = initDisplay(); + + if (!success) + { + os::Printer::log("Error: Could not initialize EGL display.\n"); + close(); + return false; + } + + bool has_minimum_requirements = false; + + if (m_creation_params.opengl_api == CEGL_API_OPENGL) + { + if (hasEGLExtension("EGL_KHR_create_context") || m_egl_version >= 150) + { + has_minimum_requirements = true; + eglBindAPI(EGL_OPENGL_API); + } + } + else if (m_creation_params.opengl_api == CEGL_API_OPENGL_ES) + { + if (m_egl_version >= 130) + { + has_minimum_requirements = true; + eglBindAPI(EGL_OPENGL_ES_API); + } + } + + if (!has_minimum_requirements) + { + os::Printer::log("Error: EGL version is too old.\n"); + close(); + return false; + } + + success = chooseConfig(); + + if (!success) + { + os::Printer::log("Error: Couldn't get EGL config.\n"); + close(); + return false; + } + + success = createSurface(); + + if (!success) + { + os::Printer::log("Error: Couldn't create EGL surface.\n"); + close(); + return false; + } + + success = createContext(); + + if (!success) + { + os::Printer::log("Error: Couldn't create OpenGL context.\n"); + close(); + return false; + } + + success = eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, + m_egl_context); + + if (!success) + { + checkEGLError(); + os::Printer::log("Error: Couldn't make context current for EGL display.\n"); + close(); + return false; + } + + eglSwapInterval(m_egl_display, m_creation_params.vsync_enabled ? 1 : 0); + + m_initialized = true; + return true; +} + + +bool ContextManagerEGL::initDisplay() +{ + EGLNativeDisplayType display = m_creation_params.display; + +#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_ + display = EGL_DEFAULT_DISPLAY; +#endif + + if (display != EGL_DEFAULT_DISPLAY) + { + m_egl_display = eglGetDisplay(display); + } + + if (m_egl_display == EGL_NO_DISPLAY) + { + m_egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + } + + if (m_egl_display == EGL_NO_DISPLAY) + { + return false; + } + + int egl_version_major = 0; + int egl_version_minor = 0; + + bool success = eglInitialize(m_egl_display, &egl_version_major, + &egl_version_minor); + + if (success) + { + m_egl_version = 100 * egl_version_major + 10 * egl_version_minor; + } + + return success; +} + + +bool ContextManagerEGL::chooseConfig() +{ + std::vector config_attribs; + config_attribs.push_back(EGL_RED_SIZE); + config_attribs.push_back(8); + config_attribs.push_back(EGL_GREEN_SIZE); + config_attribs.push_back(8); + config_attribs.push_back(EGL_BLUE_SIZE); + config_attribs.push_back(8); + config_attribs.push_back(EGL_ALPHA_SIZE); + config_attribs.push_back(m_creation_params.with_alpha_channel ? 8 : 0); + // config_attribs.push_back(EGL_BUFFER_SIZE); + // config_attribs.push_back(24); + config_attribs.push_back(EGL_DEPTH_SIZE); + config_attribs.push_back(16); + // config_attribs.push_back(EGL_STENCIL_SIZE); + // config_attribs.push_back(stencil_buffer); + // config_attribs.push_back(EGL_SAMPLE_BUFFERS); + // config_attribs.push_back(antialias ? 1 : 0); + // config_attribs.push_back(EGL_SAMPLES); + // config_attribs.push_back(antialias); + + if (m_creation_params.opengl_api == CEGL_API_OPENGL) + { + config_attribs.push_back(EGL_RENDERABLE_TYPE); + config_attribs.push_back(EGL_OPENGL_BIT); + } + else if (m_creation_params.opengl_api == CEGL_API_OPENGL_ES) + { + config_attribs.push_back(EGL_RENDERABLE_TYPE); + config_attribs.push_back(EGL_OPENGL_ES2_BIT); + } + + if (m_creation_params.surface_type == CEGL_SURFACE_WINDOW) + { + config_attribs.push_back(EGL_SURFACE_TYPE); + config_attribs.push_back(EGL_WINDOW_BIT); + } + else if (m_creation_params.surface_type == CEGL_SURFACE_PBUFFER) + { + config_attribs.push_back(EGL_SURFACE_TYPE); + config_attribs.push_back(EGL_PBUFFER_BIT); + } + + config_attribs.push_back(EGL_NONE); + config_attribs.push_back(0); + + EGLint num_configs = 0; + + bool success = eglChooseConfig(m_egl_display, &config_attribs[0], + &m_egl_config, 1, &num_configs); + + if (!success || num_configs == 0) + { + return false; + } + +#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_ + EGLint format = 0; + eglGetConfigAttrib(m_egl_display, m_egl_config, EGL_NATIVE_VISUAL_ID, + &format); + ANativeWindow_setBuffersGeometry(m_egl_window, 0, 0, format); +#endif + + return true; +} + + +bool ContextManagerEGL::createSurface() +{ + if (m_creation_params.surface_type == CEGL_SURFACE_WINDOW) + { + if (m_egl_surface == EGL_NO_SURFACE) + { + m_egl_surface = eglCreateWindowSurface(m_egl_display, m_egl_config, + m_egl_window, NULL); + } + + if (m_egl_surface == EGL_NO_SURFACE) + { + m_egl_surface = eglCreateWindowSurface(m_egl_display, m_egl_config, + 0, NULL); + } + } + else if (m_creation_params.surface_type == CEGL_SURFACE_PBUFFER) + { + if (m_egl_surface == EGL_NO_SURFACE) + { + std::vector pbuffer_attribs; + pbuffer_attribs.push_back(EGL_WIDTH); + pbuffer_attribs.push_back(m_creation_params.pbuffer_width); + pbuffer_attribs.push_back(EGL_HEIGHT); + pbuffer_attribs.push_back(m_creation_params.pbuffer_height); + pbuffer_attribs.push_back(EGL_NONE); + pbuffer_attribs.push_back(0); + + m_egl_surface = eglCreatePbufferSurface(m_egl_display, + m_egl_config, + &pbuffer_attribs[0]); + } + + if (m_egl_surface == EGL_NO_SURFACE) + { + std::vector pbuffer_attribs; + pbuffer_attribs.push_back(EGL_WIDTH); + pbuffer_attribs.push_back(m_creation_params.pbuffer_width); + pbuffer_attribs.push_back(EGL_HEIGHT); + pbuffer_attribs.push_back(m_creation_params.pbuffer_height); + pbuffer_attribs.push_back(EGL_LARGEST_PBUFFER); + pbuffer_attribs.push_back(EGL_TRUE); + pbuffer_attribs.push_back(EGL_NONE); + pbuffer_attribs.push_back(0); + + m_egl_surface = eglCreatePbufferSurface(m_egl_display, + m_egl_config, + &pbuffer_attribs[0]); + } + } + + return m_egl_surface != EGL_NO_SURFACE; +} + + +bool ContextManagerEGL::createContext() +{ + m_is_legacy_device = false; + + if (m_creation_params.opengl_api == CEGL_API_OPENGL_ES) + { + if (!m_creation_params.force_legacy_device) + { + if (m_egl_context == EGL_NO_CONTEXT) + { + std::vector context_attribs; + context_attribs.push_back(EGL_CONTEXT_CLIENT_VERSION); + context_attribs.push_back(3); + context_attribs.push_back(EGL_NONE); + context_attribs.push_back(0); + + m_egl_context = eglCreateContext(m_egl_display, + m_egl_config, + EGL_NO_CONTEXT, + &context_attribs[0]); + } + } + + if (m_egl_context == EGL_NO_CONTEXT) + { + m_is_legacy_device = true; + + std::vector context_attribs; + context_attribs.push_back(EGL_CONTEXT_CLIENT_VERSION); + context_attribs.push_back(2); + context_attribs.push_back(EGL_NONE); + context_attribs.push_back(0); + + m_egl_context = eglCreateContext(m_egl_display, + m_egl_config, + EGL_NO_CONTEXT, + &context_attribs[0]); + } + } + else if (m_creation_params.opengl_api == CEGL_API_OPENGL) + { + if (!m_creation_params.force_legacy_device) + { + if (m_egl_context == EGL_NO_CONTEXT) + { + std::vector context_attribs; + context_attribs.push_back(EGL_CONTEXT_MAJOR_VERSION); + context_attribs.push_back(4); + context_attribs.push_back(EGL_CONTEXT_MINOR_VERSION); + context_attribs.push_back(3); + context_attribs.push_back(EGL_NONE); + context_attribs.push_back(0); + + m_egl_context = eglCreateContext(m_egl_display, + m_egl_config, + EGL_NO_CONTEXT, + &context_attribs[0]); + } + + if (m_egl_context == EGL_NO_CONTEXT) + { + std::vector context_attribs; + context_attribs.push_back(EGL_CONTEXT_MAJOR_VERSION); + context_attribs.push_back(3); + context_attribs.push_back(EGL_CONTEXT_MINOR_VERSION); + context_attribs.push_back(3); + context_attribs.push_back(EGL_NONE); + context_attribs.push_back(0); + + m_egl_context = eglCreateContext(m_egl_display, + m_egl_config, + EGL_NO_CONTEXT, + &context_attribs[0]); + } + + if (m_egl_context == EGL_NO_CONTEXT) + { + std::vector context_attribs; + context_attribs.push_back(EGL_CONTEXT_MAJOR_VERSION); + context_attribs.push_back(3); + context_attribs.push_back(EGL_CONTEXT_MINOR_VERSION); + context_attribs.push_back(1); + context_attribs.push_back(EGL_NONE); + context_attribs.push_back(0); + + m_egl_context = eglCreateContext(m_egl_display, + m_egl_config, + EGL_NO_CONTEXT, + &context_attribs[0]); + } + } + + if (m_egl_context == EGL_NO_CONTEXT) + { + m_is_legacy_device = true; + + std::vector context_attribs; + context_attribs.push_back(EGL_CONTEXT_MAJOR_VERSION); + context_attribs.push_back(2); + context_attribs.push_back(EGL_CONTEXT_MINOR_VERSION); + context_attribs.push_back(1); + context_attribs.push_back(EGL_NONE); + context_attribs.push_back(0); + + m_egl_context = eglCreateContext(m_egl_display, + m_egl_config, + EGL_NO_CONTEXT, + &context_attribs[0]); + } + } + + return m_egl_context != EGL_NO_CONTEXT; +} + + +void ContextManagerEGL::close() +{ + eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + if (m_egl_context != EGL_NO_CONTEXT) + { + eglDestroyContext(m_egl_display, m_egl_context); + m_egl_context = EGL_NO_CONTEXT; + } + + if (m_egl_surface != EGL_NO_SURFACE) + { + eglDestroySurface(m_egl_display, m_egl_surface); + m_egl_surface = EGL_NO_SURFACE; + } + + if (m_egl_display != EGL_NO_DISPLAY) + { + eglTerminate(m_egl_display); + m_egl_display = EGL_NO_DISPLAY; + } +} + + +bool ContextManagerEGL::swapBuffers() +{ + bool success = eglSwapBuffers(m_egl_display, m_egl_surface); + +#ifdef DEBUG + if (!success) + { + eglGetError(); + } +#endif + + return success; +} + + +void ContextManagerEGL::reloadEGLSurface(void* window) +{ +#ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_ + m_egl_window = (ANativeWindow*)window; + + if (!m_egl_window) + { + os::Printer::log("Error: Invalid EGL window.\n"); + } +#endif + + eglMakeCurrent(m_egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + + eglDestroySurface(m_egl_display, m_egl_surface); + m_egl_surface = EGL_NO_SURFACE; + + bool success = createSurface(); + + if (!success) + { + os::Printer::log("Error: Could not create EGL surface."); + } + + success = eglMakeCurrent(m_egl_display, m_egl_surface, m_egl_surface, + m_egl_context); + + if (!success) + { + checkEGLError(); + os::Printer::log("Error: Couldn't make context current for EGL display.\n"); + } +} + + +bool ContextManagerEGL::getSurfaceDimensions(int* width, int* height) +{ + if (!eglQuerySurface(m_egl_display, m_egl_surface, EGL_WIDTH, width)) + return false; + + if (!eglQuerySurface(m_egl_display, m_egl_surface, EGL_HEIGHT, height)) + return false; + + return true; +} + + +bool ContextManagerEGL::hasEGLExtension(const char* extension) +{ + const char* extensions = eglQueryString(m_egl_display, EGL_EXTENSIONS); + + if (extensions && strstr(extensions, extension) != NULL) + { + return true; + } + + return false; +} + + +bool ContextManagerEGL::checkEGLError() +{ + bool result = true; + + switch (eglGetError()) + { + case EGL_SUCCESS: + result = false; + break; + case EGL_NOT_INITIALIZED: + os::Printer::log("Error: EGL_NOT_INITIALIZED\n"); + break; + case EGL_BAD_ACCESS: + os::Printer::log("Error: EGL_BAD_ACCESS\n"); + break; + case EGL_BAD_ALLOC: + os::Printer::log("Error: EGL_BAD_ALLOC\n"); + break; + case EGL_BAD_ATTRIBUTE: + os::Printer::log("Error: EGL_BAD_ATTRIBUTE\n"); + break; + case EGL_BAD_CONTEXT: + os::Printer::log("Error: EGL_BAD_CONTEXT\n"); + break; + case EGL_BAD_CONFIG: + os::Printer::log("Error: EGL_BAD_CONFIG\n"); + break; + case EGL_BAD_CURRENT_SURFACE: + os::Printer::log("Error: EGL_BAD_CURRENT_SURFACE\n"); + break; + case EGL_BAD_DISPLAY: + os::Printer::log("Error: EGL_BAD_DISPLAY\n"); + break; + case EGL_BAD_SURFACE: + os::Printer::log("Error: EGL_BAD_SURFACE\n"); + break; + case EGL_BAD_MATCH: + os::Printer::log("Error: EGL_BAD_MATCH\n"); + break; + case EGL_BAD_PARAMETER: + os::Printer::log("Error: EGL_BAD_PARAMETER\n"); + break; + case EGL_BAD_NATIVE_PIXMAP: + os::Printer::log("Error: EGL_BAD_NATIVE_PIXMAP\n"); + break; + case EGL_BAD_NATIVE_WINDOW: + os::Printer::log("Error: EGL_BAD_NATIVE_WINDOW\n"); + break; + case EGL_CONTEXT_LOST: + os::Printer::log("Error: EGL_CONTEXT_LOST\n"); + break; + default: + os::Printer::log("Error: Unknown EGL error.\n"); + break; + }; + + return result; +} + +#endif diff --git a/lib/irrlicht/source/Irrlicht/CContextEGL.h b/lib/irrlicht/source/Irrlicht/CContextEGL.h new file mode 100644 index 000000000..5029df497 --- /dev/null +++ b/lib/irrlicht/source/Irrlicht/CContextEGL.h @@ -0,0 +1,87 @@ +// Copyright (C) 2013 Patryk Nadrowski +// Copyright (C) 2016-2017 Dawid Gan +// Heavily based on the OpenGL driver implemented by Nikolaus Gebhardt +// OpenGL ES driver implemented by Christian Stehno and first OpenGL ES 2.0 +// driver implemented by Amundis. +// This file is part of the "Irrlicht Engine". +// For conditions of distribution and use, see copyright notice in Irrlicht.h + +#ifndef CONTEXT_EGL_HPP +#define CONTEXT_EGL_HPP + +#include "IrrCompileConfig.h" + +#if defined(_IRR_COMPILE_WITH_EGL_) + +#include + +#ifndef EGL_CONTEXT_MAJOR_VERSION +#define EGL_CONTEXT_MAJOR_VERSION 0x3098 +#endif +#ifndef EGL_CONTEXT_MINOR_VERSION +#define EGL_CONTEXT_MINOR_VERSION 0x30FB +#endif + +enum ContextEGLOpenGLAPI +{ + CEGL_API_OPENGL, + CEGL_API_OPENGL_ES +}; + +enum ContextEGLSurfaceType +{ + CEGL_SURFACE_WINDOW, + CEGL_SURFACE_PBUFFER +}; + +struct ContextEGLParams +{ + ContextEGLOpenGLAPI opengl_api; + ContextEGLSurfaceType surface_type; + EGLNativeWindowType window; + EGLNativeDisplayType display; + bool force_legacy_device; + bool with_alpha_channel; + bool vsync_enabled; + int pbuffer_width; + int pbuffer_height; +}; + + +class ContextManagerEGL +{ +private: + EGLNativeWindowType m_egl_window; + EGLDisplay m_egl_display; + EGLSurface m_egl_surface; + EGLContext m_egl_context; + EGLConfig m_egl_config; + + ContextEGLParams m_creation_params; + bool m_is_legacy_device; + bool m_initialized; + int m_egl_version; + + bool initDisplay(); + bool chooseConfig(); + bool createSurface(); + bool createContext(); + bool hasEGLExtension(const char* extension); + bool checkEGLError(); + +public: + ContextManagerEGL(); + ~ContextManagerEGL(); + + bool init(const ContextEGLParams& params); + void close(); + + void reloadEGLSurface(void* window); + bool swapBuffers(); + bool isLegacyDevice() {return m_is_legacy_device;} + bool getSurfaceDimensions(int* width, int* height); +}; + +#endif + +#endif diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp index 3e491ff4b..95db25696 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.cpp @@ -10,6 +10,7 @@ #include #include "os.h" +#include "CContextEGL.h" #include "CFileSystem.h" #include "COGLES2Driver.h" @@ -306,7 +307,7 @@ void CIrrDeviceAndroid::handleAndroidCommand(android_app* app, int32_t cmd) device->CreationParams.DriverType == video::EDT_OGLES2) { video::COGLES2Driver* driver = (video::COGLES2Driver*)(device->VideoDriver); - driver->reloadEGLSurface(app->window); + driver->getEGLContext()->reloadEGLSurface(app->window); } } diff --git a/lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp b/lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp index a39445e7f..16991fd95 100644 --- a/lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp +++ b/lib/irrlicht/source/Irrlicht/COGLES2Driver.cpp @@ -17,6 +17,7 @@ #include "COGLES2NormalMapRenderer.h" #include "COGLES2ParallaxMapRenderer.h" #include "COGLES2Renderer2D.h" +#include "CContextEGL.h" #include "CImage.h" #include "os.h" @@ -24,7 +25,6 @@ #include #include #else -#include #include #endif @@ -45,15 +45,15 @@ namespace video BridgeCalls(0), CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true), AntiAlias(params.AntiAlias), RenderTargetTexture(0), CurrentRendertargetSize(0, 0), ColorFormat(ECF_R8G8B8) -#ifdef EGL_VERSION_1_0 - , EglDisplay(EGL_NO_DISPLAY) -#endif -#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) - , HDc(0) +#if defined(_IRR_COMPILE_WITH_EGL_) + , EglContext(0) #elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) , ViewFramebuffer(0) , ViewRenderbuffer(0) , ViewDepthRenderbuffer(0) +#endif +#if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) + , HDc(0) #endif , Params(params) { @@ -61,248 +61,50 @@ namespace video setDebugName("COGLES2Driver"); #endif ExposedData = data; + +#if defined(_IRR_COMPILE_WITH_EGL_) + EglContext = new ContextManagerEGL(); + + ContextEGLParams egl_params; + egl_params.opengl_api = CEGL_API_OPENGL_ES; + egl_params.surface_type = CEGL_SURFACE_WINDOW; + egl_params.force_legacy_device = Params.ForceLegacyDevice; + egl_params.with_alpha_channel = Params.WithAlphaChannel; + egl_params.vsync_enabled = Params.Vsync; + #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) - EglWindow = (NativeWindowType)data.OpenGLWin32.HWnd; - HDc = GetDC((HWND)EglWindow); - EglDisplay = eglGetDisplay((NativeDisplayType)HDc); + egl_params.window = (EGLNativeWindowType)(data.OpenGLWin32.HWnd); + HDc = GetDC(data.OpenGLWin32.HWnd); + egl_params.display = (NativeDisplayType)(HDc); #elif defined(_IRR_COMPILE_WITH_X11_DEVICE_) - EglWindow = (NativeWindowType)ExposedData.OpenGLLinux.X11Window; - EglDisplay = eglGetDisplay((NativeDisplayType)ExposedData.OpenGLLinux.X11Display); -#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) - Device = device; + egl_params.window = data.OpenGLLinux.X11Window; + egl_params.display = (EGLNativeDisplayType)(data.OpenGLLinux.X11Display); #elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) - EglWindow = ((struct android_app *)(params.PrivateData))->window; - EglDisplay = EGL_NO_DISPLAY; + egl_params.window = ((struct android_app *)(params.PrivateData))->window; + egl_params.display = NULL; #endif -#ifdef EGL_VERSION_1_0 - if (EglDisplay == EGL_NO_DISPLAY) - { - os::Printer::log("Getting OpenGL-ES2 display."); - EglDisplay = eglGetDisplay((NativeDisplayType) EGL_DEFAULT_DISPLAY); - } - if (EglDisplay == EGL_NO_DISPLAY) - { - os::Printer::log("Could not get OpenGL-ES2 display."); - } - - EGLint majorVersion, minorVersion; - if (!eglInitialize(EglDisplay, &majorVersion, &minorVersion)) - { - os::Printer::log("Could not initialize OpenGL-ES2 display."); - } - else - { - char text[64]; - sprintf(text, "EglDisplay initialized. Egl version %d.%d\n", majorVersion, minorVersion); - os::Printer::log(text); - } - - EGLint attribs[] = - { -#if defined( _IRR_COMPILE_WITH_ANDROID_DEVICE_ ) - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_BLUE_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_RED_SIZE, 8, - EGL_DEPTH_SIZE, 16, - EGL_NONE -#else - EGL_RED_SIZE, 5, - EGL_GREEN_SIZE, 5, - EGL_BLUE_SIZE, 5, - EGL_ALPHA_SIZE, params.WithAlphaChannel ? 1 : 0, - EGL_BUFFER_SIZE, params.Bits, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - //EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, - EGL_DEPTH_SIZE, params.ZBufferBits, - EGL_STENCIL_SIZE, params.Stencilbuffer, - EGL_SAMPLE_BUFFERS, params.AntiAlias ? 1 : 0, - EGL_SAMPLES, params.AntiAlias, -#ifdef EGL_VERSION_1_3 - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, -#endif - EGL_NONE, 0 -#endif - }; - - EGLint num_configs; - u32 steps=5; - while (!eglChooseConfig(EglDisplay, attribs, &EglConfig, 1, &num_configs) || !num_configs) - { - switch (steps) - { - case 5: // samples - if (attribs[19]>2) - { - --attribs[19]; - } - else - { - attribs[17]=0; - attribs[19]=0; - --steps; - } - break; - case 4: // alpha - if (attribs[7]) - { - attribs[7]=0; - if (params.AntiAlias) - { - attribs[17]=1; - attribs[19]=params.AntiAlias; - steps=5; - } - } - else - --steps; - break; - case 3: // stencil - if (attribs[15]) - { - attribs[15]=0; - if (params.AntiAlias) - { - attribs[17]=1; - attribs[19]=params.AntiAlias; - steps=5; - } - } - else - --steps; - break; - case 2: // depth size - if (attribs[13]>16) - { - attribs[13]-=8; - } - else - --steps; - break; - case 1: // buffer size - if (attribs[9]>16) - { - attribs[9]-=8; - } - else - --steps; - break; - default: - os::Printer::log("Could not get config for OpenGL-ES2 display."); - return; - } - } - if (params.AntiAlias && !attribs[17]) - os::Printer::log("No multisampling."); - if (params.WithAlphaChannel && !attribs[7]) - os::Printer::log("No alpha."); - if (params.Stencilbuffer && !attribs[15]) - os::Printer::log("No stencil buffer."); - if (params.ZBufferBits > attribs[13]) - os::Printer::log("No full depth buffer."); - if (params.Bits > attribs[9]) - os::Printer::log("No full color buffer."); - #if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) - /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is - * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). - * As soon as we picked a EGLConfig, we can safely reconfigure the - * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ - EGLint format; - eglGetConfigAttrib(EglDisplay, EglConfig, EGL_NATIVE_VISUAL_ID, &format); - - ANativeWindow_setBuffersGeometry(EglWindow, 0, 0, format); - #endif - os::Printer::log(" Creating EglSurface with nativeWindow..."); - EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, EglWindow, NULL); - if (EGL_NO_SURFACE == EglSurface) - { - os::Printer::log("FAILED\n"); - EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, 0, NULL); - os::Printer::log("Creating EglSurface without nativeWindows..."); - } - else - os::Printer::log("SUCCESS\n"); - if (EGL_NO_SURFACE == EglSurface) - { - os::Printer::log("FAILED\n"); - os::Printer::log("Could not create surface for OpenGL-ES2 display."); - } - else - os::Printer::log("SUCCESS\n"); - -#ifdef EGL_VERSION_1_2 - if (minorVersion>1) - eglBindAPI(EGL_OPENGL_ES_API); -#endif - os::Printer::log("Creating EglContext..."); - EglContext = EGL_NO_CONTEXT; - - if (!Params.ForceLegacyDevice) - { - os::Printer::log("Trying to create Context for OpenGL-ES3."); - - EGLint contextAttrib[] = - { - #ifdef EGL_VERSION_1_3 - EGL_CONTEXT_CLIENT_VERSION, 3, - #endif - EGL_NONE, 0 - }; - - EglContext = eglCreateContext(EglDisplay, EglConfig, EGL_NO_CONTEXT, contextAttrib); - } - - if (EGL_NO_CONTEXT == EglContext) - { - os::Printer::log("Trying to create Context for OpenGL-ES2."); - useCoreContext = false; - - EGLint contextAttrib[] = - { - #ifdef EGL_VERSION_1_3 - EGL_CONTEXT_CLIENT_VERSION, 2, - #endif - EGL_NONE, 0 - }; - - EglContext = eglCreateContext(EglDisplay, EglConfig, EGL_NO_CONTEXT, contextAttrib); - if (EGL_NO_CONTEXT == EglContext) - { - os::Printer::log("FAILED\n"); - os::Printer::log("Could not create Context for OpenGL-ES2 display."); - } - } - - eglMakeCurrent(EglDisplay, EglSurface, EglSurface, EglContext); - if (testEGLError()) - { - os::Printer::log("Could not make Context current for OpenGL-ES2 display."); - } + + EglContext->init(egl_params); + useCoreContext = !EglContext->isLegacyDevice(); genericDriverInit(params.WindowSize, params.Stencilbuffer); - + #ifdef _IRR_COMPILE_WITH_ANDROID_DEVICE_ - int backingWidth; - int backingHeight; - eglQuerySurface(EglDisplay, EglSurface, EGL_WIDTH, &backingWidth); - eglQuerySurface(EglDisplay, EglSurface, EGL_HEIGHT, &backingHeight); - core::dimension2d WindowSize(backingWidth, backingHeight); - CNullDriver::ScreenSize = WindowSize; + int width = 0; + int height = 0; + EglContext->getSurfaceDimensions(&width, &height); + CNullDriver::ScreenSize = core::dimension2d(width, height); #endif +#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) + Device = device; - // set vsync - if (params.Vsync) - eglSwapInterval(EglDisplay, 1); -#elif defined(GL_ES_VERSION_2_0) glGenFramebuffers(1, &ViewFramebuffer); glGenRenderbuffers(1, &ViewRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, ViewRenderbuffer); -#if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) ExposedData.OGLESIPhone.AppDelegate = Device; Device->displayInitialize(&ExposedData.OGLESIPhone.Context, &ExposedData.OGLESIPhone.View); -#endif GLint backingWidth; GLint backingHeight; @@ -342,32 +144,16 @@ namespace video if (BridgeCalls) delete BridgeCalls; -#if defined(EGL_VERSION_1_0) - eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (EglContext != EGL_NO_CONTEXT) - { - eglDestroyContext(EglDisplay, EglContext); - EglContext = EGL_NO_CONTEXT; - } - - if (EglSurface != EGL_NO_SURFACE) - { - eglDestroySurface(EglDisplay, EglSurface); - EglSurface = EGL_NO_SURFACE; - } - - if (EglDisplay != EGL_NO_DISPLAY) - { - eglTerminate(EglDisplay); - EglDisplay = EGL_NO_DISPLAY; - } - +#if defined(_IRR_COMPILE_WITH_EGL_) + delete EglContext; + #if defined(_IRR_COMPILE_WITH_WINDOWS_DEVICE_) if (HDc) - ReleaseDC((HWND)EglWindow, HDc); + ReleaseDC((ExposedData.OpenGLWin32.HWnd, HDc); #endif -#elif defined(GL_ES_VERSION_2_0) + + +#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) if (0 != ViewFramebuffer) { glDeleteFramebuffers(1,&ViewFramebuffer); @@ -390,41 +176,12 @@ namespace video // METHODS // ----------------------------------------------------------------------- - void COGLES2Driver::reloadEGLSurface(void* window) - { - os::Printer::log("Reload EGL surface."); - - #ifdef EGL_VERSION_1_0 - #if defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) - EglWindow = (ANativeWindow*)window; - #endif - - if (!EglWindow) - os::Printer::log("Invalid Egl window."); - - eglMakeCurrent(EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - eglDestroySurface(EglDisplay, EglSurface); - - EglSurface = eglCreateWindowSurface(EglDisplay, EglConfig, EglWindow, 0); - - if (EGL_NO_SURFACE == EglSurface) - os::Printer::log("Could not create EGL surface."); - - eglMakeCurrent(EglDisplay, EglSurface, EglSurface, EglContext); - #endif - } - bool COGLES2Driver::genericDriverInit(const core::dimension2d& screenSize, bool stencilBuffer) { Name = glGetString(GL_VERSION); printVersion(); -#if defined(EGL_VERSION_1_0) - os::Printer::log(eglQueryString(EglDisplay, EGL_CLIENT_APIS)); -#endif - // print renderer information vendorName = glGetString(GL_VENDOR); os::Printer::log(vendorName.c_str(), ELL_INFORMATION); @@ -433,11 +190,7 @@ namespace video for (i = 0; i < MATERIAL_MAX_TEXTURES; ++i) CurrentTexture[i] = 0; // load extensions - initExtensions(this, -#if defined(EGL_VERSION_1_0) - EglDisplay, -#endif - stencilBuffer); + initExtensions(this, stencilBuffer); if (!BridgeCalls) BridgeCalls = new COGLES2CallBridge(this); @@ -713,26 +466,20 @@ namespace video { CNullDriver::endScene(); -#if defined(EGL_VERSION_1_0) - eglSwapBuffers(EglDisplay, EglSurface); - EGLint g = eglGetError(); - if (EGL_SUCCESS != g) +#if defined(_IRR_COMPILE_WITH_EGL_) + + bool res = EglContext->swapBuffers(); + + if (!res) { - if (EGL_CONTEXT_LOST == g) - { - // o-oh, ogl-es has lost contexts... - os::Printer::log("Context lost, please restart your app."); - } - else - os::Printer::log("Could not swap buffers for OpenGL-ES2 driver."); + os::Printer::log("Could not swap buffers for OpenGL-ES2 driver."); return false; } -#elif defined(GL_ES_VERSION_2_0) + +#elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) glFlush(); glBindRenderbuffer(GL_RENDERBUFFER, ViewRenderbuffer); -#if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) Device->displayEnd(); -#endif #endif return true; @@ -1896,65 +1643,6 @@ namespace video #endif } - //! prints error if an error happened. - bool COGLES2Driver::testEGLError() - { -#if defined(EGL_VERSION_1_0) && defined(_DEBUG) - EGLint g = eglGetError(); - switch (g) - { - case EGL_SUCCESS: - return false; - case EGL_NOT_INITIALIZED : - os::Printer::log("Not Initialized", ELL_ERROR); - break; - case EGL_BAD_ACCESS: - os::Printer::log("Bad Access", ELL_ERROR); - break; - case EGL_BAD_ALLOC: - os::Printer::log("Bad Alloc", ELL_ERROR); - break; - case EGL_BAD_ATTRIBUTE: - os::Printer::log("Bad Attribute", ELL_ERROR); - break; - case EGL_BAD_CONTEXT: - os::Printer::log("Bad Context", ELL_ERROR); - break; - case EGL_BAD_CONFIG: - os::Printer::log("Bad Config", ELL_ERROR); - break; - case EGL_BAD_CURRENT_SURFACE: - os::Printer::log("Bad Current Surface", ELL_ERROR); - break; - case EGL_BAD_DISPLAY: - os::Printer::log("Bad Display", ELL_ERROR); - break; - case EGL_BAD_SURFACE: - os::Printer::log("Bad Surface", ELL_ERROR); - break; - case EGL_BAD_MATCH: - os::Printer::log("Bad Match", ELL_ERROR); - break; - case EGL_BAD_PARAMETER: - os::Printer::log("Bad Parameter", ELL_ERROR); - break; - case EGL_BAD_NATIVE_PIXMAP: - os::Printer::log("Bad Native Pixmap", ELL_ERROR); - break; - case EGL_BAD_NATIVE_WINDOW: - os::Printer::log("Bad Native Window", ELL_ERROR); - break; - case EGL_CONTEXT_LOST: - os::Printer::log("Context Lost", ELL_ERROR); - break; - }; - return true; -#else - return false; -#endif - } - - void COGLES2Driver::setRenderStates3DMode() { if (useCoreContext) diff --git a/lib/irrlicht/source/Irrlicht/COGLES2Driver.h b/lib/irrlicht/source/Irrlicht/COGLES2Driver.h index c6cdb9aa3..007dc2dbc 100644 --- a/lib/irrlicht/source/Irrlicht/COGLES2Driver.h +++ b/lib/irrlicht/source/Irrlicht/COGLES2Driver.h @@ -10,13 +10,7 @@ #include "IrrCompileConfig.h" -#if defined(_IRR_WINDOWS_API_) -// include windows headers for HWND -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#elif defined(_IRR_COMPILE_WITH_OSX_DEVICE_) +#if defined(_IRR_COMPILE_WITH_OSX_DEVICE_) #include "MacOSX/CIrrDeviceMacOSX.h" #elif defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) #include "iOS/CIrrDeviceiOS.h" @@ -30,11 +24,8 @@ #include #include #elif defined(_IRR_COMPILE_WITH_ANDROID_DEVICE_) -#include #include #include "android_native_app_glue.h" -#else -#include #endif #include "CNullDriver.h" @@ -43,11 +34,12 @@ #include "fast_atof.h" #ifdef _MSC_VER -#pragma comment(lib, "libEGL.lib") #pragma comment(lib, "libGLESv2.lib") #endif #include "COGLES2ExtensionHandler.h" +class ContextManagerEGL; + namespace irr { namespace video @@ -340,9 +332,6 @@ namespace video //! checks if an OpenGL error has happend and prints it bool testGLError(); - //! checks if an OGLES1 error has happend and prints it - bool testEGLError(); - //! Set/unset a clipping plane. virtual bool setClipPlane(u32 index, const core::plane3df& plane, bool enable = false); @@ -381,8 +370,10 @@ namespace video //! Get bridge calls. COGLES2CallBridge* getBridgeCalls() const; - - void reloadEGLSurface(void* window); + +#if defined(_IRR_COMPILE_WITH_EGL_) + ContextManagerEGL* getEGLContext() {return EglContext;} +#endif private: // Bridge calls. @@ -466,21 +457,18 @@ namespace video SColorf AmbientLight; COGLES2Renderer2D* MaterialRenderer2D; - -#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ - HDC HDc; + +#if defined(_IRR_COMPILE_WITH_EGL_) + ContextManagerEGL* EglContext; #endif #if defined(_IRR_COMPILE_WITH_IPHONE_DEVICE_) CIrrDeviceIPhone* Device; GLuint ViewFramebuffer; GLuint ViewRenderbuffer; GLuint ViewDepthRenderbuffer; -#else - NativeWindowType EglWindow; - void* EglDisplay; - void* EglSurface; - void* EglContext; - EGLConfig EglConfig; +#endif +#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_ + HDC HDc; #endif SIrrlichtCreationParameters Params; diff --git a/lib/irrlicht/source/Irrlicht/COGLES2ExtensionHandler.cpp b/lib/irrlicht/source/Irrlicht/COGLES2ExtensionHandler.cpp index 82bec11ea..4ec8eff19 100644 --- a/lib/irrlicht/source/Irrlicht/COGLES2ExtensionHandler.cpp +++ b/lib/irrlicht/source/Irrlicht/COGLES2ExtensionHandler.cpp @@ -158,7 +158,7 @@ namespace video }; COGLES2ExtensionHandler::COGLES2ExtensionHandler() : - EGLVersion(0), Version(0), MaxTextureUnits(0), MaxSupportedTextures(0), + Version(0), MaxTextureUnits(0), MaxSupportedTextures(0), MaxAnisotropy(1), MaxIndices(0xffff), MaxTextureSize(1), MaxTextureLODBias(0.f), StencilBuffer(false) @@ -176,17 +176,8 @@ namespace video void COGLES2ExtensionHandler::initExtensions(COGLES2Driver* driver, -#ifdef EGL_VERSION_1_0 - EGLDisplay display, -#endif bool withStencil) { -#ifdef EGL_VERSION_1_0 - const f32 egl_ver = core::fast_atof(reinterpret_cast(eglQueryString(display, EGL_VERSION))); - EGLVersion = static_cast(core::floor32(egl_ver)*100+core::round32(core::fract(egl_ver)*10.0f)); - core::stringc eglExtensions = eglQueryString(display, EGL_EXTENSIONS); - os::Printer::log(eglExtensions.c_str()); -#endif const core::stringc stringVer(glGetString(GL_VERSION)); const f32 ogl_ver = core::fast_atof(stringVer.c_str() + 10); Version = static_cast(core::floor32(ogl_ver) * 100 + core::round32(core::fract(ogl_ver) * 10.0f)); diff --git a/lib/irrlicht/source/Irrlicht/COGLES2ExtensionHandler.h b/lib/irrlicht/source/Irrlicht/COGLES2ExtensionHandler.h index 056196d8e..58ae56c63 100644 --- a/lib/irrlicht/source/Irrlicht/COGLES2ExtensionHandler.h +++ b/lib/irrlicht/source/Irrlicht/COGLES2ExtensionHandler.h @@ -14,7 +14,6 @@ #include #include #else -#include #include // seems to be missing... typedef char GLchar; @@ -232,13 +231,9 @@ namespace video void dump() const; void initExtensions(COGLES2Driver* driver, -#ifdef EGL_VERSION_1_0 - EGLDisplay display, -#endif bool withStencil); protected: - u16 EGLVersion; u16 Version; u8 MaxTextureUnits; u8 MaxSupportedTextures;