diff --git a/CMakeLists.txt b/CMakeLists.txt index 618206b..5b23358 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,28 +45,9 @@ file(GLOB_RECURSE PROJECT_BUILD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp") add_library(BLT_WITH_GRAPHICS ${PROJECT_BUILD_FILES} ${IMGUI_SOURCE_FILES}) -if (EMSCRIPTEN) - #set_target_properties(FinalProject PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file ${CMAKE_SOURCE_DIR}/assets --bind") - #set_target_properties(FinalProject PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file 'assets' --bind") - #set_target_properties(FinalProject PROPERTIES LINK_FLAGS "-sMAX_WEBGL_VERSION=2 -sASSERTIONS=1 -pthread -sPTHREAD_POOL_SIZE=8 -s INITIAL_MEMORY=134217728 -sUSE_GLFW=3 --preload-file 'assets'") - set_target_properties(BLT_WITH_GRAPHICS PROPERTIES LINK_FLAGS "-sMAX_WEBGL_VERSION=2 -sASSERTIONS=1 -pthread -sPTHREAD_POOL_SIZE=8 -s INITIAL_MEMORY=134217728 -sUSE_GLFW=3") - # these flags will be set by cmake automatically based on build type - #set_target_properties(FinalProject PROPERTIES COMPILE_FLAGS "-O3") - set_target_properties(BLT_WITH_GRAPHICS PROPERTIES COMPILE_FLAGS "-pthread") - - target_compile_options(BLT_WITH_GRAPHICS PRIVATE -Wall -Wpedantic -Wno-comment -Wno-strict-aliasing) - target_link_options(BLT_WITH_GRAPHICS PRIVATE -Wall -Wpedantic -Wno-comment -Wno-strict-aliasing) -else () - target_link_libraries(BLT_WITH_GRAPHICS PUBLIC glfw) - - target_compile_options(BLT_WITH_GRAPHICS PRIVATE -Wall -Werror -Wpedantic -Wno-comment -Wno-strict-aliasing) - target_link_options(BLT_WITH_GRAPHICS PRIVATE -Wall -Werror -Wpedantic -Wno-comment -Wno-strict-aliasing) -endif () - target_link_libraries(BLT_WITH_GRAPHICS PUBLIC BLT) target_link_libraries(BLT_WITH_GRAPHICS PUBLIC freetype) - if (${ENABLE_ADDRSAN} MATCHES ON) target_compile_options(BLT_WITH_GRAPHICS PRIVATE -fsanitize=address) target_link_options(BLT_WITH_GRAPHICS PRIVATE -fsanitize=address) @@ -116,4 +97,23 @@ if (${BUILD_GRAPHICS_TESTS}) message("Built graphics tests") endif () -project(BLT) \ No newline at end of file +project(BLT_WITH_GRAPHICS) + +if (EMSCRIPTEN) + list(APPEND TARGETS BLT_WITH_GRAPHICS) + if (${BUILD_GRAPHICS_TESTS}) + list(APPEND TARGETS BLT_GRAPHICS_TESTS) + endif () + #set_target_properties(FinalProject PROPERTIES LINK_FLAGS "-sMAX_WEBGL_VERSION=2 -sASSERTIONS=1 -pthread -sPTHREAD_POOL_SIZE=8 -s INITIAL_MEMORY=134217728 -sUSE_GLFW=3 --preload-file 'assets'") + + set_target_properties(${TARGETS} PROPERTIES LINK_FLAGS "-sMAX_WEBGL_VERSION=2 -sASSERTIONS=1 -sUSE_GLFW=3") + #set_target_properties(BLT_WITH_GRAPHICS PROPERTIES COMPILE_FLAGS "-pthread") + + target_compile_options(BLT_WITH_GRAPHICS PRIVATE -Wall -Wpedantic -Wno-comment -Wno-strict-aliasing) + target_link_options(BLT_WITH_GRAPHICS PRIVATE -Wall -Wpedantic -Wno-comment -Wno-strict-aliasing) +else () + target_link_libraries(BLT_WITH_GRAPHICS PUBLIC glfw) + + target_compile_options(BLT_WITH_GRAPHICS PRIVATE -Wall -Werror -Wpedantic -Wno-comment -Wno-strict-aliasing) + target_link_options(BLT_WITH_GRAPHICS PRIVATE -Wall -Werror -Wpedantic -Wno-comment -Wno-strict-aliasing) +endif () \ No newline at end of file diff --git a/build_emscript.sh b/build_emscript.sh index d323348..f13cb37 100755 --- a/build_emscript.sh +++ b/build_emscript.sh @@ -1,7 +1,8 @@ #!/bin/bash #mkdir cmake-build-emrelease rm -fr cmake-build-emrelease -emcmake cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_GRAPHICS_TESTS:BOOL=ON -S ./ -B ./cmake-build-emrelease +emcmake cmake "-DCMAKE_EXE_LINKER_FLAGS=-s USE_GLFW=3 -s USE_WEBGL2=1" -DCMAKE_BUILD_TYPE=Release -DBUILD_GRAPHICS_TESTS:BOOL=ON -S ./ -B ./cmake-build-emrelease +#emcmake cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_GRAPHICS_TESTS:BOOL=ON -S ./ -B ./cmake-build-emrelease cd cmake-build-emrelease emmake make -j 32 diff --git a/include/blt/gfx/gl_includes.h b/include/blt/gfx/gl_includes.h new file mode 100644 index 0000000..c4619e6 --- /dev/null +++ b/include/blt/gfx/gl_includes.h @@ -0,0 +1,21 @@ +#pragma once +/* + * Created by Brett on 16/12/23. + * Licensed under GNU General Public License V3.0 + * See LICENSE file for license detail + */ + +#ifndef BLT_GL_INCLUDES_H +#define BLT_GL_INCLUDES_H + +// emscripten provides its own gl bindings. +#ifndef __EMSCRIPTEN__ + #include +#else +#include + #include + #define GL_GLEXT_PROTOTYPES + #define EGL_EGLEXT_PROTOTYPES +#endif + +#endif //BLT_GL_INCLUDES_H diff --git a/include/blt/gfx/window.h b/include/blt/gfx/window.h index accbe4d..5137cd4 100644 --- a/include/blt/gfx/window.h +++ b/include/blt/gfx/window.h @@ -8,7 +8,7 @@ #ifndef BLT_WITH_GRAPHICS_TEMPLATE_WINDOW_H #define BLT_WITH_GRAPHICS_TEMPLATE_WINDOW_H -#include +#include #include #include #include diff --git a/src/blt/gfx/glad.cpp b/src/blt/gfx/glad.cpp index 89da0ea..61f4001 100644 --- a/src/blt/gfx/glad.cpp +++ b/src/blt/gfx/glad.cpp @@ -3,5 +3,7 @@ * Licensed under GNU General Public License V3.0 * See LICENSE file for license detail */ +#ifndef __EMSCRIPTEN #define GLAD_GL_IMPLEMENTATION -#include \ No newline at end of file +#include +#endif \ No newline at end of file diff --git a/src/blt/gfx/window.cpp b/src/blt/gfx/window.cpp index b3a9992..cfb4e59 100644 --- a/src/blt/gfx/window.cpp +++ b/src/blt/gfx/window.cpp @@ -96,7 +96,8 @@ namespace blt::gfx // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); (void)io; + ImGuiIO& io = ImGui::GetIO(); + (void) io; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls @@ -113,13 +114,39 @@ namespace blt::gfx #endif } + void loop(void* arg) + { + const auto& data = *((const window_data*) arg); + /* -- Get the current framebuffer size, update the global width/height state, along with OpenGL viewport -- */ + glfwGetFramebufferSize(window_state.window, &window_state.width, &window_state.height); + glViewport(0, 0, window_state.width, window_state.height); + // TODO: user option for this + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + /* -- Begin the next ImGUI frame -- */ + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + /* -- Call user update function -- */ + data.update(window_state.width, window_state.height); + + /* -- Render the ImGUI frame -- */ + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + /* -- Update GLFW state -- */ + glfwSwapBuffers(window_state.window); + glfwPollEvents(); + } + void init(const window_data& data) { - /* -- Setup Error Callback -- */ + /* -- Set up Error Callback -- */ glfwSetErrorCallback(error_callback); BLT_ASSERT(glfwInit() && "Unable to init GLFW. Aborting."); - /* -- Setup Window Context -- */ + /* -- Set up Window Context -- */ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, data.context.GL_MAJOR); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, data.context.GL_MINOR); glfwWindowHint(GLFW_DOUBLEBUFFER, data.context.DOUBLE_BUFFER); @@ -132,42 +159,32 @@ namespace blt::gfx /* -- Set Window Specifics + OpenGL -- */ glfwMakeContextCurrent(window_state.window); glfwSwapInterval(data.sync_interval); +#ifndef __EMSCRIPTEN__ gladLoadGL(glfwGetProcAddress); +#endif - /* -- Setup our local callbacks, ImGUI will then call these -- */ + /* -- Set up our local callbacks, ImGUI will then call these -- */ create_callbacks(); - /* -- Setup ImGUI -- */ + /* -- Set up ImGUI -- */ setup_ImGUI(); /* -- Call User Provided post-window-init function -- */ data.init(); - + +#ifdef __EMSCRIPTEN__ + /* + * "setting 0 or a negative value as the fps will use the browser’s requestAnimationFrame mechanism to call the main loop function. + * This is HIGHLY recommended if you are doing rendering, as the browser’s requestAnimationFrame will + * make sure you render at a proper smooth rate that lines up properly with the browser and monitor." + * https://emscripten.org/docs/api_reference/emscripten.h.html + */ + emscripten_set_main_loop_arg(loop, (void*)&data, 0, true); +#else /* -- General Loop -- */ while (!glfwWindowShouldClose(window_state.window)) - { - /* -- Get the current framebuffer size, update the global width/height state, along with OpenGL viewport -- */ - glfwGetFramebufferSize(window_state.window, &window_state.width, &window_state.height); - glViewport(0, 0, window_state.width, window_state.height); - // TODO: user option for this - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - /* -- Begin the next ImGUI frame -- */ - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); - - /* -- Call user update function -- */ - data.update(window_state.width, window_state.height); - - /* -- Render the ImGUI frame -- */ - ImGui::Render(); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - - /* -- Update GLFW state -- */ - glfwSwapBuffers(window_state.window); - glfwPollEvents(); - } + loop((void*)&data); +#endif } void cleanup()