Page 1 of 1

Create texture in code and use it in material scripts

Posted: Tue Jan 01, 2019 12:36 am
by mogumbo
I am creating some dynamic textures in code, and I would like to use them in multiple materials that are defined with material scripts. Is this possible? In code I am able to give each texture a unique name, but I can't find a way to reference these names in material scripts.

Re: Create texture in code and use it in material scripts

Posted: Tue Jan 01, 2019 1:19 am
by xrgo

Code: Select all

    Ogre::Pass *myMatPass = Ogre::MaterialManager::getSingletonPtr()->getByName("myMaterial")->getTechnique(0)->getPass(0);
    myMatPass->getTextureUnitState(0)->setTexture( myTexture );
    //or: myMatPass->getTextureUnitState(0)->setTextureName( "myTexture" );

Re: Create texture in code and use it in material scripts

Posted: Tue Jan 01, 2019 1:39 am
by mogumbo
Thanks for replying. I might not have been clear enough in my question. I want to reference a texture in material scripts, not in code. The texture I want to reference, however, is created in code.

If assigning the texture to materials in code is the only way to go then I guess I'll do that instead. But I'll need to devise a way to identify the materials that require my dynamic textures.

Re: Create texture in code and use it in material scripts

Posted: Tue Jan 01, 2019 4:14 am
by paroj
you can use the names in the material scripts as usual - just make sure that the textures are created before the material script is loaded.

Re: Create texture in code and use it in material scripts

Posted: Wed Jan 02, 2019 5:28 pm
by mogumbo
Hi Paraj. I don't see a usual place to use a texture name in the material scripts, only a texture filename. I probably should have specified that I'm using Ogre 1.9. Does that make a difference?

Re: Create texture in code and use it in material scripts

Posted: Wed Jan 02, 2019 5:33 pm
by paroj
this should also work in ogre 1.9. The filename is the same as the texture name.

Re: Create texture in code and use it in material scripts

Posted: Thu Jan 03, 2019 8:17 pm
by mogumbo
Thanks for the help. Ultimately, I couldn't get the texture to be created before the materials because I'm doing all this in Gazebo and I don't have control over when my plugin initializes. My solution is to let the plugin search every material for texture_units with a specific name and apply the texture to those. This gives me good flexibility within material scripts, and I only had to add this code block:

Code: Select all

  // Assign our dynamic texture wherever it is required
  // Ogre materials are all created before the a visual plugin constructor is
  // called. So a named texture created in the plugin cannot be referenced by
  // any Ogre material. The solution here is to search for TextureUnitStates
  // with the right name and assign our dynamic texture.
  // I also tried using a world and model plugins, but their prerender callbacks
  // are never called. A system plugin is probably the wrong choice because it
  // is applied to gzclient and not gzserver and we want to do off-screen
  // rendering with gzserver.
  ResourceManager::ResourceMapIterator res_it = MaterialManager::getSingleton().getResourceIterator();
  while (res_it.hasMoreElements())
  {
    ResourcePtr resource = res_it.getNext();
    MaterialPtr material = resource.staticCast<Material>();
    Material::TechniqueIterator tech_it = material->getTechniqueIterator();
    while (tech_it.hasMoreElements())
    {
      Technique* technique = tech_it.getNext();
      Technique::PassIterator pass_it = technique->getPassIterator();
      while (pass_it.hasMoreElements())
      {
        Pass* pass = pass_it.getNext();
        TextureUnitState* tus = pass->getTextureUnitState(m_texture_unit_name);
        if (tus != 0)
        {
          tus->setTexture(m_cubemap_filter->getTexture());
        }
      }
    }
  }