snaulx Posted January 25 Share Posted January 25 Работаю над собственным рендерингом UI. У меня есть вектор структур, которые содержат вершины, индексы и TexturePtr. И рендерю я всё это, как в примере ImGui (как в ImGuiImpl::draw_callback) - та же идея задавать RenderState, залить всё в меш, затем внутри render_target->enable/disable в цикле задавать текстуру для материала и рендерить меш с оффсетом по вершинам и индексам, а затем идёт точно такой же код, как и в примере, ни капельки не изменнёный. Я понимаю, что этого может быть мало, поэтому если надо, могу подробнее показать. У меня после одного такого прохода функции перестают работать текстуры. Поэтому я снарядился дебаггером и выяснил, что с умным указателем всё в порядке - рефкаунт в порядке, с указателем внутри тоже действий не было, под ним осталась Texture/APIInterface. А вот с объектом внутри APIInterface, в моём случае, с D3D11Texture произошло нехорошее - оно удалилось и стало NULL. Дальше дебаггером я выяснил, что при вызове Engine::swap(), данная текстура/данный объект очищается и вызывается деструктор. Когда я начал отслеживать текстуру внутри ImGui, то там такой подставы не произошло. В чём причина и как это пофиксить? Link to comment
silent Posted January 26 Share Posted January 26 snaulx Без какого-то внятного кода для воспроизведения сложно сказать. Если есть возможность, можете подготовить сэмпл, чтобы можно было запуститься локально и отладиться? Спасибо. How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
snaulx Posted January 26 Author Share Posted January 26 Будет очень тяжело такое сделать, так как в проекте много зависимостей и т.д. + У нас закрытый исходный код, поэтому если кода надо скинуть много, то я скину его вам в лс. Link to comment
cash-metall Posted January 26 Share Posted January 26 Здравствуйте! скачал и запустил ваш проект. запустил мир 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 никакого значения. если в вашем сообщении вы говорили про эту текстуру, то она не удаляется - она никогда не создавалась. Link to comment
snaulx Posted January 26 Author Share Posted January 26 Ошибку я поставил, чтобы не крашилось из-за как раз этого бага. И текстура есть как раз таки в первом кадре, по дебагу я это отследил. Потом происходит то, что я описывал в первом сообщении. В геометрию текстура задаётся в CompileGeometry на 42 строке. Link to comment
cash-metall Posted January 26 Share Posted January 26 окей, теперь вижу откуда пришла текстура в 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> (ток придется какойто хешер писать) чтобы избежать разыменования птр и обратно конструирования птр на сырых указателях но нужно проверять, возможно никакой разницы по перфу не будет. Link to comment
snaulx Posted January 27 Author Share Posted January 27 Правда появилась другая проблема, не связанная с этой (хотя кто знает). У меня не рендерится ничего. Функция вызывается, в рендердоке отображаются DrawIndexed, меши и текстуры, но на финальном результате ничего не видно. Я как-то неправильно вызываю рендер или просто ошибка в ассетах? Если что в том коде, я помимо пула текстур ещё пофиксил оффсеты для вершин и индексов. Link to comment
silent Posted January 30 Share Posted January 30 А как воспроизвести? Есть код? How to submit a good bug report --- FTP server for test scenes and user uploads: ftp://files.unigine.com user: upload password: 6xYkd6vLYWjpW6SN Link to comment
cash-metall Posted January 31 Share Posted January 31 Здравствуйте! вы подписались не на тот евент у вас RmlRenderInterface.cpp:12 Engine::get()->getEventEndPluginsGui().connect(this, &RmlRenderInterface::draw); // а надо Render::getEventEndScreen().connect(this, &RmlRenderInterface::draw); в итоге чтото начинает рендится связано с тем, что Render::getTemporaryRenderTarget() и Renderer::getTextureColor() только во время рендера указывают на таргет текущего рендера и на текущую текстуру. в остальных случаях это Temprorary ресурсы, результат изменения которых никуда не идет Link to comment
Recommended Posts