Make Renderer more self-contained.
The Renderer should configure the context and flip the image when in classic mode and not rely on the Window to do so. PiperOrigin-RevId: 878480986 Change-Id: I1af899107647469659662abd85527cdf66f507f4
This commit is contained in:
committed by
Copybara-Service
parent
15d8fc13b9
commit
c70b05e037
@@ -17,6 +17,7 @@
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <span>
|
||||
#include <utility>
|
||||
|
||||
#include <mujoco/mujoco.h>
|
||||
|
||||
@@ -31,11 +32,24 @@
|
||||
|
||||
namespace mujoco::platform {
|
||||
|
||||
static void FlipImage(unsigned char* pixels, int width, int height, int bpp) {
|
||||
const int row_size = width * bpp;
|
||||
for (int i = 0; i < height / 2; ++i) {
|
||||
unsigned char* top_row = pixels + i * row_size;
|
||||
unsigned char* bottom_row = pixels + (height - 1 - i) * row_size;
|
||||
for (int j = 0; j < row_size; ++j) {
|
||||
std::swap(top_row[j], bottom_row[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Renderer::Renderer(void* native_window, GraphicsMode gfx)
|
||||
: native_window_(native_window), gfx_(gfx) {
|
||||
if (IsClassic(gfx_)) {
|
||||
if (native_window == nullptr) {
|
||||
// graphics_api_context_ = CreateEglContext();
|
||||
#ifndef __EMSCRIPTEN__
|
||||
graphics_api_context_ = CreateEglContext();
|
||||
#endif // __EMSCRIPTEN__
|
||||
}
|
||||
if (ImGui::GetCurrentContext()) {
|
||||
ImGui_ImplOpenGL3_Init();
|
||||
@@ -165,6 +179,9 @@ void Renderer::Render(const mjModel* model, mjData* data,
|
||||
if (render_to_texture) {
|
||||
unsigned char* ptr = reinterpret_cast<unsigned char*>(pixels.data());
|
||||
read_pixels_(ptr, viewport);
|
||||
if (IsClassic(gfx_)) {
|
||||
FlipImage(ptr, width, height, 3);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateFps();
|
||||
@@ -182,7 +199,12 @@ void Renderer::RenderToTexture(const mjModel* model, mjData* data,
|
||||
|
||||
set_buffer_(mjFB_OFFSCREEN);
|
||||
render_(viewport, &scene_);
|
||||
read_pixels_((unsigned char*)output, viewport);
|
||||
|
||||
unsigned char* ptr = reinterpret_cast<unsigned char*>(output);
|
||||
read_pixels_(ptr, viewport);
|
||||
if (IsClassic(gfx_)) {
|
||||
FlipImage(ptr, width, height, 3);
|
||||
}
|
||||
}
|
||||
|
||||
int Renderer::UploadImage(int texture_id, const std::byte* pixels, int width,
|
||||
|
||||
@@ -140,8 +140,7 @@ Window::Window(std::string_view title, int width, int height, Config config)
|
||||
// Filament (except WebGL) manages its own swap chain including when to swap.
|
||||
// In all other cases, we'll use SDL to manage the swap chain.
|
||||
if (config_.gfx_mode == GraphicsMode::FilamentWebGl ||
|
||||
config_.gfx_mode == GraphicsMode::ClassicOpenGl ||
|
||||
config_.gfx_mode == GraphicsMode::ClassicOpenGlHeadless) {
|
||||
config_.gfx_mode == GraphicsMode::ClassicOpenGl) {
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window_);
|
||||
SDL_GL_MakeCurrent(sdl_window_, gl_context);
|
||||
}
|
||||
@@ -260,17 +259,6 @@ void Window::Present(std::span<const std::byte> pixels) {
|
||||
}
|
||||
}
|
||||
|
||||
// Flip the image vertically because the classic renderer uses a bottom-left
|
||||
// coordinate system while SDL assumes a top-left coordinate system.
|
||||
if (config_.gfx_mode == GraphicsMode::ClassicOpenGlHeadless) {
|
||||
dst = static_cast<unsigned char*>(surface->pixels);
|
||||
for (int r = 0; r < height_ / 2; ++r) {
|
||||
unsigned char* top_row = &dst[4 * width_ * r];
|
||||
unsigned char* bottom_row = &dst[4 * width_ * (height_ - 1 - r)];
|
||||
std::swap_ranges(top_row, top_row + 4 * width_, bottom_row);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RenderPresent(sdl_renderer_);
|
||||
} else if (config_.gfx_mode != GraphicsMode::FilamentVulkan
|
||||
&& config_.gfx_mode != GraphicsMode::FilamentOpenGl) {
|
||||
|
||||
Reference in New Issue
Block a user