Vasara Posted August 2, 2021 Share Posted August 2, 2021 (edited) Добрый день. В примере показана генерация ландшафта передачей в обратный вызов ссылки на метод OnCreatorCreate: creator->addCreateCallback(MakeCallback(this, &LMapCreator::OnCreatorCreate)); В самом методе создаётся контейнер images . OnCreatorCreate(LandscapeMapFileCreatorPtr creator, LandscapeImagesPtr images, int x, int y) Я хочу собрать из уже сгенерированных в память ресурсов контейнер fillImages(int x, int y, ImagePtr height, ImagePtr albedo) { ptrImages = LandscapeImages::create(Math::ivec2(x, y)); height = ptrImages->getHeight(); albedo = ptrImages->getAlbedo(); } и передать указатель ptrImages в OnCreatorCreate(). Можно ли это провернуть и как? С уважением, Константин! Edited August 3, 2021 by Vasara Link to comment
cash-metall Posted August 3, 2021 Share Posted August 3, 2021 Здравствуйте! пожалуйста уточните, вы хотите из ландскейпа вытащить данные или создать лендскейп по своим данным? вы можете посмотреть примеры в SDK -> samples ->demos -> CPP Samples там есть пример Create который создает ландскейп по height/albedo и примеры Fetch и Mesh на получение данных из террейна. Link to comment
Vasara Posted August 3, 2021 Author Share Posted August 3, 2021 2 hours ago, cash-metall said: Здравствуйте! пожалуйста уточните, вы хотите из ландскейпа вытащить данные или создать лендскейп по своим данным? вы можете посмотреть примеры в SDK -> samples ->demos -> CPP Samples там есть пример Create который создает ландскейп по height/albedo и примеры Fetch и Mesh на получение данных из террейна. Создать свой из процедурных данных. Пользовался куском из примера: void AppWorldLogic::OnCreatorCreate(LandscapeMapFileCreatorPtr creator, LandscapeImagesPtr images, int x, int y) { // get number of the current tile int tileNumber = x * lmapGridSizeY + y; Log::message("Create tile %d\n", tileNumber); // set albedo for current tile if (FileSystem::isFileExist(tiles[tileNumber].albedoImagePath)) { ImagePtr albedoImage = Image::create(tiles[tileNumber].albedoImagePath); if (albedoImage && (albedoImage->getWidth() == lmapTileResolutionX) && (albedoImage->getHeight() == lmapTileResolutionY)) { ImagePtr albedo = images->getAlbedo(); albedo->create2D(albedoImage->getWidth(), albedoImage->getHeight(), albedoImage->getFormat(), albedoImage->getNumMipmaps()); albedo->copy(albedoImage, 0, 0, 0, 0, albedoImage->getWidth(), albedoImage->getHeight()); } else Log::error("The albedo image cannot be loaded, or its resolution does not match the resolution of tile.\n"); } else Log::error("Albedo file does not exist.\n"); // set height for current tile if (FileSystem::isFileExist(tiles[tileNumber].heightImagePath)) { ImagePtr heightImage = Image::create(tiles[tileNumber].heightImagePath); if (heightImage && (heightImage->getWidth() == lmapTileResolutionX) && (heightImage->getHeight() == lmapTileResolutionY)) { ImagePtr height = images->getHeight(); height->create2D(heightImage->getWidth(), heightImage->getHeight(), heightImage->getFormat(), heightImage->getNumMipmaps()); height->copy(heightImage, 0, 0, 0, 0, heightImage->getWidth(), height->getHeight()); } else Log::error("The height image cannot be loaded, or its resolution does not match the resolution of tile.\n"); } else Log::error("Height file does not exist.\n"); } Сейчас подчищаю код, хочу убрать загрузку/выгрузку с диска. Т.е. забрать текстуры с ГПУ и отдать в генератор лендскейпа. 1 Link to comment
Vasara Posted August 3, 2021 Author Share Posted August 3, 2021 (edited) В примерах тот же код, работу которого я не понимаю. auto source_albedo = Image::create(albedo_images_param.get(index).get()); if (source_albedo->getWidth() == tile_resolution.x && source_albedo->getHeight() == tile_resolution.y) { auto albedo = images->getAlbedo(); albedo->create2D(source_albedo->getWidth(), source_albedo->getHeight(), source_albedo->getFormat()); albedo->copy(source_albedo, 0, 0, 0, 0, source_albedo->getWidth(), source_albedo->getHeight()); } Как я понял из дебагера, LandscapeImagesPtr images контейнер, куда сливаются пиксели, а не ссылки на ресурсы. У нас есть ресурсы: if (source_albedo->getWidth() == tile_resolution.x && source_albedo->getHeight() == tile_resolution.y) В моём варианте ими управляет другая обёртка, а этот класс о них соответственно знать ни чего не знает. Эту строчку я не понимаю в принципе: auto albedo = images->getAlbedo(); Дальше создалась копия ресурса: albedo->create2D(source_albedo->getWidth(), source_albedo->getHeight(), source_albedo->getFormat()); albedo->copy(source_albedo, 0, 0, 0, 0, source_albedo->getWidth(), source_albedo->getHeight()); Потом, могу лишь предположить, что происходит магия и всё оказывается в автоматически создаваемом контейнере images. Так вот, я хочу создать свой myImages, залить туда все ресурсы и передать в метод: CreateSample::create_callback(Unigine::LandscapeMapFileCreatorPtr creator, Unigine::LandscapeImagesPtr images, int x, int y) Зачем мне это: хочу свести код к--> myImages.albedo->set(myAlbedo); create_callback(creator, ptrMyImages) Edited August 3, 2021 by Vasara Link to comment
cash-metall Posted August 3, 2021 Share Posted August 3, 2021 2 hours ago, Vasara said: Как я понял из дебагера, LandscapeImagesPtr images контейнер, куда сливаются пиксели, а не ссылки на ресурсы. да все верно. LandscapeImagesPtr - Это контейнер данных для landscape на CPU стороне. // загружаем картинку из файла (albedo_images_param - массив из компоненты, там пути до файлов) ImagePtr source_albedo = Image::create(albedo_images_param.get(index).get()); // берем УКАЗАТЕЛЬ на текущую картинку ландсейпа ImagePtr albedo = images->getAlbedo(); // create2D - удаляет старые данные и выделяет место под новые albedo->create2D(source_albedo->getWidth(), source_albedo->getHeight(), source_albedo->getFormat()); // копируем данные из нашего файла (source_albedo) в картинку ландскейпа (которая уже лежит в LandscapeImages) albedo->copy(source_albedo, 0, 0, 0, 0, source_albedo->getWidth(), source_albedo->getHeight()); 2 hours ago, Vasara said: Зачем мне это: хочу свести код к myImages.albedo->set(myAlbedo); create_callback(creator, ptrMyImages) рантаймовая модификация террейна возможно только из специльного колбека из потока террейна. т.к. его данные хранятся прежде всего на GPU и обновление данных с CPU может занять много времени. 1 Link to comment
Vasara Posted August 3, 2021 Author Share Posted August 3, 2021 3 hours ago, cash-metall said: // берем УКАЗАТЕЛЬ на текущую картинку ландсейпа ImagePtr albedo = images->getAlbedo(); Супер, теперь понятно куда что передавать, всё работает. Спасибо. Link to comment
Recommended Posts