Page 1 of 1

Need advice with CharacterPreview / InventoryPreview

Posted: 07 May 2017, 23:21
by Jyby
I'm trying to get the osg::Texture2D from an InventoryPreview instance that I've made.

The problem is, it's basically missing the actual character preview texture, i.e. the osg::Image is empty.

Also note, I understand my implementation might be counter to the desired design. I'm just trying to hack something together first.

Code: Select all

// Not sure if I'm missing steps or creating this preview outside of InventoryDialogue is possible
void RenderingManager::avatar(osg::Image *image, const MWWorld::Ptr& player)
{
	MWRender::InventoryPreview* inventoryPreview = new MWRender::InventoryPreview(mViewer->getSceneData()->asGroup(), mResourceSystem, player);
	inventoryPreview->rebuild(); 
	inventoryPreview->update();
	image = inventoryPreview->getTexture()->getImage();
}
I took reference from how the InventoryDialogue sets everything up. Any pointers / tips would be super helpful.

My goal is to be able to save the ChatacterPreview image (when you open your inventory up and you see your character) to a file.

EDIT:

This continues with code to write to file when the player saves his/her game. When complete I could push to master with the option to turn this feature on. I'm working on a website based character browser for people to see and read the states of everyones characters, the mods they use, and a download to the save file for OpenMW. One day it'd be cool to host here, with authentication for everyone to upload their characters.

Code is similar to the way we save screenshots for saved games. I see todo's to clean screenshot saves up so I will investigate that at some point.

Code: Select all

void MWState::StateManager::writeAvatar(std::vector<char> &imageData) const
{
	osg::ref_ptr<osg::Image> avatar(new osg::Image);

	MWBase::Environment::get().getWorld()->avatar(avatar.get(), MWBase::Environment::get().getWorld()->getPlayerPtr());

	osgDB::ReaderWriter* readerwriter = osgDB::Registry::instance()->getReaderWriterForExtension("jpg");
	if (!readerwriter)
	{
		std::cerr << "Error: Unable to write avatar, can't find a jpg ReaderWriter" << std::endl;
		return;
	}

	std::ostringstream ostream;
	osgDB::ReaderWriter::WriteResult result = readerwriter->writeImage(*avatar, ostream);
	if (!result.success())
	{
		std::cerr << "Error: Unable to write avatar: " << result.message() << " code " << result.status() << std::endl;
		return;
	}

	// \todo save the avatar image
}
EDIT EDIT:

I think this feature, the ability to save a preview of your character, is a neat for when people have mods and such. And adds uniformity when compiling a list of character previews.

Re: Need advice with CharacterPreview / InventoryPreview

Posted: 08 May 2017, 14:52
by scrawl
Well, you probably shouldn't expect help for hacking on undiscussed features that the code was never intended for. But, in the interest of education and because I'm in a good mood, I'll answer anyway:

- You're just building an animation and loading it into the scene graph, but not rendering it. The actual render usually happens as part of the frame update.
- If you render to a texture, it will only exist on the GPU by default. To download the render to the system memory, you'll have to do so explicitely; in OSG, the simplest way to do so is to assign an Image to the Camera before you render (see Camera::attach, plenty of examples of this in our codebase)

Re: Need advice with CharacterPreview / InventoryPreview

Posted: 09 May 2017, 07:04
by Jyby
I figured you had knowledge on this Scrawl, at least the Git Blame says so. And cool, I'll look into this and report back here. Thanks