Jump to content

[SOLVED] How to handle Texture MipMaps for following scenario?


photo

Recommended Posts

Hi there,

First look at three screenshots for the explanation.

First image the World is loaded and I have one plane with the default texture mapped on to it.

image.thumb.png.838d471ca8ab099720f19248fa6a58a4.png

Now what I do is enumerate this plane using C++ API. Then enumerate the this first surface and acquire the material mapped onto the surface. I save the textures mapped to albedo and emission texture sources. The pointers are saved. and then I use my other texture to mapped on to that material texture slots. and you may see the effect in the second image.

ObjectPtr objObject = static_ptr_cast<Object>(objNode);
				if (objObject != nullptr)
				{
					for (int iSurfaceCount = 0; iSurfaceCount < objObject->getNumSurfaces(); iSurfaceCount++)
					{

						struct SAroExportedSurfaceMaterialInfo objSurfaceMaterialInfo;

						objSurfaceMaterialInfo.objMaterialChanger = objObject->getMaterial(iSurfaceCount);
						if (objSurfaceMaterialInfo.objMaterialChanger.get() != nullptr)
						{
							objSurfaceMaterialInfo.iDiffuseTextureID = objSurfaceMaterialInfo.objMaterialChanger->findTexture("albedo");
							if (objSurfaceMaterialInfo.iDiffuseTextureID == -1)
							{
								objSurfaceMaterialInfo.iDiffuseTextureID = objSurfaceMaterialInfo.objMaterialChanger->findTexture("diffuse");
								if (objSurfaceMaterialInfo.iDiffuseTextureID == -1)
									return;
							}

							objSurfaceMaterialInfo.iEmmisionTextureID = objSurfaceMaterialInfo.objMaterialChanger->findTexture("emission");

							objSurfaceMaterialInfo.objTextureDiffuse = objSurfaceMaterialInfo.objMaterialChanger->getTexture(objSurfaceMaterialInfo.iDiffuseTextureID);
							objSurfaceMaterialInfo.objTextureEmission = objSurfaceMaterialInfo.objMaterialChanger->getTexture(objSurfaceMaterialInfo.iEmmisionTextureID);							

						}
						objExporteNode.m_vecExportedSurfaceMaterialInfo.push_back(objSurfaceMaterialInfo);
					}
				}

//Used to map new texture to the material texture slots.
void CAroUnigineWorldNodesEnumerator::setThisTexture(int _iNodeIndex, int _iSurfaceIndex, TexturePtr _textureData)
{
	if (_iNodeIndex >= 0 && _iNodeIndex < m_vecStringValues.size())
	{
		if (_iSurfaceIndex > -1 && _iSurfaceIndex < m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo.size())
		{
			if (m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].iDiffuseTextureID != -1)
				m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].objMaterialChanger->setTexture(
				m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].iDiffuseTextureID, _textureData);

			if (m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].iEmmisionTextureID != -1)
				m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].objMaterialChanger->setTexture(
					m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].iEmmisionTextureID, _textureData);			
		}
	}	
}

image.thumb.png.28b466738baea82325d75500afbbe7e8.png

Now I put an option to retain  original texture on the material. When I do this using the following code and saved texture pointer the result is like in the third image.

void CAroUnigineWorldNodesEnumerator::setOriginalTexture(int _iNodeIndex, int _iSurfaceIndex)
{
	if (_iNodeIndex >= 0 && _iNodeIndex < m_vecStringValues.size())
	{
		if (_iSurfaceIndex > -1 && _iSurfaceIndex < m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo.size())
		{
			if (m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].iDiffuseTextureID != -1)
				m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].objMaterialChanger->setTexture(
					m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].iDiffuseTextureID, 
					m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].objTextureDiffuse);

			if (m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].iEmmisionTextureID != -1)
				m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].objMaterialChanger->setTexture(
					m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].iEmmisionTextureID, 
					m_vecExporteNodes[_iNodeIndex].m_vecExportedSurfaceMaterialInfo[_iSurfaceIndex].objTextureEmission);
		}
	}
}

image.thumb.png.0e7f47218756aa97c637a9af6ec49eb8.png

Now I think when did I saved the texture there happened some problem with mip map assignment. And now I have this behavior. Any clue? Is it related to mip map? 

Regards,

Rohit

Link to comment

Hi Rohit,

This is happening because of texture streaming.
When you set a texture for your material via an Editor - engine will utilize texture streaming in order to load/unload cached/full textures at runtime on demand.
When you stored your pointer to texture (assuming that happend in AppWorldLogic::init()) you stored pointer to a cached texture because engine haven't fully loaded it yet.
If you try storing pointer to already loaded texture then changed both albedo and emission slots to something different and after sometime tried switching them back you'd hit a crash. Because texture that you stored pointer to would be already unloaded by now.

What i would suggest trying is storing path to texture instead. If it's invalid then store a pointer.

Hope this helps,

Kirill

  • Thanks 1
Link to comment

Dear Sweetluna,

Your suggestion worked. Pointers are dangerous when I am not in control of them. 

My main problem is solved, when anyone changes the original texture they can get it back now. 

But it is not real time which I was 100% sure with pointers (if they would have remained alive.). There is a glitch as engine loads this texture and shows it. So this feature is for configuration purposes only for me but it is a life saver. 

Otherwise previously I always needed to restart the engine to get the original textures.

Rohit

  • Like 1
Link to comment

I have also adapted the logic to put an extra texture with pointer using the same paths, and now I can switch between original texture and my custom textures in real time. The newly created texture is completely in my control.

Bingo.

Rohit

  • Like 1
Link to comment
  • silent changed the title to [SOLVED] How to handle Texture MipMaps for following scenario?
×
×
  • Create New...