Simplify RenderTarget creation.

Remove the RenderTargetTextureType enum and, instead, create
RenderTargets directly from pixel formats.

PiperOrigin-RevId: 902536708
Change-Id: I2683aa9db23c011212087d93df0260ad27621170
This commit is contained in:
Haroon Qureshi
2026-04-20 03:27:10 -07:00
committed by Copybara-Service
parent e6d77650f7
commit eb31027a7c
6 changed files with 87 additions and 84 deletions
@@ -191,14 +191,17 @@ void FilamentContext::SetFrameBuffer(int framebuffer) {
}
void FilamentContext::PrepareRenderTargets(int width, int height) {
color_target_ = std::make_unique<RenderTarget>(
engine_, RenderTargetTextureType::kColor,
RenderTargetTextureType::kDepth);
RenderTargetConfig config;
DefaultRenderTargetConfig(&config);
config.color_format = mjPIXEL_FORMAT_RGB8;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
color_target_ = std::make_unique<RenderTarget>(engine_, config);
color_target_->Prepare(width, height);
depth_target_ = std::make_unique<RenderTarget>(
engine_, RenderTargetTextureType::kDepthColor,
RenderTargetTextureType::kDepth);
config.color_format = mjPIXEL_FORMAT_R32F;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
depth_target_ = std::make_unique<RenderTarget>(engine_, config);
depth_target_->Prepare(width, height);
}
@@ -30,10 +30,14 @@
namespace mujoco {
void DefaultRenderTargetConfig(RenderTargetConfig* config) {
config->color_format = mjPIXEL_FORMAT_RGBA8;
config->depth_format = mjPIXEL_FORMAT_DEPTH32F;
}
RenderTarget::RenderTarget(filament::Engine* engine,
RenderTargetTextureType color,
RenderTargetTextureType depth)
: engine_(engine), color_type_(color), depth_type_(depth) {}
const RenderTargetConfig& config)
: engine_(engine), config_(config) {}
RenderTarget::~RenderTarget() noexcept {
Destroy();
@@ -47,10 +51,29 @@ void RenderTarget::Prepare(int width, int height) {
width_ = width;
height_ = height;
color_texture_ =
std::make_unique<Texture>(engine_, color_type_, width, height);
depth_texture_ =
std::make_unique<Texture>(engine_, depth_type_, width, height);
TextureConfig color_config;
DefaultTextureConfig(&color_config);
Texture::InternalFlags color_flags;
color_config.width = width;
color_config.height = height;
color_config.target = mjTEXTURE_2D;
color_config.format = config_.color_format;
color_config.color_space = mjCOLORSPACE_LINEAR;
color_config.format = mjPIXEL_FORMAT_RGB8;
color_flags.color_attachment = true;
color_texture_ = std::make_unique<Texture>(engine_, color_config, color_flags);
TextureConfig depth_config;
DefaultTextureConfig(&depth_config);
Texture::InternalFlags depth_flags;
depth_config.width = width;
depth_config.height = height;
depth_config.target = mjTEXTURE_2D;
depth_config.format = config_.depth_format;
depth_config.color_space = mjCOLORSPACE_LINEAR;
depth_config.format = mjPIXEL_FORMAT_DEPTH32F;
depth_flags.depth_attachment = true;
depth_texture_ = std::make_unique<Texture>(engine_, depth_config, depth_flags);
filament::RenderTarget::Builder builder;
builder.texture(filament::RenderTarget::AttachmentPoint::COLOR,
@@ -65,19 +88,19 @@ void RenderTarget::ReadColorPixels(filament::Renderer* renderer, uint8_t* bytes,
filament::backend::PixelDataFormat format;
filament::backend::PixelDataType type;
size_t expected_num_bytes = 0;
switch (color_type_) {
case RenderTargetTextureType::kColor:
switch (config_.color_format) {
case mjPIXEL_FORMAT_RGB8:
format = filament::backend::PixelDataFormat::RGB;
type = filament::backend::PixelDataType::UBYTE;
expected_num_bytes = width_ * height_ * 3;
break;
case RenderTargetTextureType::kDepthColor:
case mjPIXEL_FORMAT_R32F:
format = filament::backend::PixelDataFormat::R;
type = filament::backend::PixelDataType::FLOAT;
expected_num_bytes = width_ * height_ * sizeof(float);
break;
default:
mju_error("Unsupported pixel format: %d", color_type_);
mju_error("Unsupported pixel format: %d", config_.color_format);
return;
}
if (num_bytes != expected_num_bytes) {
@@ -25,13 +25,21 @@
namespace mujoco {
// Defines the basic properties of a render target.
struct RenderTargetConfig {
mjtPixelFormat color_format;
mjtPixelFormat depth_format;
};
// Initializes the RenderTargetConfig to default values.
void DefaultRenderTargetConfig(RenderTargetConfig* config);
// Manages a filament RenderTarget and the textures which are bound to it.
class RenderTarget {
public:
// Defines the types of textures to create for the color and depth
// attachments.
RenderTarget(filament::Engine* engine, RenderTargetTextureType color,
RenderTargetTextureType depth);
RenderTarget(filament::Engine* engine, const RenderTargetConfig& config);
~RenderTarget() noexcept;
RenderTarget(const RenderTarget&) = delete;
@@ -58,11 +66,10 @@ class RenderTarget {
void Destroy();
filament::Engine* engine_ = nullptr;
RenderTargetConfig config_;
filament::RenderTarget* render_target_ = nullptr;
std::unique_ptr<Texture> color_texture_ = nullptr;
std::unique_ptr<Texture> depth_texture_ = nullptr;
RenderTargetTextureType color_type_;
RenderTargetTextureType depth_type_;
int width_ = 0;
int height_ = 0;
};
@@ -325,9 +325,12 @@ void SceneView::AddReflectiveRenderable(Renderable* renderable) {
// Ensure we have the same number of render targets as we do reflective
// renderables.
while (reflect_targets_.size() < reflectives_.size()) {
reflect_targets_.push_back(std::make_unique<RenderTarget>(
engine_, RenderTargetTextureType::kReflectionColor,
RenderTargetTextureType::kDepth));
RenderTargetConfig config;
DefaultRenderTargetConfig(&config);
config.color_format = mjPIXEL_FORMAT_RGBA8;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
reflect_targets_.push_back(std::make_unique<RenderTarget>(engine_, config));
}
// Prepare a render target for the reflective renderable.
+17 -38
View File
@@ -99,6 +99,10 @@ static filament::Texture::InternalFormat GetTextureInternalFormat(
return filament::Texture::InternalFormat::RGB8;
case mjPIXEL_FORMAT_RGBA8:
return filament::Texture::InternalFormat::RGBA8;
case mjPIXEL_FORMAT_R32F:
return filament::Texture::InternalFormat::R32F;
case mjPIXEL_FORMAT_DEPTH32F:
return filament::Texture::InternalFormat::DEPTH32F;
default:
mju_error("Unsupported format: %d", (int)config.format);
return filament::Texture::InternalFormat::UNUSED;
@@ -114,7 +118,8 @@ void DefaultTextureConfig(TextureConfig* config) {
std::memset(config, 0, sizeof(TextureConfig));
}
Texture::Texture(filament::Engine* engine, const TextureConfig& config)
Texture::Texture(filament::Engine* engine, const TextureConfig& config,
InternalFlags flags)
: engine_(engine), config_(config) {
if (IsCompressed(config_)) {
// We defer creation of compressed textures until Upload() is called. In
@@ -139,45 +144,19 @@ Texture::Texture(filament::Engine* engine, const TextureConfig& config)
builder.sampler(filament::Texture::Sampler::SAMPLER_2D);
}
if (config_.color_space != mjCOLORSPACE_SRGB) {
builder.usage(filament::Texture::Usage::GEN_MIPMAPPABLE |
filament::Texture::Usage::SAMPLEABLE |
filament::Texture::Usage::UPLOADABLE);
filament::Texture::Usage usage = filament::Texture::Usage::DEFAULT;
if (flags.color_attachment) {
usage |= filament::Texture::Usage::COLOR_ATTACHMENT;
usage |= filament::Texture::Usage::BLIT_SRC;
} else if (flags.depth_attachment) {
usage |= filament::Texture::Usage::DEPTH_ATTACHMENT;
usage |= filament::Texture::Usage::BLIT_SRC;
} else if (config_.color_space != mjCOLORSPACE_SRGB) {
usage |= filament::Texture::Usage::GEN_MIPMAPPABLE;
}
texture_ = builder.build(*engine_);
}
builder.usage(usage);
Texture::Texture(filament::Engine* engine, RenderTargetTextureType type,
int width, int height) : engine_(engine) {
filament::Texture::Builder builder;
builder.width(width);
builder.height(height);
switch (type) {
case RenderTargetTextureType::kColor:
builder.usage(filament::Texture::Usage::COLOR_ATTACHMENT |
filament::Texture::Usage::BLIT_SRC);
builder.format(filament::Texture::InternalFormat::RGB8);
break;
case RenderTargetTextureType::kDepth:
builder.usage(filament::Texture::Usage::DEPTH_ATTACHMENT |
filament::Texture::Usage::SAMPLEABLE);
builder.format(filament::Texture::InternalFormat::DEPTH32F);
break;
case RenderTargetTextureType::kDepthColor:
builder.usage(filament::Texture::Usage::COLOR_ATTACHMENT |
filament::Texture::Usage::BLIT_SRC);
builder.format(filament::Texture::InternalFormat::R32F);
break;
case RenderTargetTextureType::kReflectionColor:
builder.usage(filament::Texture::Usage::COLOR_ATTACHMENT |
filament::Texture::Usage::BLIT_SRC |
filament::Texture::Usage::SAMPLEABLE);
builder.format(filament::Texture::InternalFormat::RGBA8);
break;
default:
mju_error("Unknown type: %d", static_cast<int>(type));
}
texture_ = builder.build(*engine);
texture_ = builder.build(*engine_);
}
Texture::~Texture() {
+10 -22
View File
@@ -25,29 +25,13 @@
// Functions for creating filament textures.
namespace mujoco {
// The types of textures we can create. For internal use only.
enum class TextureTarget {
// A standard 2D image with a width and a height.
kNormal2d,
// A 2D texture split up into the 6 faces of a cube.
kCube,
};
// The different types of textures we can create for a render target.
// For internal use only.
enum class RenderTargetTextureType {
kColor,
kDepth,
kDepthColor,
kReflectionColor,
};
// Pixel formats for textures.
typedef enum mjtPixelFormat_ {
mjPIXEL_FORMAT_UNKNOWN = 0,
mjPIXEL_FORMAT_R8,
mjPIXEL_FORMAT_RGB8,
mjPIXEL_FORMAT_RGBA8,
mjPIXEL_FORMAT_R32F,
mjPIXEL_FORMAT_DEPTH32F,
mjPIXEL_FORMAT_KTX,
} mjtPixelFormat;
@@ -98,12 +82,16 @@ void DefaultTextureConfig(TextureConfig* config);
// Wrapper around a filament::Texture.
class Texture {
public:
// Creates a texture with the given data.
Texture(filament::Engine* engine, const TextureConfig& config);
// Flags for internal use.
struct InternalFlags {
InternalFlags() : color_attachment(false), depth_attachment(false) {}
bool color_attachment;
bool depth_attachment;
};
// Creates a texture for use with a render target, for internal use.
Texture(filament::Engine* engine, RenderTargetTextureType type, int width,
int height);
// Creates a texture with the given data.
Texture(filament::Engine* engine, const TextureConfig& config,
InternalFlags flags = InternalFlags());
~Texture();