diff --git a/src/experimental/filament/CMakeLists.txt b/src/experimental/filament/CMakeLists.txt index 99854dfc..17ebec93 100644 --- a/src/experimental/filament/CMakeLists.txt +++ b/src/experimental/filament/CMakeLists.txt @@ -21,7 +21,7 @@ target_compile_definitions(${MUJOCO_FILAMENT_TARGET_NAME} PRIVATE MJ_STATIC) target_sources(${MUJOCO_FILAMENT_TARGET_NAME} PUBLIC - stubs.cc + mjr_compat.cc render_context_filament.h render_context_filament.cc filament/buffer_util.cc diff --git a/src/experimental/filament/stubs.cc b/src/experimental/filament/mjr_compat.cc similarity index 65% rename from src/experimental/filament/stubs.cc rename to src/experimental/filament/mjr_compat.cc index 9d2d099c..9d06dea6 100644 --- a/src/experimental/filament/stubs.cc +++ b/src/experimental/filament/mjr_compat.cc @@ -13,9 +13,50 @@ // limitations under the License. #include +#include "experimental/filament/render_context_filament.h" + +// This library implements the entirety of mujoco's mjr API. You can link this +// library with your application (instead of the "classic" mujoco renderer) to +// use the same APIs but with Filament rendering instead. +// +// However, you should consider using filament's mjrf API directly as it will +// provide you with access to more features and optimizations. extern "C" { +// mjr functions that are supported by the filament renderer. + +void mjr_defaultContext(mjrContext* con) { + mjrf_defaultContext(con); +} +void mjr_makeContext(const mjModel* m, mjrContext* con, int fontscale) { + mjrf_makeContext(m, con, fontscale); +} +void mjr_freeContext(mjrContext* con) { + mjrf_freeContext(con); +} +void mjr_render(mjrRect viewport, mjvScene* scn, const mjrContext* con) { + mjrf_render(viewport, scn, con); +} +void mjr_uploadMesh(const mjModel* m, const mjrContext* con, int meshid) { + mjrf_uploadMesh(m, con, meshid); +} +void mjr_uploadTexture(const mjModel* m, const mjrContext* con, int texid) { + mjrf_uploadTexture(m, con, texid); +} +void mjr_uploadHField(const mjModel* m, const mjrContext* con, int hfieldid) { + mjrf_uploadHField(m, con, hfieldid); +} +void mjr_setBuffer(int framebuffer, mjrContext* con) { + mjrf_setBuffer(framebuffer, con); +} +void mjr_readPixels(unsigned char* rgb, float* depth, mjrRect viewport, + const mjrContext* con) { + mjrf_readPixels(rgb, depth, viewport, con); +} + +// mjr functions that are NOT supported by the filament renderer. + void mjr_setAux(int index, const mjrContext* con) { mju_error("mjr_setAux not implemented."); } diff --git a/src/experimental/filament/render_context_filament.cc b/src/experimental/filament/render_context_filament.cc index 4695599f..3955a816 100644 --- a/src/experimental/filament/render_context_filament.cc +++ b/src/experimental/filament/render_context_filament.cc @@ -32,17 +32,17 @@ static mujoco::FilamentContext* g_filament_context = nullptr; static void CheckFilamentContext() { if (g_filament_context == nullptr) { - mju_error("Missing context; did you call mjr_makeFilamentContext?"); + mju_error("Missing context; did you call mjrf_makeFilamentContext?"); } } extern "C" { -void mjr_defaultFilamentConfig(mjrFilamentConfig* config) { +void mjrf_defaultFilamentConfig(mjrFilamentConfig* config) { memset(config, 0, sizeof(mjrFilamentConfig)); } -void mjr_makeFilamentContext(const mjModel* m, mjrContext* con, +void mjrf_makeFilamentContext(const mjModel* m, mjrContext* con, const mjrFilamentConfig* config) { // TODO: Support multiple contexts and multiple threads. For now, we'll just // assume a single, global context. @@ -52,16 +52,18 @@ void mjr_makeFilamentContext(const mjModel* m, mjrContext* con, g_filament_context = new mujoco::FilamentContext(config, m, con); } -void mjr_defaultContext(mjrContext* con) { memset(con, 0, sizeof(mjrContext)); } - -void mjr_makeContext(const mjModel* m, mjrContext* con, int fontscale) { - mjr_freeContext(con); - mjrFilamentConfig cfg; - mjr_defaultFilamentConfig(&cfg); - mjr_makeFilamentContext(m, con, &cfg); +void mjrf_defaultContext(mjrContext* con) { + memset(con, 0, sizeof(mjrContext)); } -void mjr_freeContext(mjrContext* con) { +void mjrf_makeContext(const mjModel* m, mjrContext* con, int fontscale) { + mjr_freeContext(con); + mjrFilamentConfig cfg; + mjrf_defaultFilamentConfig(&cfg); + mjrf_makeFilamentContext(m, con, &cfg); +} + +void mjrf_freeContext(mjrContext* con) { // mjr_freeContext may be called multiple times. if (g_filament_context) { delete g_filament_context; @@ -70,50 +72,50 @@ void mjr_freeContext(mjrContext* con) { mjr_defaultContext(con); } -void mjr_render(mjrRect viewport, mjvScene* scn, const mjrContext* con) { +void mjrf_render(mjrRect viewport, mjvScene* scn, const mjrContext* con) { CheckFilamentContext(); g_filament_context->Render(viewport, scn, con); } -void mjr_uploadMesh(const mjModel* m, const mjrContext* con, int meshid) { +void mjrf_uploadMesh(const mjModel* m, const mjrContext* con, int meshid) { CheckFilamentContext(); g_filament_context->UploadMesh(m, meshid); } -void mjr_uploadTexture(const mjModel* m, const mjrContext* con, int texid) { +void mjrf_uploadTexture(const mjModel* m, const mjrContext* con, int texid) { CheckFilamentContext(); g_filament_context->UploadTexture(m, texid); } -void mjr_uploadHField(const mjModel* m, const mjrContext* con, int hfieldid) { +void mjrf_uploadHField(const mjModel* m, const mjrContext* con, int hfieldid) { CheckFilamentContext(); g_filament_context->UploadHeightField(m, hfieldid); } -void mjr_setBuffer(int framebuffer, mjrContext* con) { +void mjrf_setBuffer(int framebuffer, mjrContext* con) { CheckFilamentContext(); g_filament_context->SetFrameBuffer(framebuffer); } -void mjr_readPixels(unsigned char* rgb, float* depth, mjrRect viewport, +void mjrf_readPixels(unsigned char* rgb, float* depth, mjrRect viewport, const mjrContext* con) { CheckFilamentContext(); g_filament_context->ReadPixels(viewport, rgb, depth); } -uintptr_t mjr_uploadGuiImage(uintptr_t tex_id, const unsigned char* pixels, +uintptr_t mjrf_uploadGuiImage(uintptr_t tex_id, const unsigned char* pixels, int width, int height, int bpp, const mjrContext* con) { CheckFilamentContext(); return g_filament_context->UploadGuiImage(tex_id, pixels, width, height, bpp); } -double mjr_getFrameRate(const mjrContext* con) { +double mjrf_getFrameRate(const mjrContext* con) { CheckFilamentContext(); return g_filament_context->GetFrameRate(); } -void mjr_updateGui(const mjrContext* con) { +void mjrf_updateGui(const mjrContext* con) { if (g_filament_context != nullptr) { g_filament_context->UpdateGui(); } diff --git a/src/experimental/filament/render_context_filament.h b/src/experimental/filament/render_context_filament.h index c0423e4a..aef8f182 100644 --- a/src/experimental/filament/render_context_filament.h +++ b/src/experimental/filament/render_context_filament.h @@ -26,6 +26,9 @@ extern "C" { #endif +// IMPORTANT: This API should still be considered experimental and is likely +// change frequently. + typedef enum mjtGraphicsApi_ { // backend graphics API to use mjGFX_DEFAULT = 0, // default based on platform mjGFX_OPENGL, // OpenGL (desktop) @@ -43,35 +46,37 @@ struct mjrFilamentConfig { bool enable_gui; }; -void mjr_defaultFilamentConfig(mjrFilamentConfig* config); +void mjrf_defaultFilamentConfig(mjrFilamentConfig* config); -void mjr_makeFilamentContext(const mjModel* m, mjrContext* con, - const mjrFilamentConfig* config); +void mjrf_makeFilamentContext(const mjModel* m, mjrContext* con, + const mjrFilamentConfig* config); -MJAPI void mjr_defaultContext(mjrContext* con); +void mjrf_defaultContext(mjrContext* con); -MJAPI void mjr_makeContext(const mjModel* m, mjrContext* con, int fontscale); +void mjrf_makeContext(const mjModel* m, mjrContext* con, int fontscale); -MJAPI void mjr_freeContext(mjrContext* con); +void mjrf_freeContext(mjrContext* con); -MJAPI void mjr_render(mjrRect viewport, mjvScene* scn, const mjrContext* con); +void mjrf_render(mjrRect viewport, mjvScene* scn, const mjrContext* con); -MJAPI void mjr_uploadMesh(const mjModel* m, const mjrContext* con, int meshid); +void mjrf_uploadMesh(const mjModel* m, const mjrContext* con, int meshid); -MJAPI void mjr_uploadTexture(const mjModel* m, const mjrContext* con, int texid); +void mjrf_uploadTexture(const mjModel* m, const mjrContext* con, int texid); -MJAPI void mjr_setBuffer(int framebuffer, mjrContext* con); +void mjrf_uploadHField(const mjModel* m, const mjrContext* con, int hfieldid); -MJAPI void mjr_readPixels(unsigned char* rgb, float* depth, mjrRect viewport, - const mjrContext* con); +void mjrf_setBuffer(int framebuffer, mjrContext* con); -double mjr_getFrameRate(const mjrContext* con); +void mjrf_readPixels(unsigned char* rgb, float* depth, mjrRect viewport, + const mjrContext* con); -uintptr_t mjr_uploadGuiImage(uintptr_t tex_id, const unsigned char* pixels, - int width, int height, int bpp, - const mjrContext* con); +double mjrf_getFrameRate(const mjrContext* con); -void mjr_updateGui(const mjrContext* con); +uintptr_t mjrf_uploadGuiImage(uintptr_t tex_id, const unsigned char* pixels, + int width, int height, int bpp, + const mjrContext* con); + +void mjrf_updateGui(const mjrContext* con); #if defined(__cplusplus) } // extern "C" diff --git a/src/experimental/platform/renderer.cc b/src/experimental/platform/renderer.cc index 6fe16730..2188d86f 100644 --- a/src/experimental/platform/renderer.cc +++ b/src/experimental/platform/renderer.cc @@ -56,7 +56,7 @@ void Renderer::Init(const mjModel* model) { mjr_makeContext(model, &render_context_, mjFONTSCALE_150); #else mjrFilamentConfig render_config; - mjr_defaultFilamentConfig(&render_config); + mjrf_defaultFilamentConfig(&render_config); render_config.native_window = native_window_; render_config.enable_gui = true; #if defined(MUJOCO_RENDERER_FILAMENT_OPENGL) @@ -66,7 +66,7 @@ void Renderer::Init(const mjModel* model) { #elif defined(MUJOCO_RENDERER_FILAMENT_VULKAN) render_config.graphics_api = mjGFX_VULKAN; #endif - mjr_makeFilamentContext(model, &render_context_, &render_config); + mjrf_makeFilamentContext(model, &render_context_, &render_config); #endif mjv_defaultScene(&scene_); @@ -171,9 +171,9 @@ int Renderer::UploadImage(int texture_id, const std::byte* pixels, int width, #if defined(MUJOCO_RENDERER_CLASSIC_OPENGL) return 0; #else - return mjr_uploadGuiImage(texture_id, - reinterpret_cast(pixels), - width, height, bpp, &render_context_); + return mjrf_uploadGuiImage(texture_id, + reinterpret_cast(pixels), + width, height, bpp, &render_context_); #endif } @@ -191,7 +191,7 @@ void Renderer::UpdateFps() { frames_ = 0; } #else - fps_ = mjr_getFrameRate(&render_context_); + fps_ = mjrf_getFrameRate(&render_context_); #endif } @@ -217,7 +217,7 @@ mjPLUGIN_LIB_INIT { mujoco::platform::GuiPlugin plugin; plugin.name = "Filament"; plugin.update = [](mujoco::platform::GuiPlugin* self) { - mjr_updateGui(nullptr); + mjrf_updateGui(nullptr); }; mujoco::platform::RegisterPlugin(plugin); }