Changing a uniform shader variable on the fly?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Viking86
Posts: 24
Joined: Tue Apr 20, 2010 2:29 pm

Changing a uniform shader variable on the fly?

Post by Viking86 »

Is it possible, I was planing to combine the slidebar from the tutorial no.5 with a shader. So that when that the user moves the slidebar the parameters of the shader change.

Can this be done?
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Of course, just send the value via setPixelShaderConstant or setVertexShaderConstant to the gpu.
Never take advice from someone who likes to give advice, so take my advice and don't take it.
ent1ty
Competition winner
Posts: 1106
Joined: Sun Nov 08, 2009 11:09 am

Post by ent1ty »

Some question on not an unrelated note: Can I set the shader constant callback thingy after the new material was with one of the methods in GPUProgrammingServices, or can it be only done when creating the new material type?
irrRenderer 1.0
Height2Normal v. 2.1 - convert height maps to normal maps

Step back! I have a void pointer, and I'm not afraid to use it!
Bate
Posts: 364
Joined: Sun Nov 01, 2009 11:39 pm
Location: Germany

Post by Bate »

Yeah, some kind of setCallback would be nice. I'm using the same material with different callback values for multiple nodes, so at the moment I have to create separate materials (which takes ages to load).
Never take advice from someone who likes to give advice, so take my advice and don't take it.
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

What about something like this, wouldn't it help?

Code: Select all

class ShaderMaterialControler : public video::IMaterialRenderer,
                                public video::IShaderConstantSetCallBack
{
   video::IMaterialRenderer *ShaderMaterialRenderer;
   const video::SMaterial *Material;

public:

   ShaderMaterialControler(video::IVideoDriver *driver, const c8 *vertexShaderFilename, const c8 *fragmentShaderFilename, s32 &materialID, const c8 *materialName)
   {
      video::IGPUProgrammingServices *services = driver->getGPUProgrammingServices();

      s32 mID = services->addHighLevelShaderMaterialFromFiles(
         vertexShaderFilename, "main", video::EVST_VS_1_1,
         fragmentShaderFilename, "main", video::EPST_PS_1_1,
         this, video::EMT_SOLID);

      materialID = driver->addMaterialRenderer(this, "materialName");

      ShaderMaterialRenderer = driver->getMaterialRenderer(mID);
   }

   virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
   {
      video::IVideoDriver* driver = services->getVideoDriver();

      if(driver->getDynamicLightCount() > 0)
      {
         u32 type = (u32)Device->getVideoDriver()->getDynamicLight(0).Type;
         services->setVertexShaderConstant("LightType0", (f32*)&type, 1);
      }
      if(driver->getDynamicLightCount() > 1)
      {
         u32 type = (u32)Device->getVideoDriver()->getDynamicLight(1).Type;
         services->setVertexShaderConstant("LightType1", (f32*)&type, 1);
      }
      if(driver->getDynamicLightCount() > 2)
      {
         u32 type = (u32)Device->getVideoDriver()->getDynamicLight(2).Type;
         services->setVertexShaderConstant("LightType2", (f32*)&type, 1);
      }
   }

   void OnSetMaterial(const video::SMaterial& material, const video::SMaterial& lastMaterial,
      bool resetAllRenderstates, video::IMaterialRendererServices* services)
   {
      Material = &material;
      ShaderMaterialRenderer->OnSetMaterial(material, lastMaterial, resetAllRenderstates, services);
   }

   bool OnRender(video::IMaterialRendererServices *services, video::E_VERTEX_TYPE vtxtype)
   {
      return ShaderMaterialRenderer->OnRender(services, vtxtype);
   }

   void OnUnsetMaterial()
   {
      ShaderMaterialRenderer->OnUnsetMaterial();
   }

   bool isTransparent()
   {
      return ShaderMaterialRenderer->isTransparent();
   }

   s32 getRenderCapability()
   {
      return ShaderMaterialRenderer->getRenderCapability();
   }
};
Viking86
Posts: 24
Joined: Tue Apr 20, 2010 2:29 pm

Post by Viking86 »

Thank you, I made it like this
declare a global variable for the parameter
pass that variable as a uniform to the shader

Make an event receiver in which key presses modify the global variable.
Voila :)
Post Reply