Merge pull request #3340 from devshahofficial:devshahofficial/mjr-renderer-info
PiperOrigin-RevId: 948183711 Change-Id: I28b256eca22e86ec0ba05a4fa26458d678aca130
This commit is contained in:
@@ -1286,6 +1286,16 @@ This structure specifies the attributes for a single vertex.
|
||||
|
||||
|
||||
|
||||
.. _mjrRendererInfo:
|
||||
|
||||
mjrRendererInfo
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
This structure contains information about the available renderer and its current context.
|
||||
|
||||
.. mujoco-include:: mjrRendererInfo
|
||||
|
||||
|
||||
.. _mjrContext:
|
||||
|
||||
mjrContext
|
||||
|
||||
@@ -2797,6 +2797,24 @@ of how to use these functions.
|
||||
|
||||
Set default mjrContext.
|
||||
|
||||
.. _mjr_defaultRendererInfo:
|
||||
|
||||
`mjr_defaultRendererInfo <#mjr_defaultRendererInfo>`__
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mjr_defaultRendererInfo
|
||||
|
||||
Set default mjrRendererInfo.
|
||||
|
||||
.. _mjr_getRendererInfo:
|
||||
|
||||
`mjr_getRendererInfo <#mjr_getRendererInfo>`__
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. mujoco-include:: mjr_getRendererInfo
|
||||
|
||||
Get active renderer information.
|
||||
|
||||
.. _mjr_makeContext:
|
||||
|
||||
`mjr_makeContext <#mjr_makeContext>`__
|
||||
|
||||
@@ -1378,6 +1378,10 @@ typedef struct mjrRect_ { // OpenGL rectangle
|
||||
int width; // width (usually buffer width)
|
||||
int height; // height (usually buffer height)
|
||||
} mjrRect;
|
||||
typedef struct mjrRendererInfo_ { // active renderer identity
|
||||
const char* renderer; // renderer family: classic, filament, noop
|
||||
const char* backend; // graphics backend: opengl, vulkan; empty if uninitialized
|
||||
} mjrRendererInfo;
|
||||
typedef struct mjrVertexAttribute_ { // vertex attribute format specification
|
||||
const void* bytes; // vertex data
|
||||
int usage; // position, normal, etc [mjrVertexAttributeUsage]
|
||||
@@ -3471,6 +3475,8 @@ void mjv_cameraFrame(mjtNum headpos[3], mjtNum forward[3], mjtNum up[3], mjtNum
|
||||
void mjv_cameraFrustum(float zver[2], float zhor[2], float zclip[2], const mjModel* m,
|
||||
const mjvCamera* cam);
|
||||
void mjr_defaultContext(mjrContext* con);
|
||||
void mjr_defaultRendererInfo(mjrRendererInfo* info);
|
||||
void mjr_getRendererInfo(mjrRendererInfo* info);
|
||||
void mjr_makeContext(const mjModel* m, mjrContext* con, int fontscale);
|
||||
void mjr_changeFont(int fontscale, mjrContext* con);
|
||||
void mjr_addAux(int index, int width, int height, int samples, mjrContext* con);
|
||||
|
||||
@@ -117,6 +117,12 @@ typedef struct mjrRect_ { // OpenGL rectangle
|
||||
} mjrRect;
|
||||
|
||||
|
||||
typedef struct mjrRendererInfo_ { // active renderer identity
|
||||
const char* renderer; // renderer family: classic, filament, noop
|
||||
const char* backend; // graphics backend: opengl, vulkan; empty if uninitialized
|
||||
} mjrRendererInfo;
|
||||
|
||||
|
||||
typedef struct mjrVertexAttribute_ { // vertex attribute format specification
|
||||
const void* bytes; // vertex data
|
||||
int usage; // position, normal, etc [mjrVertexAttributeUsage]
|
||||
|
||||
@@ -104,6 +104,9 @@ mjrfContext* mjrf_createContext(const mjrfContextConfig* config);
|
||||
// Destroys the filament rendering context.
|
||||
void mjrf_destroyContext(mjrfContext* ctx);
|
||||
|
||||
// Gets active renderer information for the given filament context.
|
||||
void mjrf_getRendererInfo(mjrfContext* ctx, mjrRendererInfo* info);
|
||||
|
||||
typedef enum mjrDrawMode_ { // how to draw objects in the scene
|
||||
mjDRAW_MODE_DEFAULT, // default colors and lighting
|
||||
mjDRAW_MODE_DEFAULT_NO_TEXTURES, // default, but without textures
|
||||
|
||||
@@ -855,6 +855,12 @@ MJAPI void mjv_cameraFrustum(float zver[2], float zhor[2], float zclip[2], cons
|
||||
// Set default mjrContext.
|
||||
MJAPI void mjr_defaultContext(mjrContext* con);
|
||||
|
||||
// Set default mjrRendererInfo.
|
||||
MJAPI void mjr_defaultRendererInfo(mjrRendererInfo* info);
|
||||
|
||||
// Get active renderer information.
|
||||
MJAPI void mjr_getRendererInfo(mjrRendererInfo* info);
|
||||
|
||||
// Allocate resources in custom OpenGL context; fontscale is mjtFontScale.
|
||||
MJAPI void mjr_makeContext(const mjModel* m, mjrContext* con, int fontscale);
|
||||
|
||||
|
||||
@@ -5480,6 +5480,34 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
||||
),
|
||||
doc='Set default mjrContext.',
|
||||
)),
|
||||
('mjr_defaultRendererInfo',
|
||||
FunctionDecl(
|
||||
name='mjr_defaultRendererInfo',
|
||||
return_type=ValueType(name='void'),
|
||||
parameters=(
|
||||
FunctionParameterDecl(
|
||||
name='info',
|
||||
type=PointerType(
|
||||
inner_type=ValueType(name='mjrRendererInfo'),
|
||||
),
|
||||
),
|
||||
),
|
||||
doc='Set default mjrRendererInfo.',
|
||||
)),
|
||||
('mjr_getRendererInfo',
|
||||
FunctionDecl(
|
||||
name='mjr_getRendererInfo',
|
||||
return_type=ValueType(name='void'),
|
||||
parameters=(
|
||||
FunctionParameterDecl(
|
||||
name='info',
|
||||
type=PointerType(
|
||||
inner_type=ValueType(name='mjrRendererInfo'),
|
||||
),
|
||||
),
|
||||
),
|
||||
doc='Get active renderer information.',
|
||||
)),
|
||||
('mjr_makeContext',
|
||||
FunctionDecl(
|
||||
name='mjr_makeContext',
|
||||
|
||||
@@ -11005,6 +11005,27 @@ STRUCTS: Mapping[str, StructDecl] = dict([
|
||||
),
|
||||
),
|
||||
)),
|
||||
('mjrRendererInfo',
|
||||
StructDecl(
|
||||
name='mjrRendererInfo',
|
||||
declname='struct mjrRendererInfo_',
|
||||
fields=(
|
||||
StructFieldDecl(
|
||||
name='renderer',
|
||||
type=PointerType(
|
||||
inner_type=ValueType(name='char', is_const=True),
|
||||
),
|
||||
doc='renderer family: classic, filament, noop',
|
||||
),
|
||||
StructFieldDecl(
|
||||
name='backend',
|
||||
type=PointerType(
|
||||
inner_type=ValueType(name='char', is_const=True),
|
||||
),
|
||||
doc='graphics backend: opengl, vulkan; empty if uninitialized',
|
||||
),
|
||||
),
|
||||
)),
|
||||
('mjrVertexAttribute',
|
||||
StructDecl(
|
||||
name='mjrVertexAttribute',
|
||||
|
||||
@@ -79,6 +79,7 @@ using MjLogMessage = ::mjLogMessage;
|
||||
|
||||
// From mjrender.h
|
||||
using MjrRect = ::mjrRect;
|
||||
using MjrRendererInfo = ::mjrRendererInfo;
|
||||
using MjrContext = ::mjrContext;
|
||||
using MjrVertexAttribute = ::mjrVertexAttribute;
|
||||
|
||||
|
||||
+28
-1
@@ -143,7 +143,6 @@ void MjrContextWrapper::Free() {
|
||||
// mjr_freeContext is safe to call multiple times.
|
||||
InterceptMjErrors(mjr_freeContext)(ptr_);
|
||||
}
|
||||
|
||||
} // namespace _impl
|
||||
|
||||
namespace {
|
||||
@@ -241,10 +240,38 @@ PYBIND11_MODULE(_render, pymodule, pybind11::mod_gil_not_used()) {
|
||||
X(charWidthBig);
|
||||
#undef X
|
||||
|
||||
// ==================== MJRRENDERERINFO ======================================
|
||||
py::class_<raw::MjrRendererInfo> mjrRendererInfo(pymodule, "MjrRendererInfo");
|
||||
mjrRendererInfo.def(py::init([]() {
|
||||
raw::MjrRendererInfo info;
|
||||
mjr_defaultRendererInfo(&info);
|
||||
return info;
|
||||
}));
|
||||
mjrRendererInfo.def("__copy__", [](const raw::MjrRendererInfo& other) {
|
||||
return raw::MjrRendererInfo(other);
|
||||
});
|
||||
mjrRendererInfo.def("__deepcopy__",
|
||||
[](const raw::MjrRendererInfo& other, py::dict) {
|
||||
return raw::MjrRendererInfo(other);
|
||||
});
|
||||
DefineStructFunctions(mjrRendererInfo);
|
||||
mjrRendererInfo.def_property_readonly("renderer",
|
||||
[](const raw::MjrRendererInfo& info) {
|
||||
return info.renderer ? info.renderer
|
||||
: "";
|
||||
});
|
||||
mjrRendererInfo.def_property_readonly("backend",
|
||||
[](const raw::MjrRendererInfo& info) {
|
||||
return info.backend ? info.backend
|
||||
: "";
|
||||
});
|
||||
|
||||
using EigenUnsignedCharVectorX = Eigen::Vector<unsigned char, Eigen::Dynamic>;
|
||||
using EigenFloatVectorX = Eigen::Vector<float, Eigen::Dynamic>;
|
||||
|
||||
// Skipped: mjr_defaultContext (have MjrContext.__init__)
|
||||
Def<traits::mjr_defaultRendererInfo>(pymodule);
|
||||
Def<traits::mjr_getRendererInfo>(pymodule);
|
||||
// Skipped: mjr_makeContext (have MjrContext.__init__)
|
||||
Def<traits::mjr_changeFont>(pymodule);
|
||||
Def<traits::mjr_addAux>(pymodule);
|
||||
|
||||
@@ -28,6 +28,13 @@ import numpy as np
|
||||
)
|
||||
class MuJoCoRendererTest(parameterized.TestCase):
|
||||
|
||||
def test_renderer_info_binding(self):
|
||||
info = mujoco.MjrRendererInfo()
|
||||
mujoco.mjr_getRendererInfo(info)
|
||||
|
||||
self.assertIn(info.renderer, ('classic', 'filament', 'noop'))
|
||||
self.assertIn(info.backend, ('', 'opengl', 'vulkan', 'unknown'))
|
||||
|
||||
def test_renderer_unknown_camera_name(self):
|
||||
xml = """
|
||||
<mujoco>
|
||||
|
||||
@@ -57,6 +57,8 @@ class CompatContext {
|
||||
scene_bridge_->UploadHeightField(model, id);
|
||||
}
|
||||
|
||||
mjrfContext* Context() const { return context_.get(); }
|
||||
|
||||
private:
|
||||
mjrDrawMode draw_mode_ = mjDRAW_MODE_DEFAULT;
|
||||
UniquePtr<mjrfContext> context_{nullptr, nullptr};
|
||||
@@ -189,6 +191,19 @@ void mjr_defaultContext(mjrContext* con) {
|
||||
memset(con, 0, sizeof(mjrContext));
|
||||
}
|
||||
|
||||
void mjr_defaultRendererInfo(mjrRendererInfo* info) {
|
||||
memset(info, 0, sizeof(mjrRendererInfo));
|
||||
info->renderer = "filament";
|
||||
info->backend = "";
|
||||
}
|
||||
|
||||
void mjr_getRendererInfo(mjrRendererInfo* info) {
|
||||
mjr_defaultRendererInfo(info);
|
||||
if (g_context) {
|
||||
mjrf_getRendererInfo(g_context->Context(), info);
|
||||
}
|
||||
}
|
||||
|
||||
void mjr_makeFilamentContext(const mjModel* m, const mjrfContextConfig* cfg,
|
||||
mjrContext* con) {
|
||||
if (g_context != nullptr) {
|
||||
|
||||
@@ -55,6 +55,29 @@ void mjr_defaultContext(mjrContext* con) {
|
||||
memset(con, 0, sizeof(mjrContext));
|
||||
}
|
||||
|
||||
static int context_count = 0;
|
||||
|
||||
static int contextHasResources(const mjrContext* con) {
|
||||
return con->ntexture || con->offColor || con->offDepthStencil || con->offFBO ||
|
||||
con->shadowTex || con->shadowFBO || con->rangePlane || con->rangeMesh ||
|
||||
con->rangeHField || con->rangeBuiltin || con->rangeFont || con->nskin;
|
||||
}
|
||||
|
||||
// set default mjrRendererInfo
|
||||
void mjr_defaultRendererInfo(mjrRendererInfo* info) {
|
||||
memset(info, 0, sizeof(mjrRendererInfo));
|
||||
info->renderer = "classic";
|
||||
info->backend = "";
|
||||
}
|
||||
|
||||
// get active renderer information
|
||||
void mjr_getRendererInfo(mjrRendererInfo* info) {
|
||||
mjr_defaultRendererInfo(info);
|
||||
if (context_count > 0) {
|
||||
info->backend = "opengl";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// allocate lists
|
||||
@@ -1608,6 +1631,7 @@ void mjr_makeContext_offSize(const mjModel* m, mjrContext* con, int fontscale,
|
||||
// try to bind window (bind offscreen if no window)
|
||||
mjr_setBuffer(mjFB_WINDOW, con);
|
||||
|
||||
context_count++;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1667,6 +1691,7 @@ void mjr_makeContext_offSize(const mjModel* m, mjrContext* con, int fontscale,
|
||||
|
||||
// set default depth mapping for mjr_readPixels
|
||||
con->readDepthMap = mjDEPTH_ZERONEAR;
|
||||
context_count++;
|
||||
}
|
||||
|
||||
|
||||
@@ -1811,6 +1836,8 @@ void mjr_addAux(int index, int width, int height, int samples, mjrContext* con)
|
||||
|
||||
// free resources in custom OpenGL context
|
||||
void mjr_freeContext(mjrContext* con) {
|
||||
int had_resources = contextHasResources(con);
|
||||
|
||||
// save flags
|
||||
int glInitialized = con->glInitialized;
|
||||
int windowAvailable = con->windowAvailable;
|
||||
@@ -1867,6 +1894,10 @@ void mjr_freeContext(mjrContext* con) {
|
||||
con->windowSamples = windowSamples;
|
||||
con->windowStereo = windowStereo;
|
||||
con->windowDoublebuffer = windowDoublebuffer;
|
||||
|
||||
if (had_resources && context_count > 0) {
|
||||
context_count--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace mujoco {
|
||||
FilamentContext::FilamentContext(const mjrfContextConfig* config)
|
||||
: config_(*config) {
|
||||
FilamentPlatformSetup setup = CreateFilamentPlatform(config_);
|
||||
backend_ = setup.backend;
|
||||
platform_ = std::move(setup.platform);
|
||||
|
||||
filament::Engine::Config engine_config;
|
||||
@@ -58,7 +59,7 @@ FilamentContext::FilamentContext(const mjrfContextConfig* config)
|
||||
|
||||
filament::Engine::Builder engine_builder;
|
||||
engine_builder.config(&engine_config);
|
||||
engine_builder.backend(setup.backend);
|
||||
engine_builder.backend(backend_);
|
||||
engine_builder.platform(platform_.get());
|
||||
engine_builder.feature("backend.disable_parallel_shader_compile",
|
||||
setup.disable_parallel_shader_compile);
|
||||
|
||||
@@ -59,6 +59,8 @@ class FilamentContext : public mjrfContext {
|
||||
|
||||
filament::Engine* GetEngine() const { return engine_; }
|
||||
|
||||
filament::Engine::Backend GetBackend() const { return backend_; }
|
||||
|
||||
ObjectManager* GetObjectManager() const { return object_manager_.get(); }
|
||||
|
||||
MaterialManager* GetMaterialManager() const {
|
||||
@@ -76,6 +78,7 @@ class FilamentContext : public mjrfContext {
|
||||
void ValidateSwapChains(std::span<const mjrfRenderRequest> render_requests);
|
||||
|
||||
mjrfContextConfig config_;
|
||||
filament::Engine::Backend backend_;
|
||||
filament::Engine* engine_ = nullptr;
|
||||
filament::Renderer* renderer_ = nullptr;
|
||||
filament::SwapChain* window_swap_chain_ = nullptr;
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
#include <mujoco/mjrfilament.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include <filament/Engine.h>
|
||||
#include <math/mat3.h>
|
||||
#include <math/vec3.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
@@ -37,6 +37,17 @@ static void setf(float (&arr)[N], const std::array<float, N>& values) {
|
||||
}
|
||||
}
|
||||
|
||||
static const char* BackendName(filament::Engine::Backend backend) {
|
||||
switch (backend) {
|
||||
case filament::Engine::Backend::OPENGL:
|
||||
return "opengl";
|
||||
case filament::Engine::Backend::VULKAN:
|
||||
return "vulkan";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void mjrf_defaultContextConfig(mjrfContextConfig* config) {
|
||||
@@ -124,6 +135,12 @@ void mjrf_destroyContext(mjrfContext* ctx) {
|
||||
delete mujoco::FilamentContext::downcast(ctx);
|
||||
}
|
||||
|
||||
void mjrf_getRendererInfo(mjrfContext* ctx, mjrRendererInfo* info) {
|
||||
memset(info, 0, sizeof(mjrRendererInfo));
|
||||
info->renderer = "filament";
|
||||
info->backend = ctx ? BackendName(mujoco::FilamentContext::downcast(ctx)->GetBackend()) : "";
|
||||
}
|
||||
|
||||
mjrfTexture* mjrf_createTexture(mjrfContext* ctx,
|
||||
const mjrfTextureConfig* config) {
|
||||
return new mujoco::Texture(
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
// limitations under the License.
|
||||
|
||||
#include <mujoco/mujoco.h>
|
||||
#include <string.h>
|
||||
|
||||
// This library implements the entirety of mujoco's mjr API as fast-fail stubs.
|
||||
// You can link this library with your application (instead of standard renderer
|
||||
@@ -22,6 +23,14 @@
|
||||
void mjr_defaultContext(mjrContext* con) {
|
||||
mju_error("mjr_defaultContext not implemented.");
|
||||
}
|
||||
void mjr_defaultRendererInfo(mjrRendererInfo* info) {
|
||||
memset(info, 0, sizeof(mjrRendererInfo));
|
||||
info->renderer = "noop";
|
||||
info->backend = "";
|
||||
}
|
||||
void mjr_getRendererInfo(mjrRendererInfo* info) {
|
||||
mjr_defaultRendererInfo(info);
|
||||
}
|
||||
void mjr_makeContext(const mjModel* m, mjrContext* con, int fontscale) {
|
||||
mju_error("mjr_makeContext not implemented.");
|
||||
}
|
||||
|
||||
@@ -6182,6 +6182,12 @@ public unsafe struct mjrRect_ {
|
||||
public int height;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct mjrRendererInfo_ {
|
||||
public char* renderer;
|
||||
public char* backend;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct mjrVertexAttribute_ {
|
||||
public void* bytes;
|
||||
@@ -7215,6 +7221,12 @@ public static unsafe extern void mjv_cameraFrustum(float* zver, float* zhor, flo
|
||||
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static unsafe extern void mjr_defaultContext(mjrContext_* con);
|
||||
|
||||
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static unsafe extern void mjr_defaultRendererInfo(mjrRendererInfo_* info);
|
||||
|
||||
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static unsafe extern void mjr_getRendererInfo(mjrRendererInfo_* info);
|
||||
|
||||
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static unsafe extern void mjr_makeContext(mjModel_* m, mjrContext_* con, int fontscale);
|
||||
|
||||
|
||||
@@ -218,6 +218,7 @@ SKIPPED_STRUCTS: tuple[str, ...] = (
|
||||
"mjUI",
|
||||
"mjVFS",
|
||||
"mjrContext",
|
||||
"mjrRendererInfo",
|
||||
"mjrRect",
|
||||
"mjrVertexAttribute",
|
||||
"mjuiDef",
|
||||
|
||||
Reference in New Issue
Block a user