From 333d3e9f9cc54f5f0a011abaa16b24c46e71b8f6 Mon Sep 17 00:00:00 2001 From: martinfouilleul Date: Fri, 17 Feb 2023 18:56:16 +0100 Subject: [PATCH] [gles, wip] reintroducing egl surface (for win32 at first) --- examples/triangleGL/build.bat | 3 +- examples/triangleGL/main.c | 70 +---- examples/triangleGLES/build.bat | 3 +- examples/triangleGLES/main.c | 459 ++++++++++++++++---------------- src/egl_surface.c | 143 ++++++++++ src/egl_surface.h | 17 ++ src/gl_loader.c | 3 +- src/glsl_shaders.h | 2 +- src/graphics.c | 10 + src/graphics.h | 4 + src/milepost.c | 9 +- src/milepost.h | 4 +- todo.txt | 13 +- 13 files changed, 432 insertions(+), 308 deletions(-) create mode 100644 src/egl_surface.c create mode 100644 src/egl_surface.h diff --git a/examples/triangleGL/build.bat b/examples/triangleGL/build.bat index f0aee81..e408577 100644 --- a/examples/triangleGL/build.bat +++ b/examples/triangleGL/build.bat @@ -1,2 +1,3 @@ set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext -cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib /out:test.exe + +cl /we4013 /Zi /Zc:preprocessor /DMG_IMPLEMENTS_BACKEND_GL /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/example_gl_triangle.exe diff --git a/examples/triangleGL/main.c b/examples/triangleGL/main.c index 231318f..52fcc4c 100644 --- a/examples/triangleGL/main.c +++ b/examples/triangleGL/main.c @@ -12,6 +12,7 @@ #define _USE_MATH_DEFINES //NOTE: necessary for MSVC #include +#define MG_INCLUDE_GL_API #include"milepost.h" #define LOG_SUBSYSTEM "Main" @@ -67,9 +68,11 @@ int main() mp_window window = mp_window_create(rect, "test", 0); //NOTE: create surface - mg_surface surface = mg_gl_surface_create_for_window(window); + mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_GL); //NOTE: init shader and gl state + mg_surface_prepare(surface); + GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); @@ -123,69 +126,6 @@ int main() mp_request_quit(); } break; - case MP_EVENT_WINDOW_RESIZE: - { - printf("resized, rect = {%f, %f, %f, %f}\n", - event.frame.rect.x, - event.frame.rect.y, - event.frame.rect.w, - event.frame.rect.h); - } break; - - case MP_EVENT_WINDOW_MOVE: - { - printf("moved, rect = {%f, %f, %f, %f}\n", - event.frame.rect.x, - event.frame.rect.y, - event.frame.rect.w, - event.frame.rect.h); - } break; - - case MP_EVENT_MOUSE_MOVE: - { - printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n", - event.move.x, - event.move.y, - event.move.deltaX, - event.move.deltaY); - } break; - - case MP_EVENT_MOUSE_WHEEL: - { - printf("mouse wheel, delta = {%f, %f}\n", - event.move.deltaX, - event.move.deltaY); - } break; - - case MP_EVENT_MOUSE_ENTER: - { - printf("mouse enter\n"); - } break; - - case MP_EVENT_MOUSE_LEAVE: - { - printf("mouse leave\n"); - } break; - - case MP_EVENT_MOUSE_BUTTON: - { - printf("mouse button %i: %i\n", - event.key.code, - event.key.action == MP_KEY_PRESS ? 1 : 0); - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - printf("key %i: %s\n", - event.key.code, - event.key.action == MP_KEY_PRESS ? "press" : (event.key.action == MP_KEY_RELEASE ? "release" : "repeat")); - } break; - - case MP_EVENT_KEYBOARD_CHAR: - { - printf("entered char %s\n", event.character.sequence); - } break; - default: break; } @@ -200,8 +140,6 @@ int main() //f32 aspect = frameSize.x/frameSize.y; f32 aspect = 800/(f32)600; - glViewport(0, 0, 800, 600); - GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, -sinf(alpha)/aspect, cosf(alpha), 0, 0, 0, 0, 1, 0, diff --git a/examples/triangleGLES/build.bat b/examples/triangleGLES/build.bat index a108856..703566f 100644 --- a/examples/triangleGLES/build.bat +++ b/examples/triangleGLES/build.bat @@ -1,2 +1,3 @@ set INCLUDES=/I ..\..\src /I ..\..\src\util /I ..\..\src\platform /I ../../ext /I ../../ext/angle_headers -cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib /out:../../bin/example_gles_triangle.exe + +cl /we4013 /Zi /Zc:preprocessor /std:c11 %INCLUDES% main.c /link /LIBPATH:../../bin milepost.lib /LIBPATH:../../bin libEGL.dll.lib libGLESv2.dll.lib user32.lib opengl32.lib gdi32.lib shcore.lib /out:../../bin/example_gles_triangle.exe diff --git a/examples/triangleGLES/main.c b/examples/triangleGLES/main.c index 676ac4d..00024c5 100644 --- a/examples/triangleGLES/main.c +++ b/examples/triangleGLES/main.c @@ -1,232 +1,227 @@ -/************************************************************//** -* -* @file: main.cpp -* @author: Martin Fouilleul -* @date: 30/07/2022 -* @revision: -* -*****************************************************************/ -#include -#include - -#define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include - -#include - -#include"milepost.h" - -#define LOG_SUBSYSTEM "Main" - - -mg_surface mg_gles_surface_create_for_window(mp_window window); - -unsigned int program; - -const char* vshaderSource = - //"#version 320 es\n" - "attribute vec4 vPosition;\n" - "uniform mat4 transform;\n" - "void main()\n" - "{\n" - " gl_Position = transform*vPosition;\n" - "}\n"; - -const char* fshaderSource = - //"#version 320 es\n" - "precision mediump float;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" - "}\n"; - -void compile_shader(GLuint shader, const char* source) -{ - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); - - int err = glGetError(); - if(err) - { - printf("gl error: %i\n", err); - } - - int status = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetShaderInfoLog(shader, 256, &size, buffer); - printf("shader error: %.*s\n", size, buffer); - } -} - -int main() -{ - LogLevel(LOG_LEVEL_DEBUG); - - mp_init(); - - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); - - //NOTE: create surface - mg_surface surface = mg_gles_surface_create_for_window(window); - - //NOTE: init shader and gl state - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - GLuint vertexBuffer; - glGenBuffers(1, &vertexBuffer); - - GLfloat vertices[] = { - -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; - - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - - unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); - unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); - program = glCreateProgram(); - - compile_shader(vshader, vshaderSource); - compile_shader(fshader, fshaderSource); - - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); - - int status = 0; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetProgramInfoLog(program, 256, &size, buffer); - printf("link error: %.*s\n", size, buffer); - } - - glUseProgram(program); - - mp_window_bring_to_front(window); -// mp_window_focus(window); - - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event event = {0}; - while(mp_next_event(&event)) - { - switch(event.type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; - - case MP_EVENT_WINDOW_RESIZE: - { - printf("resized, rect = {%f, %f, %f, %f}\n", - event.frame.rect.x, - event.frame.rect.y, - event.frame.rect.w, - event.frame.rect.h); - } break; - - case MP_EVENT_WINDOW_MOVE: - { - printf("moved, rect = {%f, %f, %f, %f}\n", - event.frame.rect.x, - event.frame.rect.y, - event.frame.rect.w, - event.frame.rect.h); - } break; - - case MP_EVENT_MOUSE_MOVE: - { - printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n", - event.move.x, - event.move.y, - event.move.deltaX, - event.move.deltaY); - } break; - - case MP_EVENT_MOUSE_WHEEL: - { - printf("mouse wheel, delta = {%f, %f}\n", - event.move.deltaX, - event.move.deltaY); - } break; - - case MP_EVENT_MOUSE_ENTER: - { - printf("mouse enter\n"); - } break; - - case MP_EVENT_MOUSE_LEAVE: - { - printf("mouse leave\n"); - } break; - - case MP_EVENT_MOUSE_BUTTON: - { - printf("mouse button %i: %i\n", - event.key.code, - event.key.action == MP_KEY_PRESS ? 1 : 0); - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - printf("key %i: %s\n", - event.key.code, - event.key.action == MP_KEY_PRESS ? "press" : (event.key.action == MP_KEY_RELEASE ? "release" : "repeat")); - } break; - - case MP_EVENT_KEYBOARD_CHAR: - { - printf("entered char %s\n", event.character.sequence); - } break; - - default: - break; - } - } - - mg_surface_prepare(surface); - - glClearColor(0.3, 0.3, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - - static float alpha = 0; - //f32 aspect = frameSize.x/frameSize.y; - f32 aspect = 800/(f32)600; - - glViewport(0, 0, 800, 600); - - GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, - -sinf(alpha)/aspect, cosf(alpha), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1}; - - alpha += 2*M_PI/120; - - glUniformMatrix4fv(0, 1, false, matrix); - - - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(0); - - glDrawArrays(GL_TRIANGLES, 0, 3); - - mg_surface_present(surface); - } - - mp_terminate(); - - return(0); -} +/************************************************************//** +* +* @file: main.cpp +* @author: Martin Fouilleul +* @date: 30/07/2022 +* @revision: +* +*****************************************************************/ +#include +#include + +#define _USE_MATH_DEFINES //NOTE: necessary for MSVC +#include + +#include + +#include"milepost.h" + +#define LOG_SUBSYSTEM "Main" + +unsigned int program; + +const char* vshaderSource = + //"#version 320 es\n" + "attribute vec4 vPosition;\n" + "uniform mat4 transform;\n" + "void main()\n" + "{\n" + " gl_Position = transform*vPosition;\n" + "}\n"; + +const char* fshaderSource = + //"#version 320 es\n" + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; + +void compile_shader(GLuint shader, const char* source) +{ + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); + + int err = glGetError(); + if(err) + { + printf("gl error: %i\n", err); + } + + int status = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetShaderInfoLog(shader, 256, &size, buffer); + printf("shader error: %.*s\n", size, buffer); + } +} + +int main() +{ + LogLevel(LOG_LEVEL_DEBUG); + + mp_init(); + + mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; + mp_window window = mp_window_create(rect, "test", 0); + + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_GLES); + + //NOTE: init shader and gl state + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + GLuint vertexBuffer; + glGenBuffers(1, &vertexBuffer); + + GLfloat vertices[] = { + -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; + + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + + unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); + unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); + program = glCreateProgram(); + + compile_shader(vshader, vshaderSource); + compile_shader(fshader, fshaderSource); + + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); + + int status = 0; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetProgramInfoLog(program, 256, &size, buffer); + printf("link error: %.*s\n", size, buffer); + } + + glUseProgram(program); + + mp_window_bring_to_front(window); +// mp_window_focus(window); + + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event event = {0}; + while(mp_next_event(&event)) + { + switch(event.type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } break; + + case MP_EVENT_WINDOW_RESIZE: + { + printf("resized, rect = {%f, %f, %f, %f}\n", + event.frame.rect.x, + event.frame.rect.y, + event.frame.rect.w, + event.frame.rect.h); + } break; + + case MP_EVENT_WINDOW_MOVE: + { + printf("moved, rect = {%f, %f, %f, %f}\n", + event.frame.rect.x, + event.frame.rect.y, + event.frame.rect.w, + event.frame.rect.h); + } break; + + case MP_EVENT_MOUSE_MOVE: + { + printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n", + event.move.x, + event.move.y, + event.move.deltaX, + event.move.deltaY); + } break; + + case MP_EVENT_MOUSE_WHEEL: + { + printf("mouse wheel, delta = {%f, %f}\n", + event.move.deltaX, + event.move.deltaY); + } break; + + case MP_EVENT_MOUSE_ENTER: + { + printf("mouse enter\n"); + } break; + + case MP_EVENT_MOUSE_LEAVE: + { + printf("mouse leave\n"); + } break; + + case MP_EVENT_MOUSE_BUTTON: + { + printf("mouse button %i: %i\n", + event.key.code, + event.key.action == MP_KEY_PRESS ? 1 : 0); + } break; + + case MP_EVENT_KEYBOARD_KEY: + { + printf("key %i: %s\n", + event.key.code, + event.key.action == MP_KEY_PRESS ? "press" : (event.key.action == MP_KEY_RELEASE ? "release" : "repeat")); + } break; + + case MP_EVENT_KEYBOARD_CHAR: + { + printf("entered char %s\n", event.character.sequence); + } break; + + default: + break; + } + } + + mg_surface_prepare(surface); + + glClearColor(0.3, 0.3, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + + static float alpha = 0; + //f32 aspect = frameSize.x/frameSize.y; + f32 aspect = 800/(f32)600; + + GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, + -sinf(alpha)/aspect, cosf(alpha), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1}; + + alpha += 2*M_PI/120; + + glUniformMatrix4fv(0, 1, false, matrix); + + + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + mg_surface_present(surface); + } + + mp_terminate(); + + return(0); +} diff --git a/src/egl_surface.c b/src/egl_surface.c new file mode 100644 index 0000000..ef82c15 --- /dev/null +++ b/src/egl_surface.c @@ -0,0 +1,143 @@ +/************************************************************//** +* +* @file: egl_surface.cpp +* @author: Martin Fouilleul +* @date: 17/02/2023 +* @revision: +* +*****************************************************************/ + +#define EGL_EGLEXT_PROTOTYPES +#include +#include + +#include"graphics_internal.h" +#include"gl_loader.h" + +typedef struct mg_egl_surface +{ + mg_surface_data interface; + + void* nativeSurface; + + EGLDisplay eglDisplay; + EGLConfig eglConfig; + EGLContext eglContext; + EGLSurface eglSurface; + + mg_gl_api api; + +} mg_egl_surface; + +#if OS_MACOS +#include"osx_app.h" + +void* mg_egl_get_native_surface(mp_window_data* window) +{ + return((void*)window->osx.nsView); +} +#elif OS_WIN64 +#include"win32_app.h" + +void* mg_egl_get_native_surface(mp_window_data* window) +{ + return((void*)window->win32.hWnd); +} +#endif + +void mg_egl_surface_destroy(mg_surface_data* interface) +{ + ////////////////////////////////////////////////// + //TODO + ////////////////////////////////////////////////// +} + +void mg_egl_surface_prepare(mg_surface_data* interface) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); + mg_gl_select_api(&surface->api); +} + +void mg_egl_surface_present(mg_surface_data* interface) +{ + mg_egl_surface* surface = (mg_egl_surface*)interface; + eglSwapBuffers(surface->eglDisplay, surface->eglSurface); +} + +/* +mp_rect mg_egl_surface_get_frame(mg_surface_data* interface); +void mg_egl_surface_set_frame(mg_surface_data* interface, mp_rect frame); +void mg_egl_surface_set_hidden(mg_surface_data* interface, bool hidden); +bool mg_egl_surface_get_hidden(mg_surface_data* interface); +*/ + +mg_surface mg_egl_surface_create_for_window(mp_window window) +{ + mg_surface res = mg_surface_nil(); + mp_window_data* windowData = mp_window_ptr_from_handle(window); + if(windowData) + { + mg_egl_surface* surface = malloc_type(mg_egl_surface); + memset(surface, 0, sizeof(mg_egl_surface)); + + surface->interface.backend = MG_BACKEND_GLES; + surface->interface.destroy = mg_egl_surface_destroy; + surface->interface.prepare = mg_egl_surface_prepare; + surface->interface.present = mg_egl_surface_present; + /*TODO + surface->interface.getFrame = mg_egl_surface_get_frame; + surface->interface.setFrame = mg_egl_surface_set_frame; + surface->interface.getHidden = mg_egl_surface_get_hidden; + surface->interface.setHidden = mg_egl_surface_set_hidden; + */ + + surface->nativeSurface = mg_egl_get_native_surface(windowData); + + EGLAttrib displayAttribs[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, + EGL_NONE}; + + surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs); + eglInitialize(surface->eglDisplay, NULL, NULL); + + EGLint const configAttributes[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, 0, + EGL_SAMPLES, EGL_DONT_CARE, + EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, + EGL_NONE }; + + int numConfigs = 0; + eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs); + + EGLint const surfaceAttributes[] = {EGL_NONE}; + surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay, surface->eglConfig, surface->nativeSurface, surfaceAttributes); + + eglBindAPI(EGL_OPENGL_ES_API); + EGLint contextAttributes[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, 3, + EGL_CONTEXT_MINOR_VERSION_KHR, 1, + EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE, + EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE, + EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE, + EGL_NONE}; + + surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes); + eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); + + mg_gl_load_gles32(&surface->api, (mg_gl_load_proc)eglGetProcAddress); + + eglSwapInterval(surface->eglDisplay, 1); + + res = mg_surface_alloc_handle((mg_surface_data*)surface); + } + return(res); +} diff --git a/src/egl_surface.h b/src/egl_surface.h new file mode 100644 index 0000000..a4d57a0 --- /dev/null +++ b/src/egl_surface.h @@ -0,0 +1,17 @@ +/************************************************************//** +* +* @file: egl_surface.h +* @author: Martin Fouilleul +* @date: 28/01/2023 +* @revision: +* +*****************************************************************/ +#ifndef __EGL_SURFACE_H_ +#define __EGL_SURFACE_H_ + +#include"graphics.h" +#include"mp_app.h" + +mg_surface mg_egl_surface_create_for_window(mp_window window); + +#endif // __EGL_SURFACE_H_ diff --git a/src/gl_loader.c b/src/gl_loader.c index 5c49b5e..ccf6fa4 100644 --- a/src/gl_loader.c +++ b/src/gl_loader.c @@ -5,7 +5,7 @@ * @date: 16/022023 * /********************************************************/ -#include"gl_api.h" +#include"gl_loader.h" #include"platform.h" mp_thread_local mg_gl_api* __mgGLAPI = 0; @@ -1719,4 +1719,3 @@ void mg_gl_load_gles32(mg_gl_api* api, mg_gl_load_proc loadProc) } void mg_gl_select_api(mg_gl_api* api){ __mgGLAPI = api; } - diff --git a/src/glsl_shaders.h b/src/glsl_shaders.h index 403a352..cf12adc 100644 --- a/src/glsl_shaders.h +++ b/src/glsl_shaders.h @@ -2,7 +2,7 @@ * * file: glsl_shaders.h * note: string literals auto-generated by embed_text.py -* date: 16/022023 +* date: 17/022023 * **********************************************************************/ #ifndef __GLSL_SHADERS_H__ diff --git a/src/graphics.c b/src/graphics.c index 7f4b623..74c2bce 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -302,6 +302,10 @@ mg_font_data* mg_font_data_from_handle(mg_font font) #endif #endif +#if MG_COMPILE_BACKEND_GLES + #include"egl_surface.h" +#endif + #if MG_COMPILE_BACKEND_METAL #include"mtl_surface.h" #endif @@ -361,6 +365,12 @@ mg_surface mg_surface_create_for_window(mp_window window, mg_backend_id backend) break; #endif + #if MG_COMPILE_BACKEND_GLES + case MG_BACKEND_GLES: + surface = mg_egl_surface_create_for_window(window); + break; + #endif + #if MG_COMPILE_BACKEND_METAL case MG_METAL_BACKEND: surface = mg_mtl_surface_create_for_window(window); diff --git a/src/graphics.h b/src/graphics.h index 2f44f2f..4f1dee8 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -46,6 +46,10 @@ typedef enum { #define MG_COMPILE_BACKEND_GL 1 #endif + #ifndef MG_COMPILE_BACKEND_GLES + #define MG_COMPILE_BACKEND_GLES 1 + #endif + #if MG_COMPILE_BACKEND_GL #define MG_BACKEND_DEFAULT MG_BACKEND_GL #else diff --git a/src/milepost.c b/src/milepost.c index b3cf892..1430f6a 100644 --- a/src/milepost.c +++ b/src/milepost.c @@ -55,10 +55,17 @@ #include"win32_app.c" #include"graphics.c" + #if MG_COMPILE_BACKEND_GL || MG_COMPILE_BACKEND_GLES + #include"gl_loader.c" + #endif + #if MG_COMPILE_BACKEND_GL #include"wgl_surface.c" #include"gl_canvas.c" - #include"gl_loader.c" + #endif + + #if MG_COMPILE_BACKEND_GLES + #include"egl_surface.c" #endif #elif defined(OS_MACOS) diff --git a/src/milepost.h b/src/milepost.h index d995772..5ff356f 100644 --- a/src/milepost.h +++ b/src/milepost.h @@ -39,7 +39,9 @@ #include"graphics.h" #if defined(OS_WIN64) - #include"gl_api.h" + #ifdef MG_INCLUDE_GL_API + #include"gl_api.h" + #endif #endif //#include"ui.h" diff --git a/todo.txt b/todo.txt index 68d5e25..5e128cc 100644 --- a/todo.txt +++ b/todo.txt @@ -7,7 +7,8 @@ Overview [.] Make backend selection easier [x] rename backend-specific files with api prefix (e.g. egl_, nsgl_, wgl_, mtl_, ...) [x] option macros to select surface/canvas backends to compile into milepost lib - [/] option macros to select backend-specific APIs to include when building an app + [.] option macros to select backend-specific APIs to include when building an app + (ie, include gl_api.h when using gl backend) [x] surface/canvas functions that take a backend id [x] feature-detection functions to know what surface/canvas backends are available at run-time [>] write doc about these options @@ -17,12 +18,18 @@ Overview [ ] Baked fonts? [x] Allow different versions of GL/GLES to co-exist -[!] Keep dummy window/dummy context around for gl context creation, and don't reload wgl functions every time +[>] Allow selecting version of GL/GLES context when creating surface + - pass/set attributes when creating surface? + +[/] Keep dummy window/dummy context around for gl context creation, and don't reload wgl functions every time [>] Reintroduce GLES surface +[>] Back surface by child windows and implement moving frame/hiding/overlay +[>] Check that we can make GLES and GL surfaces co-exist in the app + [?] Backport canvas to GLES -[ ] Back surface by child windows and implement moving frame/hiding/overlay + [ ] Delegated drawing API+Impl