Allow uploading textures for use with ImGui.
PiperOrigin-RevId: 840669528 Change-Id: I7c5854d966dd024cd492953f86bca961cfaf88b8
This commit is contained in:
committed by
Copybara-Service
parent
e93786c161
commit
f18c9996e6
@@ -316,6 +316,15 @@ void FilamentContext::UploadHeightField(const mjModel* model, int id) {
|
||||
object_manager_->UploadHeightField(model, id);
|
||||
}
|
||||
|
||||
uintptr_t FilamentContext::UploadGuiImage(uintptr_t tex_id,
|
||||
const uint8_t* pixels, int width,
|
||||
int height, int bpp) {
|
||||
if (gui_view_) {
|
||||
return gui_view_->UploadImage(tex_id, pixels, width, height, bpp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
double FilamentContext::GetFrameRate() const {
|
||||
utils::FixedCapacityVector<filament::Renderer::FrameInfo> frame_info =
|
||||
renderer_->getFrameInfoHistory(1);
|
||||
|
||||
@@ -51,6 +51,9 @@ class FilamentContext {
|
||||
|
||||
void UploadHeightField(const mjModel* model, int id);
|
||||
|
||||
uintptr_t UploadGuiImage(uintptr_t tex_id, const uint8_t* pixels, int width,
|
||||
int height, int bpp);
|
||||
|
||||
double GetFrameRate() const;
|
||||
|
||||
FilamentContext(const FilamentContext&) = delete;
|
||||
|
||||
@@ -83,6 +83,49 @@ void GuiView::ResetRenderable() {
|
||||
buffers_.clear();
|
||||
}
|
||||
|
||||
uintptr_t GuiView::UploadImage(uintptr_t tex_id, const uint8_t* pixels,
|
||||
int width, int height, int bpp) {
|
||||
if (bpp != 4) {
|
||||
mju_error("Unsupported image bpp. Got %d, wanted 4", bpp);
|
||||
}
|
||||
|
||||
filament::Engine* engine = object_mgr_->GetEngine();
|
||||
|
||||
filament::Texture* texture = nullptr;
|
||||
if (tex_id == 0) {
|
||||
texture = filament::Texture::Builder()
|
||||
.width(width)
|
||||
.height(height)
|
||||
.levels(1)
|
||||
.format(filament::Texture::InternalFormat::RGBA8)
|
||||
.sampler(filament::Texture::Sampler::SAMPLER_2D)
|
||||
.build(*engine);
|
||||
tex_id = reinterpret_cast<uintptr_t>(texture);
|
||||
textures_[tex_id] = texture;
|
||||
} else {
|
||||
auto iter = textures_.find(tex_id);
|
||||
if (iter == textures_.end()) {
|
||||
mju_error("Texture not found: %lu", tex_id);
|
||||
}
|
||||
texture = iter->second;
|
||||
}
|
||||
|
||||
// Create a copy of the image to pass it to filament as we don't know the
|
||||
// lifetime of the data.
|
||||
const int num_bytes = width * height * bpp;
|
||||
std::byte* bytes = new std::byte[num_bytes];
|
||||
std::memcpy(bytes, pixels, num_bytes);
|
||||
const auto callback = [](void* buffer, size_t size, void* user) {
|
||||
auto* ptr = reinterpret_cast<std::byte*>(user);
|
||||
delete[] ptr;
|
||||
};
|
||||
filament::Texture::PixelBufferDescriptor pb(
|
||||
bytes, num_bytes, filament::Texture::Format::RGBA,
|
||||
filament::Texture::Type::UBYTE, callback);
|
||||
texture->setImage(*engine, 0, std::move(pb));
|
||||
return tex_id;
|
||||
}
|
||||
|
||||
void GuiView::CreateTexture(ImTextureData* data) {
|
||||
filament::Engine* engine = object_mgr_->GetEngine();
|
||||
if (data->Format != ImTextureFormat_RGBA32) {
|
||||
@@ -256,18 +299,16 @@ filament::MaterialInstance* GuiView::GetMaterialInstance(int index,
|
||||
mjrRect rect,
|
||||
uintptr_t texture_id) {
|
||||
while (index >= instances_.size()) {
|
||||
auto iter = textures_.find(texture_id);
|
||||
if (iter == textures_.end()) {
|
||||
mju_error("Texture not found: %lu", texture_id);
|
||||
}
|
||||
instances_.push_back(material_->createInstance());
|
||||
}
|
||||
|
||||
filament::TextureSampler sampler;
|
||||
filament::MaterialInstance* instance = material_->createInstance();
|
||||
instance->setParameter("glyph", iter->second, sampler);
|
||||
instances_.push_back(instance);
|
||||
auto iter = textures_.find(texture_id);
|
||||
if (iter == textures_.end()) {
|
||||
mju_error("Texture not found: %lu", texture_id);
|
||||
}
|
||||
|
||||
filament::MaterialInstance* instance = instances_[index];
|
||||
instance->setParameter("glyph", iter->second, filament::TextureSampler());
|
||||
instance->setScissor(rect.left, rect.bottom, rect.width, rect.height);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,10 @@ class GuiView {
|
||||
// Returns the filament::View used to render the UX scene.
|
||||
filament::View* PrepareRenderView();
|
||||
|
||||
// Uploads texture to be used with ImGui's Image and ImageButton functions.
|
||||
uintptr_t UploadImage(uintptr_t tex_id, const uint8_t* pixels, int width,
|
||||
int height, int bpp);
|
||||
|
||||
private:
|
||||
void CreateTexture(ImTextureData* data);
|
||||
void UpdateTexture(ImTextureData* data);
|
||||
|
||||
@@ -137,6 +137,13 @@ void mjr_readPixels(unsigned char* rgb, float* depth, mjrRect viewport,
|
||||
g_filament_context->ReadPixels(viewport, rgb, depth);
|
||||
}
|
||||
|
||||
uintptr_t mjr_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) {
|
||||
CheckFilamentContext();
|
||||
return g_filament_context->GetFrameRate();
|
||||
|
||||
@@ -81,6 +81,10 @@ MJAPI void mjr_readPixels(unsigned char* rgb, float* depth, mjrRect viewport,
|
||||
|
||||
double mjr_getFrameRate(const mjrContext* con);
|
||||
|
||||
uintptr_t mjr_uploadGuiImage(uintptr_t tex_id, const unsigned char* pixels,
|
||||
int width, int height, int bpp,
|
||||
const mjrContext* con);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user