Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
63c4d67e3This file is pinned to the selected release. Download the original to open it in your design tool.
// portions of this file are copied from GLFW egl_context.c/egl_context.h
//========================================================================
// GLFW 3.3 EGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifdef BT_USE_EGL
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cstdlib>
#include "OpenGLInclude.h"
#include "glad/egl.h"
#include "glad/gl.h"
#include "EGLOpenGLWindow.h"
struct EGLInternalData2
{
bool m_isInitialized;
int m_windowWidth;
int m_windowHeight;
int m_renderDevice;
b3KeyboardCallback m_keyboardCallback;
b3WheelCallback m_wheelCallback;
b3ResizeCallback m_resizeCallback;
b3MouseButtonCallback m_mouseButtonCallback;
b3MouseMoveCallback m_mouseMoveCallback;
EGLBoolean success;
EGLint num_configs;
EGLConfig egl_config;
EGLSurface egl_surface;
EGLContext egl_context;
EGLDisplay egl_display;
EGLInternalData2()
: m_isInitialized(false),
m_windowWidth(0),
m_windowHeight(0),
m_keyboardCallback(0),
m_wheelCallback(0),
m_resizeCallback(0),
m_mouseButtonCallback(0),
m_mouseMoveCallback(0) {}
};
EGLOpenGLWindow::EGLOpenGLWindow() { m_data = new EGLInternalData2(); }
EGLOpenGLWindow::~EGLOpenGLWindow() { delete m_data; }
void EGLOpenGLWindow::createWindow(const b3gWindowConstructionInfo& ci)
{
m_data->m_windowWidth = ci.m_width;
m_data->m_windowHeight = ci.m_height;
m_data->m_renderDevice = ci.m_renderDevice;
EGLint egl_config_attribs[] = {EGL_RED_SIZE,
8,
EGL_GREEN_SIZE,
8,
EGL_BLUE_SIZE,
8,
EGL_DEPTH_SIZE,
8,
EGL_SURFACE_TYPE,
EGL_PBUFFER_BIT,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_BIT,
EGL_NONE};
EGLint egl_pbuffer_attribs[] = {
EGL_WIDTH,
m_data->m_windowWidth,
EGL_HEIGHT,
m_data->m_windowHeight,
EGL_NONE,
};
// Load EGL functions
int egl_version = gladLoaderLoadEGL(NULL);
if (!egl_version)
{
fprintf(stderr, "failed to EGL with glad.\n");
exit(EXIT_FAILURE);
};
// Query EGL Devices
const int max_devices = 32;
EGLDeviceEXT egl_devices[max_devices];
EGLint num_devices = 0;
EGLint egl_error = eglGetError();
if (!eglQueryDevicesEXT(max_devices, egl_devices, &num_devices) ||
egl_error != EGL_SUCCESS)
{
printf("eglQueryDevicesEXT Failed.\n");
m_data->egl_display = EGL_NO_DISPLAY;
} else
{
// default case, should always happen (for future compatibility)
if (m_data->m_renderDevice == -1)
{
// check env variable
const char* env_p = std::getenv("EGL_VISIBLE_DEVICES");
// variable is set
if(env_p != NULL)
{
m_data->m_renderDevice = std::atoi(env_p);
fprintf(stderr, "EGL device choice: %d of %d (from EGL_VISIBLE_DEVICES)\n", m_data->m_renderDevice, num_devices);
} else {
fprintf(stderr, "EGL device choice: %d of %d.\n", m_data->m_renderDevice, num_devices);
} // else leave with -1
} else
{
fprintf(stderr, "EGL device choice: %d of %d.\n", m_data->m_renderDevice, num_devices);
}
}
// Query EGL Screens
if (m_data->m_renderDevice == -1)
{
// Chose default screen, by trying all
for (EGLint i = 0; i < num_devices; ++i)
{
// Set display
EGLDisplay display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
egl_devices[i], NULL);
if (eglGetError() == EGL_SUCCESS && display != EGL_NO_DISPLAY)
{
int major, minor;
EGLBoolean initialized = eglInitialize(display, &major, &minor);
if (eglGetError() == EGL_SUCCESS && initialized == EGL_TRUE)
{
m_data->egl_display = display;
break;
}
}
else
{
fprintf(stderr, "GetDisplay %d failed with error: %x\n", i, eglGetError());
}
}
}
else
{
// Chose specific screen, by using m_renderDevice
if (m_data->m_renderDevice < 0 || m_data->m_renderDevice >= num_devices)
{
fprintf(stderr, "Invalid render_device choice: %d < %d.\n", m_data->m_renderDevice, num_devices);
exit(EXIT_FAILURE);
}
// Set display
EGLDisplay display = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
egl_devices[m_data->m_renderDevice], NULL);
if (eglGetError() == EGL_SUCCESS && display != EGL_NO_DISPLAY)
{
int major, minor;
EGLBoolean initialized = eglInitialize(display, &major, &minor);
if (eglGetError() == EGL_SUCCESS && initialized == EGL_TRUE)
{
m_data->egl_display = display;
}
}
else
{
fprintf(stderr, "GetDisplay %d failed with error: %x\n", m_data->m_renderDevice, eglGetError());
}
}
if (!eglInitialize(m_data->egl_display, NULL, NULL))
{
fprintf(stderr, "eglInitialize() failed with error: %x\n", eglGetError());
exit(EXIT_FAILURE);
}
egl_version = gladLoaderLoadEGL(m_data->egl_display);
if (!egl_version)
{
fprintf(stderr, "Unable to reload EGL.\n");
exit(EXIT_FAILURE);
}
printf("Loaded EGL %d.%d after reload.\n", GLAD_VERSION_MAJOR(egl_version),
GLAD_VERSION_MINOR(egl_version));
m_data->success = eglBindAPI(EGL_OPENGL_API);
if (!m_data->success)
{
// TODO: Properly handle this error (requires change to default window
// API to change return on all window types to bool).
fprintf(stderr, "Failed to bind OpenGL API.\n");
exit(EXIT_FAILURE);
}
m_data->success =
eglChooseConfig(m_data->egl_display, egl_config_attribs,
&m_data->egl_config, 1, &m_data->num_configs);
if (!m_data->success)
{
// TODO: Properly handle this error (requires change to default window
// API to change return on all window types to bool).
fprintf(stderr, "Failed to choose config (eglError: %d)\n", eglGetError());
exit(EXIT_FAILURE);
}
if (m_data->num_configs != 1)
{
fprintf(stderr, "Didn't get exactly one config, but %d\n", m_data->num_configs);
exit(EXIT_FAILURE);
}
m_data->egl_surface = eglCreatePbufferSurface(
m_data->egl_display, m_data->egl_config, egl_pbuffer_attribs);
if (m_data->egl_surface == EGL_NO_SURFACE)
{
fprintf(stderr, "Unable to create EGL surface (eglError: %d)\n", eglGetError());
exit(EXIT_FAILURE);
}
EGLint egl_context_attribs[] = {
EGL_CONTEXT_MAJOR_VERSION,
3,
EGL_CONTEXT_MINOR_VERSION,
3,
EGL_CONTEXT_OPENGL_PROFILE_MASK,
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE,
EGL_TRUE,
EGL_NONE,
};
m_data->egl_context = eglCreateContext(
m_data->egl_display, m_data->egl_config, EGL_NO_CONTEXT, egl_context_attribs);
if (!m_data->egl_context)
{
fprintf(stderr, "Unable to create EGL context (eglError: %d)\n", eglGetError());
exit(EXIT_FAILURE);
}
m_data->success =
eglMakeCurrent(m_data->egl_display, m_data->egl_surface, m_data->egl_surface,
m_data->egl_context);
if (!m_data->success)
{
fprintf(stderr, "Failed to make context current (eglError: %d)\n", eglGetError());
exit(EXIT_FAILURE);
}
if (!gladLoadGL((GLADloadfunc)eglGetProcAddress))
{
fprintf(stderr, "failed to load GL with glad.\n");
exit(EXIT_FAILURE);
}
const GLubyte* ven = glGetString(GL_VENDOR);
printf("GL_VENDOR=%s\n", ven);
const GLubyte* ren = glGetString(GL_RENDERER);
printf("GL_RENDERER=%s\n", ren);
const GLubyte* ver = glGetString(GL_VERSION);
printf("GL_VERSION=%s\n", ver);
const GLubyte* sl = glGetString(GL_SHADING_LANGUAGE_VERSION);
printf("GL_SHADING_LANGUAGE_VERSION=%s\n", sl);
glViewport(0,0,m_data->m_windowWidth, m_data->m_windowHeight);
//int i = pthread_getconcurrency();
//printf("pthread_getconcurrency()=%d\n", i);
}
void EGLOpenGLWindow::closeWindow()
{
eglMakeCurrent(m_data->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
EGL_NO_CONTEXT);
eglDestroySurface(m_data->egl_display, m_data->egl_surface);
eglDestroyContext(m_data->egl_display, m_data->egl_context);
printf("Destroy EGL OpenGL window.\n");
}
void EGLOpenGLWindow::runMainLoop() {}
float EGLOpenGLWindow::getTimeInSeconds() { return 0.; }
bool EGLOpenGLWindow::requestedExit() const { return false; }
void EGLOpenGLWindow::setRequestExit() {}
void EGLOpenGLWindow::startRendering()
{
// printf("EGL window start rendering.\n");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
}
void EGLOpenGLWindow::endRendering()
{
// printf("EGL window end rendering.\n");
eglSwapBuffers(m_data->egl_display, m_data->egl_surface);
}
bool EGLOpenGLWindow::isModifierKeyPressed(int key) { return false; }
void EGLOpenGLWindow::setMouseMoveCallback(b3MouseMoveCallback mouseCallback)
{
m_data->m_mouseMoveCallback = mouseCallback;
}
b3MouseMoveCallback EGLOpenGLWindow::getMouseMoveCallback()
{
return m_data->m_mouseMoveCallback;
}
void EGLOpenGLWindow::setMouseButtonCallback(
b3MouseButtonCallback mouseCallback)
{
m_data->m_mouseButtonCallback = mouseCallback;
}
b3MouseButtonCallback EGLOpenGLWindow::getMouseButtonCallback()
{
return m_data->m_mouseButtonCallback;
}
void EGLOpenGLWindow::setResizeCallback(b3ResizeCallback resizeCallback)
{
m_data->m_resizeCallback = resizeCallback;
}
b3ResizeCallback EGLOpenGLWindow::getResizeCallback()
{
return m_data->m_resizeCallback;
}
void EGLOpenGLWindow::setWheelCallback(b3WheelCallback wheelCallback)
{
m_data->m_wheelCallback = wheelCallback;
}
b3WheelCallback EGLOpenGLWindow::getWheelCallback()
{
return m_data->m_wheelCallback;
}
void EGLOpenGLWindow::setKeyboardCallback(b3KeyboardCallback keyboardCallback)
{
m_data->m_keyboardCallback = keyboardCallback;
}
b3KeyboardCallback EGLOpenGLWindow::getKeyboardCallback()
{
return m_data->m_keyboardCallback;
}
void EGLOpenGLWindow::setRenderCallback(b3RenderCallback renderCallback) {}
void EGLOpenGLWindow::setWindowTitle(const char* title) {}
float EGLOpenGLWindow::getRetinaScale() const { return 1.f; }
void EGLOpenGLWindow::setAllowRetina(bool allow) {}
int EGLOpenGLWindow::getWidth() const { return m_data->m_windowWidth; }
int EGLOpenGLWindow::getHeight() const { return m_data->m_windowHeight; }
int EGLOpenGLWindow::fileOpenDialog(char* fileName, int maxFileNameLength)
{
return 0;
}
#endif // BT_USE_EGL