Material Plugin

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 20/02/2010 at 10:07, xxxxxxxx wrote:

User Information:
Cinema 4D Version:   11.5 
Platform:   Windows  ;   
Language(s) :     C++  ;

---------
I am trying to create a MaterialData plugin.   I have included a Shaderlink in to a channel.   I would like that when the user selects and option afrom that shader link, that choice becomes the surface of the material.  FOr example, if they choose and image, I would like that image to become the surface of the material.  How do I go about doing this?  I assume this is done in CalcSurface().    Is there an example in the SDK that shows how to accomplish this?

Thanks,

~Shawn

THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

On 24/02/2010 at 02:24, xxxxxxxx wrote:

Yes, you have to overwrite CalcSurface(). To sample the shader link use PluginShader::Sample(). You have to generate the texure projection manually. See the example code of TexData in the SDK docu.

here a simple example, it samples a shader using UV projection (make sure the texture tag is set to UVW projection) :

  
/////////////////////////////////////////////////////////////  
// CINEMA 4D SDK                                           //  
/////////////////////////////////////////////////////////////  
// (c) 1989-2004 MAXON Computer GmbH, all rights reserved  //  
/////////////////////////////////////////////////////////////  
  
// volumetric shader example that accesses particles and displays its own preview  
// absolutely not optimized for speed  
  
#include "c4d.h"  
#include "c4d_symbols.h"  
  
#include "mparticlevolume.h"  
  
  
class ParticleVolume : public MaterialData  
{  
  public:  
      virtual Bool Init(GeListNode *node);  
  
      virtual    LONG GetRenderInfo(PluginMaterial *mat) { return 0; }  
  
      virtual LONG InitRender(PluginMaterial *mat, InitRenderStruct *irs);  
      virtual void FreeRender(PluginMaterial *mat);  
  
      virtual    void CalcSurface(PluginMaterial *mat, VolumeData *vd);  
  
      static NodeData *Alloc(void) { return gNew ParticleVolume; }  
  
  private:  
      PluginShader *shader;  
};  
  
Bool ParticleVolume::Init(GeListNode *node)  
{  
  shader=NULL;  
  
  BaseContainer *data = ((PluginShader* )node)->GetDataInstance();  
  
  data->SetLink(MY_SHADER, NULL);  
  
  return TRUE;  
}  
  
LONG ParticleVolume::InitRender(PluginMaterial *mat, InitRenderStruct *irs)  
{  
  BaseContainer *data = mat->GetDataInstance();  
  
//    cd.t = irs->time.Get();  
  
  shader  = (PluginShader* )data->GetLink(MY_SHADER,irs->doc,Xbase);  
  if (shader) return shader->InitRender(irs);  
  
  return LOAD_OK;  
}  
  
void ParticleVolume::FreeRender(PluginMaterial *mat)  
{  
  if (shader) shader->FreeRender();  
  shader=NULL;  
}  
  
void ParticleVolume::CalcSurface(PluginMaterial *mat, VolumeData *vd)  
{  
  vd->trans = 0.0;  
  
  ChannelData cd(vd);  
  
  Vector uv;  
  
  cd.p = vd->GetPointUVW(vd->tex, vd->lhit, vd->p);  
  
  if (shader)  
  {  
      vd->col = shader->Sample(&cd);  
  }  
}  
  
  
// be sure to use a unique ID obtained from www.plugincafe.com  
#define ID_PARTICLEVOLUME    1001163  
  
Bool RegisterParticleVolume(void)  
{  
  // decide by name if the plugin shall be registered - just for user convenience  
  String name=GeLoadString(IDS_PARTICLEVOLUME); if (!name.Content()) return TRUE;  
  
  name = GeGetDefaultFilename(DEFAULTFILENAME_SHADER_VOLUME)+name; // place in default Shader section  
  
  return RegisterMaterialPlugin(ID_PARTICLEVOLUME,name,0,ParticleVolume::Alloc,"MParticleVolume",0);  
}  

cheers,
Matthias