137 lines
3.3 KiB
C++
137 lines
3.3 KiB
C++
// =====================================================================================================================
|
|
// fennec, a free and open source game engine
|
|
// Copyright © 2025 Medusa Slockbower
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
// =====================================================================================================================
|
|
|
|
#include <fennec/lang/startup.h>
|
|
#include <fennec/platform/interface/display.h>
|
|
#include <fennec/platform/interface/platform.h>
|
|
#include <fennec/platform/opengl/egl/context.h>
|
|
|
|
namespace fennec
|
|
{
|
|
|
|
static gfxcontext* _create_egl_context(display* display) {
|
|
eglcontext* ctx = new eglcontext(display);
|
|
if (not ctx->connected()) {
|
|
delete ctx, ctx = nullptr;
|
|
}
|
|
return ctx;
|
|
}
|
|
|
|
STATIC_CONSTRUCTOR(_egl_init) {
|
|
platform::add_driver(_create_egl_context, 1);
|
|
}
|
|
|
|
eglcontext::eglcontext(display* display)
|
|
: gfxcontext(display, "EGL", this) {
|
|
|
|
const display::pixel_format& fmt = _display->get_color_format();
|
|
|
|
EGLint context_attrs[] = {
|
|
#if FENNEC_GRAPHICS_OPENGL
|
|
EGL_CONTEXT_MAJOR_VERSION, 4,
|
|
EGL_CONTEXT_MINOR_VERSION, 3,
|
|
#elif FENNEC_GRAPHICS_GLES3
|
|
EGL_CONTEXT_MAJOR_VERSION, 3,
|
|
EGL_CONTEXT_MINOR_VERSION, 2,
|
|
#elif FENNEC_GRAPHICS_GLES2
|
|
EGL_CONTEXT_MAJOR_VERSION, 2,
|
|
EGL_CONTEXT_MINOR_VERSION, 0,
|
|
#endif
|
|
EGL_NONE
|
|
};
|
|
|
|
EGLint config_attrs[] = {
|
|
EGL_SURFACE_TYPE,
|
|
EGL_WINDOW_BIT,
|
|
EGL_DEPTH_SIZE, fmt.depth,
|
|
EGL_RED_SIZE, fmt.r,
|
|
EGL_RED_SIZE, fmt.g,
|
|
EGL_RED_SIZE, fmt.b,
|
|
EGL_RENDERABLE_TYPE,
|
|
|
|
#if FENNEC_GRAPHICS_OPENGL
|
|
EGL_OPENGL_BIT,
|
|
#elif FENNEC_GRAPHICS_GLES3
|
|
EGL_OPENGL_ES3_BIT,
|
|
#elif FENNEC_GRAPHICS_GLES2
|
|
EGL_OPENGL_ES2_BIT,
|
|
#endif
|
|
EGL_NONE
|
|
};
|
|
|
|
|
|
_egldisplay = eglGetDisplay(_display->get_native_handle());
|
|
if (_egldisplay == nullptr) {
|
|
cleanup();
|
|
return;
|
|
}
|
|
|
|
if (not eglInitialize(_egldisplay, &_eglvmajor, &_eglvminor)) {
|
|
cleanup();
|
|
return;
|
|
}
|
|
|
|
#if FENNEC_GRAPHICS_OPENGL
|
|
if (not eglBindAPI(EGL_OPENGL_API)) {
|
|
#elif FENNEC_GRAPHICS_GLES3 or FENNEC_GRAPHICS_GLES2
|
|
if (not eglBindAPI(EGL_OPENGL_ES_API)) {
|
|
#endif
|
|
cleanup();
|
|
return;
|
|
}
|
|
|
|
EGLint n;
|
|
if (not eglChooseConfig(_egldisplay, config_attrs, &_eglconfig, 1, &n)) {
|
|
cleanup();
|
|
return;
|
|
}
|
|
|
|
_eglcontext = eglCreateContext(_egldisplay, _eglconfig, EGL_NO_CONTEXT, context_attrs);
|
|
if (_eglcontext == nullptr) {
|
|
cleanup();
|
|
return;
|
|
}
|
|
}
|
|
|
|
eglcontext::~eglcontext() {
|
|
cleanup();
|
|
}
|
|
|
|
bool eglcontext::connected() {
|
|
return _eglcontext != nullptr;
|
|
}
|
|
|
|
void eglcontext::make_current(gfxsurface*) {
|
|
|
|
}
|
|
|
|
void eglcontext::cleanup() {
|
|
eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
|
eglDestroyContext(_display, _eglcontext);
|
|
eglTerminate(_display);
|
|
eglReleaseThread();
|
|
|
|
_egldisplay = nullptr;
|
|
_eglconfig = nullptr;
|
|
_eglcontext = nullptr;
|
|
_eglvmajor = 0;
|
|
_eglvminor = 0;
|
|
}
|
|
|
|
}
|