Add image shader from BuildShaderPopupMenuI



  • On 04/09/2017 at 01:36, xxxxxxxx wrote:

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

    ---------
    Hello.

    I use the following code to create a shader list pop up menu when I press a button.
    This button is in a ShaderData plugin's description.

    BaseContainer shader_list;
    BuildShaderPopupMenuI(&shader_list, NULL, NULL, 0);
    Int32 res_option = ShowPopupMenu(NULL, MOUSEPOS, MOUSEPOS, bc);
    BaseShader* parent = static_cast<BaseShader*>(Get());
    BaseShader* result_shader = NULL;
    HandleShaderPopupI(parent, result_shader, res_option, 0 );
    if (result_shader)
    	//do something
    

    The problem is that when I press Load Image from the shader list, HandleShaderPopupI cannot use it.
    So it seems I have to remove the first options from shader_list container that are related to images.
    Is this why you need a separate Add Image button in Layer Shader ?
    Can I use only one button to add a shader regardless its type ?

    Edit: Another thing that I would like to say is that if parent is NULL, the result_shader is NULL as well. How can I get the parent BaseList2D of an iCustomGui in order to use the above code in the custom gui ?

    Thank you for your time.



  • On 04/09/2017 at 02:11, xxxxxxxx wrote:

    Hello,

    this is some test code that works perfectly fine for me with "Load Image":

      
    BaseMaterial* material = doc->GetActiveMaterial();  
    if (!material)  
      return false;  
      
    // get shader list  
    BaseContainer shaderList;  
    BuildShaderPopupMenuI(&shaderList, nullptr, nullptr, 0);  
      
    // remove "Clear"  
    shaderList.RemoveData(SHADERPOPUP_CLEARSHADER);  
      
    // show shader list  
    Int32 res = ShowPopupMenu(nullptr, MOUSEPOS, MOUSEPOS, shaderList);  
      
    // handle result  
    BaseShader* shader = nullptr;  
    if (HandleShaderPopupI(material, shader, res, 0) && shader)  
    {  
      BaseShader* clone = static_cast<BaseShader*>(shader->GetClone(COPYFLAGS_0, nullptr));  
      
      // insert shader  
      material->InsertShader(clone);  
      material->SetParameter(DescID(MATERIAL_COLOR_SHADER), clone, DESCFLAGS_SET_0);  
      
      EventAdd();  
    }  
    

    What exactly does not work for you? If the default menu of BuildShaderPopupMenuI() does not fit for your needs you can of course build a complete custom menu (but then of course you cannot use HandleShaderPopupI()).

    best wishes,
    Sebastian



  • On 04/09/2017 at 04:23, xxxxxxxx wrote:

    Hello and thank you for the example.

    My mistake was that I didn't check the returned value of HandleShaderPopupI.
    But, why do you have to clone the shader ?
    Doesn't the shader already belong in the material ? Since material is the first parameter in HandleShaderpopupI, it should already be the parent of that shader right ?

    Thank you again !


Log in to reply