meta: build system for Dear ImGui + GL3W + FreeType2
* Add build instructions for Dear ImGui that build the SDL + OpenGL 3 / OpenGL ES 2 backend. * Use Dear ImGui's bundled GL3W as a loader (including in azur itself, which has not been using a loader until now). * Properly select headers for OpenGL ES 2.0 (with the VAO extension) and attributes for WebGL; clear up OpenGL 4 error codes. * If FreeType2 is available through pkg-config, or if empscripten is used (since it has a FreeType port), use FreeType to render fonts in Dear ImGui for much-appreciated hinting quality. Minor changes: * Add window title to azur_init(). * Use emscripten's infinite loop simulation to make sure everything stays in the same thread. This is needed for Dear ImGui to work.
This commit is contained in:
parent
bd081b03a2
commit
31da1c0998
|
@ -45,6 +45,7 @@ if(FACETS_PLATFORM STREQUAL linux)
|
|||
pkg_check_modules(sdl2 REQUIRED sdl2 IMPORTED_TARGET)
|
||||
pkg_check_modules(sdl2_image REQUIRED SDL2_image IMPORTED_TARGET)
|
||||
pkg_check_modules(opengl REQUIRED opengl IMPORTED_TARGET)
|
||||
pkg_check_modules(glx REQUIRED glx IMPORTED_TARGET)
|
||||
|
||||
link_libraries(PkgConfig::sdl2_image PkgConfig::sdl2 PkgConfig::opengl -lm)
|
||||
endif()
|
||||
|
@ -64,4 +65,9 @@ endif()
|
|||
|
||||
#---
|
||||
|
||||
# This provides Dear ImGui but also GL3W as an OpenGL loader
|
||||
if(NOT FACETS_PLATFORM STREQUAL gint)
|
||||
add_subdirectory(imgui-builds)
|
||||
endif()
|
||||
|
||||
add_subdirectory(azur)
|
||||
|
|
|
@ -47,6 +47,11 @@ if(AZUR_PLATFORM_EMSCRIPTEN)
|
|||
set_target_properties(azur PROPERTIES LINK_DEPENDS "${ASSETS_ABSOLUTE}")
|
||||
endif()
|
||||
|
||||
# Use ImGui's integrated GL3W loader (which we build separately)
|
||||
if(AZUR_GRAPHICS_OPENGL_3_3)
|
||||
target_link_libraries(azur PUBLIC gl3w)
|
||||
endif()
|
||||
|
||||
target_include_directories(azur
|
||||
PUBLIC "${PROJECT_SOURCE_DIR}/include"
|
||||
PUBLIC "${PROJECT_BINARY_DIR}/include"
|
||||
|
|
|
@ -14,7 +14,7 @@ AZUR_BEGIN_DECLS
|
|||
|
||||
On GINT_CG, the window size is fixed to 396x224 and ignored.
|
||||
TODO: On GINT_CG, accept super-resolution in azur_init(). */
|
||||
int azur_init(int window_width, int window_height);
|
||||
int azur_init(char const *title, int window_width, int window_height);
|
||||
|
||||
/* azur_main_loop(): Run the update/render loop.
|
||||
|
||||
|
|
|
@ -6,9 +6,19 @@
|
|||
#include <azur/defs.h>
|
||||
AZUR_BEGIN_DECLS
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <SDL2/SDL_opengl.h>
|
||||
#include <SDL2/SDL_opengl_glext.h>
|
||||
#ifdef AZUR_GRAPHICS_OPENGL_3_3
|
||||
# include "GL/gl3w.h"
|
||||
# include <SDL2/SDL_opengl.h>
|
||||
#endif /* OpenGL 3.3 */
|
||||
|
||||
#ifdef AZUR_GRAPHICS_OPENGL_ES_2_0
|
||||
# define GL_GLEXT_PROTOTYPES
|
||||
# include <SDL2/SDL_opengles2.h>
|
||||
|
||||
# define glGenVertexArrays glGenVertexArraysOES
|
||||
# define glBindVertexArray glBindVertexArrayOES
|
||||
# define glDeleteVertexArrays glDeleteVertexArraysOES
|
||||
#endif /* OpenGL ES 2.0 */
|
||||
|
||||
/* azgl_error(): String description of a GLenum error code.
|
||||
The returned pointer might be a static buffer modified by further calls. */
|
||||
|
|
|
@ -10,7 +10,7 @@ static SDL_GLContext glcontext = NULL;
|
|||
|
||||
static void main_loop_quit(void);
|
||||
|
||||
int azur_init(int window_width, int window_height)
|
||||
int azur_init(char const *title, int window_width, int window_height)
|
||||
{
|
||||
int rc = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
|
||||
if(rc < 0) {
|
||||
|
@ -24,16 +24,24 @@ int azur_init(int window_width, int window_height)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Select OpenGL 3.3 core, but not on the OpenGL ES/emscripten backend,
|
||||
which does not support context attributes. */
|
||||
/* Select OpenGL 3.3 core */
|
||||
#ifdef AZUR_GRAPHICS_OPENGL_3_3
|
||||
SDL_GL_SetAttribute(
|
||||
SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
|
||||
SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindow("facets-floating",
|
||||
/* ... or select Open GL ES 2.0 */
|
||||
#ifdef AZUR_GRAPHICS_OPENGL_ES_2_0
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindow(title,
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
window_width, window_height,
|
||||
SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
|
||||
|
@ -47,11 +55,21 @@ int azur_init(int window_width, int window_height)
|
|||
azlog(FATAL, "SDL_GL_CreateContext: %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
SDL_GL_MakeCurrent(window, glcontext);
|
||||
|
||||
rc = SDL_GL_SetSwapInterval(0);
|
||||
if(rc < 0)
|
||||
azlog(ERROR, "SDL_GL_SetSwapInterval: %s\n", SDL_GetError());
|
||||
|
||||
#ifdef AZUR_GRAPHICS_OPENGL_3_3
|
||||
rc = gl3wInit();
|
||||
if(rc != 0) {
|
||||
azlog(FATAL, "gl3wInit: %d\n", rc);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
|
@ -100,14 +118,18 @@ struct params {
|
|||
bool tied, started;
|
||||
};
|
||||
|
||||
static void nop(void)
|
||||
{
|
||||
}
|
||||
|
||||
static EM_BOOL frame(double time, void *data)
|
||||
{
|
||||
struct params *params = data;
|
||||
|
||||
if(params->tied && params->started)
|
||||
params->update();
|
||||
if(params->update) params->update();
|
||||
|
||||
params->render();
|
||||
if(params->render) params->render();
|
||||
params->started = true;
|
||||
|
||||
return EM_TRUE;
|
||||
|
@ -129,7 +151,13 @@ int azur_main_loop(
|
|||
|
||||
if(!(flags & AZUR_MAIN_LOOP_TIED)) {
|
||||
void (*update_v)(void) = (void *)update;
|
||||
emscripten_set_main_loop(update_v, update_ups, false);
|
||||
emscripten_set_main_loop(update_v, update_ups, true);
|
||||
}
|
||||
else {
|
||||
/* Even if no update is requested, we want emscripten to simulate an
|
||||
infinite loop, as it is needed for Dear ImGui to work due to
|
||||
threading considerations */
|
||||
emscripten_set_main_loop(nop, 1, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -193,7 +221,7 @@ int azur_main_loop(
|
|||
while(1) {
|
||||
if(update_tick && !(flags & AZUR_MAIN_LOOP_TIED)) {
|
||||
update_tick = 0;
|
||||
if(update()) break;
|
||||
if(update && update()) break;
|
||||
}
|
||||
|
||||
/* When vsync is enabled, render() is indirectly blocking so we just
|
||||
|
@ -203,9 +231,9 @@ int azur_main_loop(
|
|||
|
||||
/* Tied renders and updates */
|
||||
if(started && (flags & AZUR_MAIN_LOOP_TIED)) {
|
||||
if(update()) break;
|
||||
if(update && update()) break;
|
||||
}
|
||||
render();
|
||||
if(render) render();
|
||||
started = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,10 +45,6 @@ char const *azgl_error(GLenum ec)
|
|||
return "Invalid value";
|
||||
case GL_INVALID_OPERATION:
|
||||
return "Invalid operation";
|
||||
case GL_STACK_OVERFLOW:
|
||||
return "Stack overflow";
|
||||
case GL_STACK_UNDERFLOW:
|
||||
return "Stack underflow";
|
||||
case GL_OUT_OF_MEMORY:
|
||||
return "Out of memory";
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
# The GL3W library which is generated along in Dear ImGui
|
||||
if(AZUR_GRAPHICS_OPENGL_3_3)
|
||||
add_library(gl3w
|
||||
../imgui/examples/libs/gl3w/GL/gl3w.c)
|
||||
target_include_directories(gl3w PUBLIC
|
||||
../imgui/examples/libs/gl3w)
|
||||
# Link with GLX for GL3X to find the extensions, and -ldl
|
||||
target_link_libraries(gl3w INTERFACE PkgConfig::glx -ldl)
|
||||
endif()
|
||||
|
||||
# The Dear ImGui library for SDL + OpenGL3/OpenGLES2
|
||||
set(SOURCES
|
||||
../imgui/imgui.cpp
|
||||
../imgui/imgui_demo.cpp
|
||||
../imgui/imgui_draw.cpp
|
||||
../imgui/imgui_tables.cpp
|
||||
../imgui/imgui_widgets.cpp
|
||||
../imgui/backends/imgui_impl_opengl3.cpp
|
||||
../imgui/backends/imgui_impl_sdl.cpp)
|
||||
|
||||
# Use Freetype if the library is installed, or the emscripten port
|
||||
if(AZUR_PLATFORM_EMSCRIPTEN)
|
||||
list(APPEND SOURCES ../imgui/misc/freetype/imgui_freetype.cpp)
|
||||
else()
|
||||
pkg_check_modules(freetype2 freetype2 IMPORTED_TARGET)
|
||||
if(freetype2_FOUND)
|
||||
list(APPEND SOURCES ../imgui/misc/freetype/imgui_freetype.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(imgui ${SOURCES})
|
||||
|
||||
# Try to reduce the size of the binary code by including individual functions
|
||||
# from the archive, instead of whole files
|
||||
target_compile_options(imgui PRIVATE -ffunction-sections)
|
||||
target_compile_options(imgui INTERFACE -Wl,--gc-sections)
|
||||
|
||||
# Use the pre-built GL3W loader on desktop
|
||||
if(AZUR_GRAPHICS_OPENGL_3_3)
|
||||
target_compile_definitions(imgui PUBLIC
|
||||
-DIMGUI_IMPL_OPENGL_LOADER_GL3W="GL/gl3w.h")
|
||||
target_link_libraries(imgui PUBLIC gl3w)
|
||||
# Use the autonomous GLES 2.0 loader otherwise
|
||||
elseif(AZUR_GRAPHICS_OPENGL_ES_2_0)
|
||||
target_compile_definitions(imgui PUBLIC
|
||||
-DIMGUI_IMPL_OPENGL_ES2)
|
||||
endif()
|
||||
|
||||
# FreeType2 settings
|
||||
if(freetype2_FOUND)
|
||||
target_compile_definitions(imgui PUBLIC -DIMGUI_ENABLE_FREETYPE)
|
||||
target_include_directories(imgui PRIVATE ../imgui/misc/freetype)
|
||||
target_link_libraries(imgui PUBLIC PkgConfig::freetype2)
|
||||
elseif(AZUR_PLATFORM_EMSCRIPTEN)
|
||||
target_compile_definitions(imgui PUBLIC -DIMGUI_ENABLE_FREETYPE)
|
||||
target_include_directories(imgui PRIVATE ../imgui/misc/freetype)
|
||||
target_compile_options(imgui PUBLIC -sUSE_FREETYPE=2)
|
||||
target_link_options(imgui INTERFACE -sUSE_FREETYPE=2)
|
||||
endif()
|
||||
|
||||
# Provide include directories
|
||||
target_include_directories(imgui PUBLIC ../imgui ../imgui/backends)
|
Loading…
Reference in New Issue