On 21/03/2018 at 01:33, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 19.053
Platform: Windows ;
Language(s) : C++ ;
---------
I'm trying to implement my own renderer, And I creating a material plugin for own renderer.
Now, I'm doing some simple test, most of the code is referenced on the simplematerial.cpp plugin.
I want to display the rendered result of the custom renderer in the preview of my material plugin.
I found some similar topic.
https://plugincafe.maxon.net/topic/9639/12945_render-material-preview-in-custom-renderer&KW=custom+render&PID=51246#51246
https://plugincafe.maxon.net/topic/9094/12074_matpreview-popup-show-custom-scenes&KW=AddUserPreviewScene&PID=47829#47829
https://plugincafe.maxon.net/topic/8833/11670_matpreviewgenerateimage-with-custom-renderer&KW=material+preview&PID=46019#46019
https://plugincafe.maxon.net/topic/9639/12945_render-material-preview-in-custom-renderer&KW=MATPREVIEW_MODIFY_CACHE_SCENE&PID=51274#51274
MATPREVIEW_GET_OBJECT_INFO
MATPREVIEW_MODIFY_CACHE_SCENE
MATPREVIEW_PREPARE_SCENE
MATPREVIEW_GENERATE_IMAGE
I'm changing these codes.
In the MATPREVIEW_GET_OBJECT_INFO, bNoStandardScene is set to True and the scene is being rebuilt within MATPREVIEW_MODIFY_CACHE_SCENE.
Here, just add a sphere and set to texture tag, and add a camera.
Next, MATPREVIEW_PREPARE_SCENE sets the material as a sphere texture tag's material link.
Code here.
switch (type)
{
case MATPREVIEW_GET_OBJECT_INFO:
{
GePrint("MATPREVIEW_GET_OBJECT_INFO");
MatPreviewObjectInfo* info = (MatPreviewObjectInfo* )data;
info->bHandlePreview = true; // own preview handling
info->bNeedsOwnScene = true; // we need our own entry in the preview scene cache
info->bNoStandardScene = true; // we modify the standard scene
info->lFlags = 0;
return true;
break;
}
case MATPREVIEW_MODIFY_CACHE_SCENE:
// modify the preview scene here. We have a pointer to a scene inside the preview scene cache.
// our scene contains the object
{
GePrint("MATPREVIEW_MODIFY_CACHE_SCENE");
MatPreviewModifyCacheScene* scene = (MatPreviewModifyCacheScene* )data;
BaseObject* obj = BaseObject::Alloc(Osphere);
obj->GetDataInstance()->SetParameter(DescID(PRIM_SPHERE_TYPE), 4);
obj->GetDataInstance()->SetInt32(PRIM_SPHERE_SUB, 12);
obj->GetDataInstance()->SetBool(PRIM_SPHERE_PERFECT, false);
obj->SetName("Object");
BaseTag* mattag = obj->MakeTag(Ttexture);
if (!mattag) { return false; }
scene->pDoc->InsertObject(obj, nullptr, nullptr);
BaseObject* camera = BaseObject::Alloc(Ocamera);
Matrix dir = Matrix(Vector(0, 0, -300),Vector(0, 0, 0),Vector(0, 0, 0),Vector(0, 0, 0));
camera->SetMg(dir);
scene->pDoc->InsertObject(camera, nullptr, nullptr);
BaseDraw* bd = scene->pDoc->GetRenderBaseDraw();
bd->SetSceneCamera(camera, 0);
return true;
break;
}
case MATPREVIEW_PREPARE_SCENE:
{
// let the preview handle the rest...
GePrint("MATPREVIEW_PREPARE_SCENE");
MatPreviewPrepareScene* preparescene = (MatPreviewPrepareScene* )data;
AutoAlloc<AliasTrans> trans;
if (!trans) { return false; }
if (!trans->Init(GetActiveDocument())) { return false; }
BaseMaterial* matclone = (BaseMaterial* )(Get()->GetClone(COPYFLAGS_0, trans));
preparescene->pDoc->InsertMaterial(matclone);
trans->Translate(true);
if (preparescene->pLink)
preparescene->pLink->SetLink(matclone); // necessary
// find the environment object and set the material
BaseObject* obj = preparescene->pDoc->SearchObject("Object");
if (obj)
{
TextureTag* textag = (TextureTag* )obj->GetTag(Ttexture);
if (textag) { textag->SetMaterial(matclone); }
}
preparescene->bScenePrepared = true; // inform the preview that the scene is prepared now
return TRUE;
break;
}
case MATPREVIEW_GENERATE_IMAGE:
{
GePrint("MATPREVIEW_GENERATE_IMAGE");
MatPreviewGenerateImage* image = (MatPreviewGenerateImage* )data;
if (image->pDoc)
{
RenderData* rd = image->pDoc->GetActiveRenderData();
if (!rd) { return true; }
BaseVideoPost* post = BaseVideoPost::Alloc(ID_VPMYENGINE);
if (post)
{
rd->InsertVideoPost(post);
post->DelBit(BIT_VPDISABLED);
}
Int32 w = image->pDest->GetBw();
Int32 h = image->pDest->GetBh();
BaseContainer bcRender = image->pDoc->GetActiveRenderData()->GetData();
bcRender.SetFloat(RDATA_XRES, w);
bcRender.SetFloat(RDATA_YRES, h);
bcRender.SetInt32(RDATA_RENDERENGINE, ID_VPMYENGINE);
image->pDest->Clear(0, 0, 0);
image->lResult = RenderDocument(image->pDoc, bcRender, nullptr, nullptr, image->pDest,
RENDERFLAGS_EXTERNAL | RENDERFLAGS_PREVIEWRENDER, image->pThread);
}
return true;
break;
}
case MATPREVIEW_GET_PREVIEW_ID:
{
*((Int32* )data) = MYMATERIAL_MAT_PREVIEW;
return true;
}
However, when creating a new my material, render the open scene file and set the result to the material preview image.
When I set the MATPREVIEW_GENERATE_IMAGE renderer to Software, Standart, or Physical etc, I get a material preview the sphere in MATPREVIEW_MODIFY_CACHE_SCENE.
The issue is that my renderer does not render MATPREVIEW_MODIFY_CACHE_SCENE, but renders the scene I am editing and returns it to the material preview.
I maybe that the description of the custom renderer itself is wrong.
How to call, conditions of VideoPost::Exexcute, etc ...
RENDERRESULT VpMyEngine::Execute(BaseVideoPost* node, VideoPostStruct* vps) {
if (vps->vp == VIDEOPOSTCALL_RENDER && !vps->open && *vps->error == RENDERRESULT_OK && !vps->thread->TestBreak())
{
GePrint("call to Execute");
vps->vd->SkipRenderProcess();
// Start my renderer...
}
return RENDERRESULT_OK;
}
Could I get advice on where is wrong and whether it is highly likely?
Or, Could I know if the mistake is Material::Message side or VideoPost side?
Best Regards,
Makoto