Jump to content

[SOLVED] Передача параметром контейнера Images в OnCreatorCreate()


photo

Recommended Posts

Добрый день.

В примере показана генерация ландшафта передачей в обратный вызов ссылки на метод 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 by Vasara
Link to comment

Здравствуйте! 
пожалуйста уточните, вы хотите из ландскейпа вытащить данные или создать лендскейп по своим данным?

 

вы можете посмотреть примеры в SDK -> samples ->demos -> CPP Samples
там есть пример Create который создает ландскейп по height/albedo и примеры Fetch и Mesh на получение данных из террейна.

Link to comment
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");
}

Сейчас подчищаю код, хочу убрать загрузку/выгрузку с диска. Т.е. забрать текстуры с ГПУ и отдать в генератор лендскейпа.

  • Like 1
Link to comment

В примерах тот же код, работу которого я не понимаю.

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 by Vasara
Link to comment
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 может занять много времени. 

  • Thanks 1
Link to comment
3 hours ago, cash-metall said:
// берем УКАЗАТЕЛЬ на текущую картинку ландсейпа
ImagePtr albedo = images->getAlbedo(); 

Супер, теперь понятно куда что передавать, всё работает. Спасибо.

Link to comment
  • Vasara changed the title to [SOLVED] Передача параметром контейнера Images в OnCreatorCreate()
×
×
  • Create New...