snaulx Posted January 25, 2024 Posted January 25, 2024 Работаю над собственным рендерингом UI. У меня есть вектор структур, которые содержат вершины, индексы и TexturePtr. И рендерю я всё это, как в примере ImGui (как в ImGuiImpl::draw_callback) - та же идея задавать RenderState, залить всё в меш, затем внутри render_target->enable/disable в цикле задавать текстуру для материала и рендерить меш с оффсетом по вершинам и индексам, а затем идёт точно такой же код, как и в примере, ни капельки не изменнёный. Я понимаю, что этого может быть мало, поэтому если надо, могу подробнее показать. У меня после одного такого прохода функции перестают работать текстуры. Поэтому я снарядился дебаггером и выяснил, что с умным указателем всё в порядке - рефкаунт в порядке, с указателем внутри тоже действий не было, под ним осталась Texture/APIInterface. А вот с объектом внутри APIInterface, в моём случае, с D3D11Texture произошло нехорошее - оно удалилось и стало NULL. Дальше дебаггером я выяснил, что при вызове Engine::swap(), данная текстура/данный объект очищается и вызывается деструктор. Когда я начал отслеживать текстуру внутри ImGui, то там такой подставы не произошло. В чём причина и как это пофиксить?
silent Posted January 26, 2024 Posted January 26, 2024 snaulx Без какого-то внятного кода для воспроизведения сложно сказать. Если есть возможность, можете подготовить сэмпл, чтобы можно было запуститься локально и отладиться? Спасибо. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
snaulx Posted January 26, 2024 Author Posted January 26, 2024 Будет очень тяжело такое сделать, так как в проекте много зависимостей и т.д. + У нас закрытый исходный код, поэтому если кода надо скинуть много, то я скину его вам в лс.
cash-metall Posted January 26, 2024 Posted January 26, 2024 Здравствуйте! скачал и запустил ваш проект. запустил мир dev/ui/ui_test_world в консоли много ошибок ``` Passed geometry doesn't contain valid texture. Remove it from pool. ``` нашел где выводится данная ошибка RmlRenderInterface.cpp:229 if (!g.texture) { Log::error("Passed geometry doesn't contain valid texture. Remove it from pool.\n"); continue; } отлично. начал искать где и кто ее создает, иии не нашел. никто никогда не назначал в Geometry::texture никакого значения. если в вашем сообщении вы говорили про эту текстуру, то она не удаляется - она никогда не создавалась.
snaulx Posted January 26, 2024 Author Posted January 26, 2024 Ошибку я поставил, чтобы не крашилось из-за как раз этого бага. И текстура есть как раз таки в первом кадре, по дебагу я это отследил. Потом происходит то, что я описывал в первом сообщении. В геометрию текстура задаётся в CompileGeometry на 42 строке.
cash-metall Posted January 26, 2024 Posted January 26, 2024 окей, теперь вижу откуда пришла текстура в LoadTexture и GenerateTexture вы загружаете Unigine текстуры. но наружу отдаете Rml::TextureHandle который не хранит счетчик ссылок. тем самым при выходе из скоупа счетчик ссылок = 0. однако объект не умирает сразу - потому что Texture это ссылка на GPU ресурс, который будет удален в свапе. поэтому все верно, когда вы обращаетесь в этом же кадре, объект еще присутствует, а в следующем уже мертв. это можно решить путем добавления всех созданных текстур в контейнер в котором они будут всегда хранится, чтобы не потерять на них ссылку public: bool LoadTexture(Rml::TextureHandle &texture_handle, Rml::Vector2i &texture_dimensions, const Rml::String &source) override { // do some TexturePtr texture = Texture::create(); // после создания текстуры all_generated_textures.append(texture); // добавляем ее в контейнер // } bool GenerateTexture(Rml::TextureHandle &texture_handle, const Rml::byte *source, const Rml::Vector2i &source_dimensions) override; { // do some TexturePtr texture = Texture::create(); // создаем текстуру all_generated_textures.append(texture); // добавляем в контейнер // } void ReleaseTexture(Rml::TextureHandle texture_handle) override; { // do some TexturePtr texture = // ... all_generated_textures.removeOne(texture); // для удаления текстуры, сначала выкидываем из контенера texture.deleteLater(); // потом просим движок удалить текстуру когда она будет не нужна. force не надо // } private: Vector<Unigine::TexturePtr> all_generated_textures; // контейнер. возможно лучше даже использовать не vector а какой нибудь hashmap <rml::textureHandle, Unigine::TexturePtr> (ток придется какойто хешер писать) чтобы избежать разыменования птр и обратно конструирования птр на сырых указателях но нужно проверять, возможно никакой разницы по перфу не будет.
snaulx Posted January 27, 2024 Author Posted January 27, 2024 Правда появилась другая проблема, не связанная с этой (хотя кто знает). У меня не рендерится ничего. Функция вызывается, в рендердоке отображаются DrawIndexed, меши и текстуры, но на финальном результате ничего не видно. Я как-то неправильно вызываю рендер или просто ошибка в ассетах? Если что в том коде, я помимо пула текстур ещё пофиксил оффсеты для вершин и индексов.
silent Posted January 30, 2024 Posted January 30, 2024 А как воспроизвести? Есть код? How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN
cash-metall Posted January 31, 2024 Posted January 31, 2024 Здравствуйте! вы подписались не на тот евент у вас RmlRenderInterface.cpp:12 Engine::get()->getEventEndPluginsGui().connect(this, &RmlRenderInterface::draw); // а надо Render::getEventEndScreen().connect(this, &RmlRenderInterface::draw); в итоге чтото начинает рендится связано с тем, что Render::getTemporaryRenderTarget() и Renderer::getTextureColor() только во время рендера указывают на таргет текущего рендера и на текущую текстуру. в остальных случаях это Temprorary ресурсы, результат изменения которых никуда не идет
Recommended Posts