Initial pass at exposing the new mjr APIs.

Moves all internal types and structs to the "public"
render_context_filament.h header file.

PiperOrigin-RevId: 906929736
Change-Id: I7e7c315fb99a3601b09841073eaeec795718b999
This commit is contained in:
Haroon Qureshi
2026-04-28 05:59:15 -07:00
committed by Copybara-Service
parent 647af382c1
commit 5751b09ff6
22 changed files with 468 additions and 475 deletions
@@ -25,7 +25,6 @@
#include "experimental/filament/compat/imgui_bridge.h"
#include "experimental/filament/compat/imgui_editor.h"
#include "experimental/filament/compat/scene_bridge.h"
#include "experimental/filament/filament/draw_mode.h"
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/model_util.h"
#include "experimental/filament/filament/render_target.h"
@@ -42,11 +41,14 @@ void MjrFilamentRenderer::Init(const mjModel* model) {
scene_bridge_ = std::make_unique<SceneBridge>(GetObjectManager(), model);
imgui_bridge_ = std::make_unique<ImguiBridge>(GetObjectManager());
mjr_defaultRenderRequest(&render_requests_[0]);
mjr_defaultRenderRequest(&render_requests_[1]);
render_requests_[0].scene = scene_bridge_->GetSceneView();
render_requests_[0].draw_mode = DrawMode::Color;
render_requests_[0].draw_mode = mjDRAW_MODE_COLOR;
render_requests_[1].scene = imgui_bridge_->GetSceneView();
render_requests_[1].draw_mode = DrawMode::Color;
render_requests_[1].draw_mode = mjDRAW_MODE_COLOR;
// The UX camera is a fixed orthographic camera. We only need to change the
// width/height based on the viewport per frame.
@@ -78,11 +80,11 @@ void MjrFilamentRenderer::Render(const mjrRect& viewport, const mjvScene* scene)
}
if (scene->flags[mjRND_SEGMENT]) {
render_requests_[0].draw_mode = DrawMode::Segmentation;
render_requests_[0].draw_mode = mjDRAW_MODE_SEGMENTATION;
} else if (scene->flags[mjRND_DEPTH]) {
render_requests_[0].draw_mode = DrawMode::Depth;
render_requests_[0].draw_mode = mjDRAW_MODE_DEPTH;
} else {
render_requests_[0].draw_mode = DrawMode::Color;
render_requests_[0].draw_mode = mjDRAW_MODE_COLOR;
}
render_requests_[0].width = viewport.width;
@@ -142,10 +144,11 @@ void MjrFilamentRenderer::ReadPixels(mjrRect viewport, unsigned char* rgb,
const size_t num_requests =
(mode_ == FrameBufferMode::OffScreenWithGui) ? 2 : 1;
ReadPixelsRequest read_request;
mjrReadPixelsRequest read_request;
mjr_defaultReadPixelsRequest(&read_request);
read_request.output = rgb;
read_request.num_bytes = viewport.width * viewport.height * 3;
const FrameHandle frame = FilamentContext::Render(
const mjrFrameHandle frame = FilamentContext::Render(
{&render_requests_[0], num_requests}, {&read_request, 1});
FilamentContext::WaitForFrame(frame);
@@ -163,13 +166,14 @@ void MjrFilamentRenderer::ReadPixels(mjrRect viewport, unsigned char* rgb,
render_requests_[0].target = target.get();
render_requests_[1].target = target.get();
DrawMode last_draw_mode = render_requests_[0].draw_mode;
render_requests_[0].draw_mode = DrawMode::Depth;
mjrDrawMode last_draw_mode = render_requests_[0].draw_mode;
render_requests_[0].draw_mode = mjDRAW_MODE_DEPTH;
ReadPixelsRequest read_request;
mjrReadPixelsRequest read_request;
mjr_defaultReadPixelsRequest(&read_request);
read_request.output = reinterpret_cast<uint8_t*>(depth);
read_request.num_bytes = viewport.width * viewport.height * sizeof(float);
const FrameHandle frame =
const mjrFrameHandle frame =
FilamentContext::Render({&render_requests_[0], 1}, {&read_request, 1});
FilamentContext::WaitForFrame(frame);
@@ -76,7 +76,7 @@ class MjrFilamentRenderer : public FilamentContext {
};
FrameBufferMode mode_ = FrameBufferMode::Window;
RenderRequest render_requests_[2];
mjrRenderRequest render_requests_[2];
std::unique_ptr<SceneBridge> scene_bridge_;
std::unique_ptr<ImguiBridge> imgui_bridge_;
};
@@ -30,12 +30,12 @@
#include <mujoco/mjvisualize.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/compat/model_objects.h"
#include "experimental/filament/filament/material.h"
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/filament/object_manager.h"
#include "experimental/filament/filament/renderable.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
@@ -424,7 +424,7 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom,
// the programmatic UVs.
if (textures.color) {
if (textures.color->GetFilamentTexture()->getTarget() ==
if (Texture::downcast(textures.color)->GetFilamentTexture()->getTarget() ==
filament::Texture::Sampler::SAMPLER_2D) {
// For 2D textures, `tex_repeat` specifies how many times the texture
// image is repeated. The `tex_uniform` flag determines if the repetition
@@ -1,36 +0,0 @@
// Copyright 2026 DeepMind Technologies Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_DRAW_MODE_H_
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_DRAW_MODE_H_
namespace mujoco {
// The different modes that can be used to render the scene.
enum class DrawMode {
// Render the scene with "normal" colors and lighting.
Color,
// Render the scene as a grayscale depth map.
Depth,
// Render each object with a unique, uniform (flat) color regardless of
// lighting and texture.
Segmentation,
};
static constexpr int kNumDrawModes = 3;
} // namespace mujoco
#endif // MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_DRAW_MODE_H_
@@ -79,16 +79,16 @@ FilamentContext::~FilamentContext() {
filament::Engine::destroy(engine_);
}
FilamentContext::FrameHandle FilamentContext::Render(
std::span<const RenderRequest> requests,
std::span<const ReadPixelsRequest> read_requests) {
mjrFrameHandle FilamentContext::Render(
std::span<const mjrRenderRequest> requests,
std::span<const mjrReadPixelsRequest> read_requests) {
if (read_requests.size() > 1) {
mju_error("Only one read request is supported for now.");
}
bool render_began = false;
mjrRenderTarget* current_target = nullptr;
for (const RenderRequest& request : requests) {
for (const mjrRenderRequest& request : requests) {
if (request.target != current_target && render_began) {
renderer_->endFrame();
render_began = false;
@@ -135,7 +135,7 @@ FilamentContext::FrameHandle FilamentContext::Render(
"Rendering to a render target without a read request is pointless.");
}
const ReadPixelsRequest& read_request = read_requests[0];
const mjrReadPixelsRequest& read_request = read_requests[0];
if (read_request.num_bytes == 0) {
mju_error("Output buffer size is zero.");
}
@@ -156,7 +156,7 @@ FilamentContext::FrameHandle FilamentContext::Render(
scene_view_request.target = render_target;
SceneView* scene_view = SceneView::downcast(request.scene);
scene_view->Render(renderer_, scene_view_request);
render_target->ReadColorPixels(renderer_, read_request.output,
render_target->ReadColorPixels(renderer_, (uint8_t*)read_request.output,
read_request.num_bytes);
}
}
@@ -179,7 +179,7 @@ FilamentContext::FrameHandle FilamentContext::Render(
return ++frame_counter_;
}
void FilamentContext::WaitForFrame(FrameHandle frame_handle) {
void FilamentContext::WaitForFrame(mjrFrameHandle frame_handle) {
if (frame_counter_ < frame_handle) {
engine_->flushAndWait();
}
@@ -15,7 +15,6 @@
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_FILAMENT_CONTEXT_H_
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_FILAMENT_CONTEXT_H_
#include <cstddef>
#include <cstdint>
#include <span>
#include <memory>
@@ -25,11 +24,7 @@
#include <filament/Renderer.h>
#include <filament/SwapChain.h>
#include <math/vec4.h>
#include <mujoco/mjvisualize.h>
#include "experimental/filament/filament/draw_mode.h"
#include "experimental/filament/filament/scene_view.h"
#include "experimental/filament/filament/object_manager.h"
#include "experimental/filament/filament/render_target.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
@@ -43,62 +38,16 @@ class FilamentContext : public mjrfContext {
FilamentContext(const FilamentContext&) = delete;
FilamentContext& operator=(const FilamentContext&) = delete;
// Information needed to render a single image of a scene.
struct RenderRequest {
// The scene to render.
mjrScene* scene = nullptr;
// The method (e.g. Color, Depth, Segmentation, etc.) to use for rendering.
DrawMode draw_mode = DrawMode::Color;
// The camera from which to render the scene.
mjvGLCamera camera;
// The dimensions of the output image.
int width = 0;
int height = 0;
// The render target into which to render the image. If nullptr, the image
// will be rendered to the window (as previously configured in
// mjrFilamentConfig::native_window).
mjrRenderTarget* target = nullptr;
};
// Information needed to read pixels from a render target.
struct ReadPixelsRequest {
mjrRenderTarget* target = nullptr;
// The buffer into which the read pixels will be written.
uint8_t* output = nullptr;
// The number of bytes in the output buffer. This should match the size of
// the render target texture.
std::size_t num_bytes = 0;
// Callback when the read pixels operation is complete. This will be called
// during WaitForFrame() or in a subsequent call to Render(). This function
// can optionally be used to free the output buffer if needed.
void (*read_completed_callback)(void* user_data) = nullptr;
// User data to pass to the completion callback.
void* user_data = nullptr;
};
// Rendering is asynchronous by nature. Each render request is assigned a
// unique Handle which can be used to query the status of the request. The
// Handle can also be used to block until the request is completed.
using FrameHandle = std::uint64_t;
// Queues the given render requests for rendering. This function copies the
// necessary data from the requests into the renderer thread and returns
// immediately afterwards. The renderer thread will then perform the actual
// rendering on the GPU. Callers can use WaitForFrame to block until the
// rendering is complete.
FrameHandle Render(std::span<const RenderRequest> render_requests,
std::span<const ReadPixelsRequest> read_requests = {});
mjrFrameHandle Render(std::span<const mjrRenderRequest> render_requests,
std::span<const mjrReadPixelsRequest> read_requests = {});
// Blocks until the given frame has completed rendering.
void WaitForFrame(FrameHandle frame_handle);
void WaitForFrame(mjrFrameHandle frame_handle);
// Sets the clear color for the renderer.
void SetClearColor(const filament::math::float4& color);
+1 -15
View File
@@ -27,27 +27,13 @@
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
using filament::math::float3;
using filament::math::mat3f;
void mjr_defaultLightParams(mjrLightParams* params) {
params->type = mjLIGHT_POINT;
params->texture = nullptr;
params->color[0] = 0;
params->color[1] = 0;
params->color[2] = 0;
params->intensity = 0.0f;
params->cast_shadows = true;
params->range = 10.0f;
params->spot_cone_angle = 180.f;
params->bulb_radius = 0.0f;
params->shadow_map_size = 2048;
params->vsm_blur_width = 0.0f;
}
Light::Light(filament::Engine* engine, const mjrLightParams& params)
: engine_(engine), params_(params) {
// Filament treats image-based lights (IBLs) as separate objects (i.e.
@@ -20,39 +20,10 @@
#include <math/vec3.h>
#include <utils/Entity.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
typedef mjtLightType mjrLightType;
// Configuration parameters for a light.
struct mjrLightParams {
// The type of light (e.g. spot, point, directional, etc.)
mjrLightType type;
// The texture to use for image lights.
const mjrTexture* texture;
// The color of the light.
float color[3];
// The intensity of the light, in candela.
float intensity;
// Whether or not the light casts shadows.
mjtByte cast_shadows;
// The range/distance in which the light is effective, in meters.
float range;
// The angle of the spot light cone, in degrees.
float spot_cone_angle;
// The radius of the bulb used for soft shadows.
float bulb_radius;
// The size of the shadow map.
int shadow_map_size;
// Blur width for EL VSM.
float vsm_blur_width;
};
void mjr_defaultLightParams(mjrLightParams* params);
// Manages the filament Entities for a single mjvLight.
class Light : public mjrLight {
public:
+4 -40
View File
@@ -14,8 +14,6 @@
#include "experimental/filament/filament/material.h"
#include <array>
#include <filament/Color.h>
#include <filament/Material.h>
#include <filament/MaterialInstance.h>
@@ -25,45 +23,10 @@
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/filament/object_manager.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
template <int N>
static void setf(float (&arr)[N], const std::array<float, N>& values) {
for (int i = 0; i < N; ++i) {
arr[i] = values[i];
}
}
void mjr_defaultMaterialTextures(mjrMaterialTextures* textures) {
textures->color = nullptr;
textures->normal = nullptr;
textures->metallic = nullptr;
textures->roughness = nullptr;
textures->occlusion = nullptr;
textures->orm = nullptr;
textures->emissive = nullptr;
textures->reflection = nullptr;
}
void mjr_defaultMaterialParams(mjrMaterialParams* params) {
setf(params->color, {1.f, 1.f, 1.f, 1.f});
setf(params->segmentation_color, {1, 1, 1, 1});
setf(params->uv_scale, {1, 1, 1});
setf(params->uv_offset, {0, 0, 0});
setf(params->scissor, {0, 0, 0, 0});
params->emissive = -1.0f;
params->specular = -1.0f;
params->glossiness = -1.0f;
params->metallic = -1.0f;
params->roughness = -1.0f;
params->reflectance = 0.0f;
params->tex_uniform = false;
params->reflective = false;
}
void UpdateMaterialInstance(filament::MaterialInstance* instance,
const mjrMaterialParams& params,
const mjrMaterialTextures& textures,
@@ -118,11 +81,12 @@ void UpdateMaterialInstance(filament::MaterialInstance* instance,
sampler.setMinFilter(
filament::TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR);
auto TrySetTexture = [&](const char* name, const Texture* texture,
auto TrySetTexture = [&](const char* name, const mjrTexture* texture,
mjtTextureRole role) {
if (material->hasParameter(name)) {
if (texture != nullptr) {
instance->setParameter(name, texture->GetFilamentTexture(), sampler);
instance->setParameter(
name, Texture::downcast(texture)->GetFilamentTexture(), sampler);
} else {
instance->setParameter(name, object_mgr->GetFallbackTexture(role),
sampler);
+1 -36
View File
@@ -17,46 +17,11 @@
#include <filament/Engine.h>
#include <filament/MaterialInstance.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/filament/object_manager.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
// The textures that can be assigned to the drawable's material.
struct mjrMaterialTextures {
const Texture* color;
const Texture* normal;
const Texture* metallic;
const Texture* roughness;
const Texture* occlusion;
const Texture* orm;
const Texture* emissive;
const Texture* reflection;
};
void mjr_defaultMaterialTextures(mjrMaterialTextures* textures);
// The parameters that can be applied to the drawable's material.
struct mjrMaterialParams {
float color[4];
float segmentation_color[4];
float tex_repeat[2];
float uv_scale[3];
float uv_offset[3];
float scissor[4];
float specular;
float glossiness;
float metallic;
float roughness;
float emissive;
float reflectance;
mjtByte tex_uniform;
mjtByte reflective;
};
void mjr_defaultMaterialParams(mjrMaterialParams* params);
// Updates the material instances based on the currently set parameters and
// textures.
void UpdateMaterialInstance(filament::MaterialInstance* instance,
+1 -5
View File
@@ -33,6 +33,7 @@
#include <math/vec4.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
@@ -101,11 +102,6 @@ int FillSequence(std::byte* buffer, std::size_t num_bytes) {
return num;
}
// Initializes the mjrMeshData to default values.
void mjr_defaultMeshData(mjrMeshData* data) {
std::memset(data, 0, sizeof(mjrMeshData));
}
Mesh::Mesh(filament::Engine* engine, const mjrMeshData& data)
: engine_(engine), shared_state_(std::make_shared<SharedState>()) {
type_ = data.primitive_type == mjMESH_PRIMITIVE_TYPE_TRIANGLES
-104
View File
@@ -16,7 +16,6 @@
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_MESH_H_
#include <array>
#include <cstddef>
#include <functional>
#include <memory>
#include <mutex>
@@ -30,114 +29,11 @@
#include <filament/RenderableManager.h>
#include <filament/VertexBuffer.h>
#include <math/vec4.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/render_context_filament.h"
// Functions for creating filament vertex and index buffers.
namespace mujoco {
// The type of data stored in an index buffer.
typedef enum mjrIndexType_ {
mjINDEX_TYPE_U16 = 0,
mjINDEX_TYPE_U32 = 1,
} mjrIndexType;
// The type of primitive to be drawn by vertex data.
typedef enum mjrMeshPrimitiveType_ {
mjMESH_PRIMITIVE_TYPE_TRIANGLES = 0,
mjMESH_PRIMITIVE_TYPE_LINES = 1,
} mjrMeshPrimitiveType;
// The usage/purpose of an attribute of a vertex.
typedef enum mjrVertexAttributeUsage_ {
mjVERTEX_ATTRIBUTE_USAGE_POSITION = 0,
mjVERTEX_ATTRIBUTE_USAGE_NORMAL = 1,
mjVERTEX_ATTRIBUTE_USAGE_TANGENTS = 2,
mjVERTEX_ATTRIBUTE_USAGE_UV = 3,
mjVERTEX_ATTRIBUTE_USAGE_COLOR = 4,
} mjrVertexAttributeUsage;
// The data format of an attribute of a vertex.
typedef enum mjrVertexAttributeType_ {
mjVERTEX_ATTRIBUTE_TYPE_FLOAT2 = 0,
mjVERTEX_ATTRIBUTE_TYPE_FLOAT3 = 1,
mjVERTEX_ATTRIBUTE_TYPE_FLOAT4 = 2,
mjVERTEX_ATTRIBUTE_TYPE_UBYTE4 = 3,
} mjrVertexAttributeType;
// Maximum number of vertex attributes that can be used by a mesh.
enum { mjMAX_VERTEX_ATTRIBUTES = 16 };
// Information about a single attribute of a vertex.
struct mjrVertexAttribute {
// The data for the attribute.
const void* bytes;
// The usage/purpose of the attribute.
mjrVertexAttributeUsage usage;
// The data format of the attribute.
mjrVertexAttributeType type;
};
// The binary contents of a mesh.
struct mjrMeshData {
// The number of vertices in the mesh. Each of the vertex arrays below is
// assumed to have this number of elements.
mjtSize nvertices;
// The number of attributes for each vertex in the mesh.
int nattributes;
// Information about each attribute of a vertex in the mesh. See `interleaved`
// for more details.
mjrVertexAttribute attributes[mjMAX_VERTEX_ATTRIBUTES];
// Whether the vertex attributes are interleaved or not.
//
// If true, assumes that the attributes are packed in the order specified in
// the attributes array, with no padding in-between. Additionally, the
// `data` pointer for each attribute is assumed to point to the first element
// of that type.
//
// If false, assume each attribute is stored in a separate array as defined
// by the `data` field of the attribute.
mjtByte interleaved;
// The number of indices in the mesh. The indices array is assumed to have
// this number of elements.
mjtSize nindices;
// The indices of the mesh, stored as either ushort or uint depending on the
// index type.
const void* indices;
// The type of data stored in the indices array.
mjrIndexType index_type;
// The type of primitive to be drawn by vertex data.
mjrMeshPrimitiveType primitive_type;
// Whether to compute the bounds of the mesh using the vertex positions.
mjtByte compute_bounds;
// The bounds of the mesh. If bounds_min == bounds_max, then we assume that
// that the bounds are not set (i.e. the bounds is empty).
float bounds_min[3];
float bounds_max[3];
// Because rendering may be multithreaded, we cannot make assumptions about
// when the mesh data will finish uploading to the GPU. As such, we will use
// this callback to notify callers when it is safe to free the mesh data.
void (*release_callback)(void* user_data);
// User data to pass to the release callback.
void* user_data;
};
// Initializes the MeshData to default values.
void mjr_defaultMeshData(mjrMeshData* data);
// Owns a Vertex and Index buffer representing a geometry mesh.
class Mesh : public mjrMesh {
public:
@@ -30,11 +30,6 @@
namespace mujoco {
void mjr_defaultRenderTargetConfig(mjrRenderTargetConfig* config) {
config->color_format = mjPIXEL_FORMAT_RGBA8;
config->depth_format = mjPIXEL_FORMAT_DEPTH32F;
}
RenderTarget::RenderTarget(filament::Engine* engine,
const mjrRenderTargetConfig& config)
: engine_(engine), config_(config) {}
@@ -26,15 +26,6 @@
namespace mujoco {
// Defines the basic properties of a render target.
struct mjrRenderTargetConfig {
mjrPixelFormat color_format;
mjrPixelFormat depth_format;
};
// Initializes the RenderTargetConfig to default values.
void mjr_defaultRenderTargetConfig(mjrRenderTargetConfig* config);
// Manages a filament RenderTarget and the textures which are bound to it.
class RenderTarget : public mjrRenderTarget {
public:
@@ -26,20 +26,17 @@
#include <math/mat4.h>
#include <utils/EntityManager.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/draw_mode.h"
#include "experimental/filament/filament/material.h"
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/filament/object_manager.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
using filament::math::mat4f;
void mjr_defaultRenderableParams(mjrRenderableParams* params) {
params->shading_model = mjSHADING_MODEL_SCENE_OBJECT;
}
Renderable::Renderable(ObjectManager* object_mgr, const mjrRenderableParams& params)
: object_mgr_(object_mgr), params_(params) {
mjr_defaultMaterialParams(&material_params_);
@@ -57,7 +54,7 @@ Renderable::~Renderable() noexcept {
engine->destroy(part.entity);
em.destroy(part.entity);
}
for (int i = 0; i < kNumDrawModes; ++i) {
for (int i = 0; i < mjNUM_DRAW_MODES; ++i) {
if (instances_[i] != nullptr) {
engine->destroy(instances_[i]);
instances_[i] = nullptr;
@@ -206,13 +203,13 @@ void Renderable::UpdateMaterial(const mjrMaterialParams& params,
material_params_ = params;
material_textures_ = textures;
AssignMaterial(DrawMode::Color, GetColorMaterialType());
AssignMaterial(mjDRAW_MODE_COLOR, GetColorMaterialType());
if (params_.shading_model == mjSHADING_MODEL_SCENE_OBJECT) {
AssignMaterial(DrawMode::Depth, ObjectManager::kUnlitDepth);
AssignMaterial(DrawMode::Segmentation, ObjectManager::kUnlitSegmentation);
AssignMaterial(mjDRAW_MODE_DEPTH, ObjectManager::kUnlitDepth);
AssignMaterial(mjDRAW_MODE_SEGMENTATION, ObjectManager::kUnlitSegmentation);
}
for (int i = 0; i < kNumDrawModes; ++i) {
for (int i = 0; i < mjNUM_DRAW_MODES; ++i) {
if (instances_[i]) {
UpdateMaterialInstance(instances_[i], material_params_,
material_textures_, object_mgr_);
@@ -221,7 +218,7 @@ void Renderable::UpdateMaterial(const mjrMaterialParams& params,
SetDrawMode(draw_mode_);
}
void Renderable::AssignMaterial(DrawMode mode,
void Renderable::AssignMaterial(mjrDrawMode mode,
ObjectManager::MaterialType material_type) {
const int index = static_cast<int>(mode);
@@ -248,10 +245,10 @@ const mjrMaterialTextures& Renderable::GetMaterialTextures() const {
return material_textures_;
}
void Renderable::SetDrawMode(DrawMode mode) {
void Renderable::SetDrawMode(mjrDrawMode mode) {
// Only SceneObjects support non-color draw modes.
if (params_.shading_model != mjSHADING_MODEL_SCENE_OBJECT) {
mode = DrawMode::Color;
mode = mjDRAW_MODE_COLOR;
}
filament::MaterialInstance* instance = instances_[static_cast<int>(mode)];
@@ -369,6 +366,7 @@ ObjectManager::MaterialType Renderable::GetColorMaterialType() const {
// geometry) and `mesh_texcoordadr` stores the address of the mesh uvs if
// it has them.
bool has_texcoords = false;
const Texture* color_texture = Texture::downcast(material_textures_.color);
if (!parts_.empty()) {
const auto attribs = parts_[0].mesh->GetVertexAttributes();
auto it = std::find(attribs.begin(), attribs.end(),
@@ -376,7 +374,7 @@ ObjectManager::MaterialType Renderable::GetColorMaterialType() const {
has_texcoords = (it != attribs.end());
}
if (material_textures_.color == nullptr) {
if (color_texture == nullptr) {
if (material_params_.color[3] < 1.0f) {
return ObjectManager::kPhongColorFade;
} else if (material_params_.reflective) {
@@ -384,7 +382,7 @@ ObjectManager::MaterialType Renderable::GetColorMaterialType() const {
} else {
return ObjectManager::kPhongColor;
}
} else if (material_textures_.color->GetFilamentTexture()->getTarget() ==
} else if (color_texture->GetFilamentTexture()->getTarget() ==
filament::Texture::Sampler::SAMPLER_CUBEMAP) {
if (material_params_.color[3] < 1.0f) {
return ObjectManager::kPhongCubeFade;
@@ -24,7 +24,6 @@
#include <filament/Scene.h>
#include <math/mat4.h>
#include <utils/Entity.h>
#include "experimental/filament/filament/draw_mode.h"
#include "experimental/filament/filament/material.h"
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/mesh.h"
@@ -33,21 +32,6 @@
namespace mujoco {
// The shading model (material) for a Renderable.
typedef enum mjrShadingModel_ {
mjSHADING_MODEL_SCENE_OBJECT,
mjSHADING_MODEL_DECOR,
mjSHADING_MODEL_DECOR_LINES,
mjSHADING_MODEL_UX,
} mjrShadingModel;
// Configuration parameters for a Renderable.
struct mjrRenderableParams {
mjrShadingModel shading_model;
};
void mjr_defaultRenderableParams(mjrRenderableParams* params);
// A Renderable is effectively two things: a mesh and a material.
//
// The mesh describes the surface geometry of the object and the material
@@ -125,7 +109,7 @@ class Renderable : public mjrRenderable {
// Further defines the material of the renderable. Only applies to renderables
// with a SceneObject shading model.
void SetDrawMode(DrawMode mode);
void SetDrawMode(mjrDrawMode mode);
// Updates the parameters for the material.
void UpdateMaterial(const mjrMaterialParams& params,
@@ -157,16 +141,16 @@ class Renderable : public mjrRenderable {
void InitPartEntity(Part& part);
void AssignMaterial(DrawMode mode, ObjectManager::MaterialType material_type);
void AssignMaterial(mjrDrawMode mode, ObjectManager::MaterialType material_type);
ObjectManager::MaterialType GetColorMaterialType() const;
ObjectManager* object_mgr_;
mjrRenderableParams params_;
filament::MaterialInstance* instances_[kNumDrawModes] = {nullptr};
filament::MaterialInstance* instances_[mjNUM_DRAW_MODES] = {nullptr};
mjrMaterialParams material_params_;
mjrMaterialTextures material_textures_;
DrawMode draw_mode_ = DrawMode::Color;
mjrDrawMode draw_mode_ = mjDRAW_MODE_COLOR;
filament::Scene* assigned_scene_ = nullptr;
std::vector<Part> parts_;
filament::math::mat4f transform_;
@@ -40,13 +40,12 @@
#include <utils/EntityManager.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/color_grading_options.h"
#include "experimental/filament/filament/draw_mode.h"
#include "experimental/filament/filament/light.h"
#include "experimental/filament/filament/material.h"
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/render_target.h"
#include "experimental/filament/filament/renderable.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
namespace mujoco {
@@ -54,10 +53,6 @@ using filament::math::float3;
using filament::math::float4;
using filament::math::mat4;
static constexpr int kNormalIndex = static_cast<int>(DrawMode::Color);
static constexpr int kDepthIndex = static_cast<int>(DrawMode::Depth);
static constexpr int kSegmentIndex = static_cast<int>(DrawMode::Segmentation);
static filament::ColorGrading::Builder ToBuilder(
const ColorGradingOptions& opts) {
return filament::ColorGrading::Builder()
@@ -146,11 +141,11 @@ SceneView::SceneView(filament::Engine* engine) : engine_(engine) {
// Disable post processing for the depth and segmentation views to preserve
// the values.
views_[kDepthIndex]->setPostProcessingEnabled(false);
views_[kSegmentIndex]->setPostProcessingEnabled(false);
views_[mjDRAW_MODE_DEPTH]->setPostProcessingEnabled(false);
views_[mjDRAW_MODE_SEGMENTATION]->setPostProcessingEnabled(false);
// Rotate the fog to align with mujoco's +Z up space.
auto fog = views_[kNormalIndex]->getFogEntity();
auto fog = views_[mjDRAW_MODE_COLOR]->getFogEntity();
auto& tm = engine->getTransformManager();
tm.create(fog);
tm.setTransform(tm.getInstance(fog),
@@ -255,7 +250,7 @@ void SceneView::Render(filament::Renderer* renderer,
}
// Render reflection passes.
if (request.draw_mode == DrawMode::Color && reflections_enabled_) {
if (request.draw_mode == mjDRAW_MODE_COLOR && reflections_enabled_) {
for (size_t i = 0; i < reflectives_.size(); ++i) {
Renderable* renderable = reflectives_[i];
@@ -317,7 +312,7 @@ void SceneView::SetColorGradingOptions(const ColorGradingOptions& opts) {
auto color_grading = ToBuilder(color_grading_options_)
.toneMapper(tone_mapper.get())
.build(*engine_);
views_[kNormalIndex]->setColorGrading(color_grading);
views_[mjDRAW_MODE_COLOR]->setColorGrading(color_grading);
if (color_grading_) {
engine_->destroy(color_grading_);
}
@@ -326,11 +321,11 @@ void SceneView::SetColorGradingOptions(const ColorGradingOptions& opts) {
}
void SceneView::EnableShadows() {
views_[kNormalIndex]->setShadowingEnabled(true);
views_[mjDRAW_MODE_COLOR]->setShadowingEnabled(true);
}
void SceneView::DisableShadows() {
views_[kNormalIndex]->setShadowingEnabled(false);
views_[mjDRAW_MODE_COLOR]->setShadowingEnabled(false);
}
void SceneView::EnableReflections() {
@@ -351,19 +346,18 @@ void SceneView::DisableReflections() {
textures.reflection = nullptr;
renderable->UpdateMaterial(renderable->GetMaterialParams(), textures);
}
}
void SceneView::EnablePostProcessing() {
views_[kNormalIndex]->setPostProcessingEnabled(true);
views_[mjDRAW_MODE_COLOR]->setPostProcessingEnabled(true);
}
void SceneView::DisablePostProcessing() {
views_[kNormalIndex]->setPostProcessingEnabled(false);
views_[mjDRAW_MODE_COLOR]->setPostProcessingEnabled(false);
}
filament::View* SceneView::GetDefaultRenderView() {
return views_[kNormalIndex];
return views_[mjDRAW_MODE_COLOR];
}
ColorGradingOptions SceneView::GetColorGradingOptions() const {
@@ -27,7 +27,6 @@
#include <filament/View.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/color_grading_options.h"
#include "experimental/filament/filament/draw_mode.h"
#include "experimental/filament/filament/light.h"
#include "experimental/filament/filament/renderable.h"
#include "experimental/filament/filament/render_target.h"
@@ -59,7 +58,7 @@ class SceneView : public mjrScene {
// Parameters for rendering the scene.
struct RenderRequest {
// The draw mode (e.g. normal, depth, segmentation) to render.
DrawMode draw_mode = DrawMode::Color;
mjrDrawMode draw_mode = mjDRAW_MODE_COLOR;
// The target viewport for the rendered image.
mjrRect viewport;
// The camera from which to render the scene.
@@ -111,7 +110,7 @@ class SceneView : public mjrScene {
filament::Camera* camera_ = nullptr;
filament::ColorGrading* color_grading_ = nullptr;
ColorGradingOptions color_grading_options_;
std::array<filament::View*, kNumDrawModes> views_;
std::array<filament::View*, mjNUM_DRAW_MODES> views_;
// Scene objects.
std::unordered_set<Light*> lights_;
@@ -110,14 +110,6 @@ static filament::Texture::InternalFormat GetTextureInternalFormat(
}
}
void mjr_defaultTextureData(mjrTextureData* data) {
std::memset(data, 0, sizeof(mjrTextureData));
}
void mjr_defaultTextureConfig(mjrTextureConfig* config) {
std::memset(config, 0, sizeof(mjrTextureConfig));
}
Texture::Texture(filament::Engine* engine, const mjrTextureConfig& config,
InternalFlags flags)
: engine_(engine), config_(config) {
@@ -25,63 +25,6 @@
// Functions for creating filament textures.
namespace mujoco {
// Pixel formats for textures.
typedef enum mjrPixelFormat_ {
mjPIXEL_FORMAT_UNKNOWN = 0,
mjPIXEL_FORMAT_R8,
mjPIXEL_FORMAT_RGB8,
mjPIXEL_FORMAT_RGBA8,
mjPIXEL_FORMAT_R32F,
mjPIXEL_FORMAT_DEPTH32F,
mjPIXEL_FORMAT_KTX,
} mjrPixelFormat;
typedef mjtTexture mjrTextureTarget;
typedef mjtColorSpace mjrColorSpace;
// The binary contents of a texture.
struct mjrTextureData {
// Pointer to the image data. If null, an empty texture will be created.
const void* bytes;
// The number of bytes in the image data.
mjtSize nbytes;
// Because rendering may be multithreaded, we cannot make assumptions about
// when the image data will finish uploading to the GPU. As such, we will use
// this callback to notify callers when it is safe to free the image data.
void (*release_callback)(void* user_data);
// User data to pass to the release callback.
void* user_data;
};
// Initializes the TextureData to default values.
void mjr_defaultTextureData(mjrTextureData* data);
// Defines the basic properties of a texture.
struct mjrTextureConfig {
// The width of the texture. For compressed textures (e.g. KTX), this is the
// number of bytes in the compressed data.
int width;
// The height of the texture. For compressed textures (e.g. KTX), this should
// be 0.
int height;
// The target of the texture (e.g. 2D, cube, etc.)
mjrTextureTarget target;
// The format of the pixels in the texture (e.g. RGB8, RGBA8, KTX, etc.)
mjrPixelFormat format;
// The color space of the texture (e.g. LINEAR, sRGB, etc.)
mjrColorSpace color_space;
};
// Initializes the TextureConfig to default values.
void mjr_defaultTextureConfig(mjrTextureConfig* config);
// Wrapper around a filament::Texture.
class Texture : public mjrTexture {
public:
@@ -14,6 +14,7 @@
#include "experimental/filament/render_context_filament.h"
#include <array>
#include <cstdint>
#include <cstring>
@@ -36,12 +37,91 @@ static void CheckFilamentContext() {
}
}
template <int N>
static void setf(float (&arr)[N], const std::array<float, N>& values) {
for (int i = 0; i < N; ++i) {
arr[i] = values[i];
}
}
extern "C" {
void mjrf_defaultFilamentConfig(mjrFilamentConfig* config) {
memset(config, 0, sizeof(mjrFilamentConfig));
}
void mjr_defaultTextureData(mjrTextureData* data) {
memset(data, 0, sizeof(mjrTextureData));
}
void mjr_defaultTextureConfig(mjrTextureConfig* config) {
memset(config, 0, sizeof(mjrTextureConfig));
}
void mjr_defaultMeshData(mjrMeshData* data) {
std::memset(data, 0, sizeof(mjrMeshData));
}
void mjr_defaultLightParams(mjrLightParams* params) {
params->type = mjLIGHT_POINT;
params->texture = nullptr;
params->color[0] = 0;
params->color[1] = 0;
params->color[2] = 0;
params->intensity = 0.0f;
params->cast_shadows = true;
params->range = 10.0f;
params->spot_cone_angle = 180.f;
params->bulb_radius = 0.0f;
params->shadow_map_size = 2048;
params->vsm_blur_width = 0.0f;
}
void mjr_defaultMaterialTextures(mjrMaterialTextures* textures) {
textures->color = nullptr;
textures->normal = nullptr;
textures->metallic = nullptr;
textures->roughness = nullptr;
textures->occlusion = nullptr;
textures->orm = nullptr;
textures->emissive = nullptr;
textures->reflection = nullptr;
}
void mjr_defaultMaterialParams(mjrMaterialParams* params) {
setf(params->color, {1.f, 1.f, 1.f, 1.f});
setf(params->segmentation_color, {1, 1, 1, 1});
setf(params->uv_scale, {1, 1, 1});
setf(params->uv_offset, {0, 0, 0});
setf(params->scissor, {0, 0, 0, 0});
params->emissive = -1.0f;
params->specular = -1.0f;
params->glossiness = -1.0f;
params->metallic = -1.0f;
params->roughness = -1.0f;
params->reflectance = 0.0f;
params->tex_uniform = false;
params->reflective = false;
}
void mjr_defaultRenderableParams(mjrRenderableParams* params) {
params->shading_model = mjSHADING_MODEL_SCENE_OBJECT;
}
void mjr_defaultRenderTargetConfig(mjrRenderTargetConfig* config) {
config->color_format = mjPIXEL_FORMAT_RGBA8;
config->depth_format = mjPIXEL_FORMAT_DEPTH32F;
}
void mjr_defaultRenderRequest(mjrRenderRequest* request) {
memset(request, 0, sizeof(mjrRenderRequest));
}
void mjr_defaultReadPixelsRequest(mjrReadPixelsRequest* request) {
memset(request, 0, sizeof(mjrReadPixelsRequest));
}
void mjrf_makeFilamentContext(const mjModel* m, mjrContext* con,
const mjrFilamentConfig* config) {
// TODO: Support multiple contexts and multiple threads. For now, we'll just
@@ -40,12 +40,334 @@ struct mjrRenderTarget {};
// Opaque type for the filament rendering context.
struct mjrfContext {};
// The different modes that can be used to render a scene.
typedef enum mjrDrawMode_ {
// Render the scene with "normal" colors and lighting.
mjDRAW_MODE_COLOR,
// Render the scene as a grayscale depth map.
mjDRAW_MODE_DEPTH,
// Render each object with a unique, uniform (flat) color regardless of
// lighting and texture.
mjDRAW_MODE_SEGMENTATION,
} mjrDrawMode;
enum { mjNUM_DRAW_MODES = 3 };
// The shading model (material) for a Renderable.
typedef enum mjrShadingModel_ {
// For renderables in the main 3D scene.
mjSHADING_MODEL_SCENE_OBJECT = 0,
// For UX renderables.
mjSHADING_MODEL_UX,
// For decorative elements in a Scene (e.g. contact points, force vectors,
// etc.). These objects will not be affected by lighting.
mjSHADING_MODEL_DECOR,
// As above, but uses a line primitives for drawing.
mjSHADING_MODEL_DECOR_LINES,
} mjrShadingModel;
// The type of data stored in an index buffer.
typedef enum mjrIndexType_ {
mjINDEX_TYPE_U16 = 0,
mjINDEX_TYPE_U32,
} mjrIndexType;
// The type of primitive to be drawn by vertex data.
typedef enum mjrMeshPrimitiveType_ {
mjMESH_PRIMITIVE_TYPE_TRIANGLES = 0,
mjMESH_PRIMITIVE_TYPE_LINES,
} mjrMeshPrimitiveType;
// The usage/purpose of an attribute of a vertex.
typedef enum mjrVertexAttributeUsage_ {
mjVERTEX_ATTRIBUTE_USAGE_POSITION = 0,
mjVERTEX_ATTRIBUTE_USAGE_NORMAL,
mjVERTEX_ATTRIBUTE_USAGE_TANGENTS,
mjVERTEX_ATTRIBUTE_USAGE_UV,
mjVERTEX_ATTRIBUTE_USAGE_COLOR,
} mjrVertexAttributeUsage;
// The data format of an attribute of a vertex.
typedef enum mjrVertexAttributeType_ {
mjVERTEX_ATTRIBUTE_TYPE_FLOAT2 = 0,
mjVERTEX_ATTRIBUTE_TYPE_FLOAT3,
mjVERTEX_ATTRIBUTE_TYPE_FLOAT4,
mjVERTEX_ATTRIBUTE_TYPE_UBYTE4,
} mjrVertexAttributeType;
// Pixel formats for textures.
typedef enum mjrPixelFormat_ {
mjPIXEL_FORMAT_UNKNOWN = 0,
mjPIXEL_FORMAT_R8,
mjPIXEL_FORMAT_RGB8,
mjPIXEL_FORMAT_RGBA8,
mjPIXEL_FORMAT_R32F,
mjPIXEL_FORMAT_DEPTH32F,
mjPIXEL_FORMAT_KTX,
} mjrPixelFormat;
typedef enum mjrGraphicsApi_ { // backend graphics API to use
mjGRAPHICS_API_DEFAULT = 0, // default based on platform
mjGRAPHICS_API_OPENGL, // OpenGL (desktop) / WebGL
mjGRAPHICS_API_VULKAN // Vulkan
} mjrGraphicsApi;
// Rendering is asynchronous by nature. Each render request is assigned a
// unique Handle which can be used to query the status of the request. The
// Handle can also be used to block until the request is completed.
typedef std::uint64_t mjrFrameHandle;
// Bring some legacy mjt types into the mjr namespace.
typedef mjtTexture mjrTextureTarget;
typedef mjtColorSpace mjrColorSpace;
typedef mjtLightType mjrLightType;
// The textures that can be assigned to the drawable's material.
struct mjrMaterialTextures {
const mjrTexture* color;
const mjrTexture* normal;
const mjrTexture* metallic;
const mjrTexture* roughness;
const mjrTexture* occlusion;
const mjrTexture* orm;
const mjrTexture* emissive;
const mjrTexture* reflection;
};
// Initializes the mjrMaterialTextures to default values.
void mjr_defaultMaterialTextures(mjrMaterialTextures* textures);
// The parameters that can be applied to the drawable's material.
struct mjrMaterialParams {
float color[4];
float segmentation_color[4];
float tex_repeat[2];
float uv_scale[3];
float uv_offset[3];
float scissor[4];
float specular;
float glossiness;
float metallic;
float roughness;
float emissive;
float reflectance;
mjtByte tex_uniform;
mjtByte reflective;
};
// Initializes the mjrMaterialParams to default values.
void mjr_defaultMaterialParams(mjrMaterialParams* params);
// The binary contents of a texture.
struct mjrTextureData {
// Pointer to the image data. If null, an empty texture will be created.
const void* bytes;
// The number of bytes in the image data.
mjtSize nbytes;
// Because rendering may be multithreaded, we cannot make assumptions about
// when the image data will finish uploading to the GPU. As such, we will use
// this callback to notify callers when it is safe to free the image data.
void (*release_callback)(void* user_data);
// User data to pass to the release callback.
void* user_data;
};
// Initializes the mjrTextureData to default values.
void mjr_defaultTextureData(mjrTextureData* data);
// Defines the basic properties of a texture.
struct mjrTextureConfig {
// The width of the texture. For compressed textures (e.g. KTX), this is the
// number of bytes in the compressed data.
int width;
// The height of the texture. For compressed textures (e.g. KTX), this should
// be 0.
int height;
// The target of the texture (e.g. 2D, cube, etc.)
mjrTextureTarget target;
// The format of the pixels in the texture (e.g. RGB8, RGBA8, KTX, etc.)
mjrPixelFormat format;
// The color space of the texture (e.g. LINEAR, sRGB, etc.)
mjrColorSpace color_space;
};
// Initializes the mjrTextureConfig to default values.
void mjr_defaultTextureConfig(mjrTextureConfig* config);
// Configuration parameters for a Renderable.
struct mjrRenderableParams {
// The shading model to use for the Renderable.
mjrShadingModel shading_model;
};
// Initializes the mjrRenderableParams to default values.
void mjr_defaultRenderableParams(mjrRenderableParams* params);
// Information about a single attribute of a vertex.
struct mjrVertexAttribute {
// The data for the attribute.
const void* bytes;
// The usage/purpose of the attribute.
mjrVertexAttributeUsage usage;
// The data format of the attribute.
mjrVertexAttributeType type;
};
// Maximum number of vertex attributes in a mesh.
enum { mjMAX_VERTEX_ATTRIBUTES = 16 };
// The binary contents of a mesh.
struct mjrMeshData {
// The number of vertices in the mesh. Each of the vertex arrays below is
// assumed to have this number of elements.
mjtSize nvertices;
// The number of attributes for each vertex in the mesh.
int nattributes;
// Information about each attribute of a vertex in the mesh. See `interleaved`
// for more details.
mjrVertexAttribute attributes[mjMAX_VERTEX_ATTRIBUTES];
// Whether the vertex attributes are interleaved or not.
//
// If true, assumes that the attributes are packed in the order specified in
// the attributes array, with no padding in-between. Additionally, the
// `data` pointer for each attribute is assumed to point to the first element
// of that type.
//
// If false, assume each attribute is stored in a separate array as defined
// by the `data` field of the attribute.
mjtByte interleaved;
// The number of indices in the mesh. The indices array is assumed to have
// this number of elements.
mjtSize nindices;
// The indices of the mesh, stored as either ushort or uint depending on the
// index type.
const void* indices;
// The type of data stored in the indices array.
mjrIndexType index_type;
// The type of primitive to be drawn by vertex data.
mjrMeshPrimitiveType primitive_type;
// Whether to compute the bounds of the mesh using the vertex positions.
mjtByte compute_bounds;
// The bounds of the mesh. If bounds_min == bounds_max, then we assume that
// that the bounds are not set (i.e. the bounds is empty).
float bounds_min[3];
float bounds_max[3];
// Because rendering may be multithreaded, we cannot make assumptions about
// when the mesh data will finish uploading to the GPU. As such, we will use
// this callback to notify callers when it is safe to free the mesh data.
void (*release_callback)(void* user_data);
// User data to pass to the release callback.
void* user_data;
};
// Initializes the mjrMeshData to default values.
void mjr_defaultMeshData(mjrMeshData* data);
// Configuration parameters for a light.
struct mjrLightParams {
// The type of light (e.g. spot, point, directional, etc.)
mjrLightType type;
// The texture to use for image lights.
const mjrTexture* texture;
// The color of the light.
float color[3];
// The intensity of the light, in candela.
float intensity;
// Whether or not the light casts shadows.
mjtByte cast_shadows;
// The range/distance in which the light is effective, in meters.
float range;
// The angle of the spot light cone, in degrees.
float spot_cone_angle;
// The radius of the bulb used for soft shadows.
float bulb_radius;
// The size of the shadow map.
int shadow_map_size;
// Blur width for EL VSM.
float vsm_blur_width;
};
// Initializes the mjrLightParams to default values.
void mjr_defaultLightParams(mjrLightParams* params);
// Defines the basic properties of a render target.
struct mjrRenderTargetConfig {
mjrPixelFormat color_format;
mjrPixelFormat depth_format;
};
// Initializes the RenderTargetConfig to default values.
void mjr_defaultRenderTargetConfig(mjrRenderTargetConfig* config);
// Information needed to render a single image of a scene.
struct mjrRenderRequest {
// The scene to render.
mjrScene* scene;
// The method (e.g. Color, Depth, Segmentation, etc.) to use for rendering.
mjrDrawMode draw_mode;
// The camera from which to render the scene.
mjvGLCamera camera;
// The dimensions of the output image.
int width;
int height;
// The render target into which to render the image. If nullptr, the image
// will be rendered to the window (as previously configured in
// mjrFilamentConfig::native_window).
mjrRenderTarget* target;
};
// Initializes the mjrRenderRequest to default values.
void mjr_defaultRenderRequest(mjrRenderRequest* request);
// Information needed to read pixels from a render target.
struct mjrReadPixelsRequest {
mjrRenderTarget* target;
// The buffer into which the read pixels will be written.
void* output;
// The number of bytes in the output buffer. This should match the size of
// the render target texture.
mjtSize num_bytes;
// Callback when the read pixels operation is complete. This will be called
// during WaitForFrame() or in a subsequent call to Render(). This function
// can optionally be used to free the output buffer if needed.
void (*read_completed_callback)(void* user_data);
// User data to pass to the completion callback.
void* user_data;
};
// Initializes the mjrReadPixelsRequest to default values.
void mjr_defaultReadPixelsRequest(mjrReadPixelsRequest* request);
// Configuration parameters for the filament rendering context.
struct mjrFilamentConfig {
// The native window handle into which we can render directly.
void* native_window;