How to get material preview my renderer
-
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://developers.maxon.net/forum/topic/9639/12945_render-material-preview-in-custom-renderer&KW=custom+render&PID=51246#51246
https://developers.maxon.net/forum/topic/9094/12074_matpreview-popup-show-custom-scenes&KW=AddUserPreviewScene&PID=47829#47829
https://developers.maxon.net/forum/topic/8833/11670_matpreviewgenerateimage-with-custom-renderer&KW=material+preview&PID=46019#46019
https://developers.maxon.net/forum/topic/9639/12945_render-material-preview-in-custom-renderer&KW=MATPREVIEW_MODIFY_CACHE_SCENE&PID=51274#51274MATPREVIEW_GET_OBJECT_INFO
MATPREVIEW_MODIFY_CACHE_SCENE
MATPREVIEW_PREPARE_SCENE
MATPREVIEW_GENERATE_IMAGEI'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 -
On 22/03/2018 at 23:53, xxxxxxxx wrote:
Hi Makoto, thanks for writing us.
With reference to the issue reported and considering the code shared, I suppose the issue is likely to be related to what your rendering engine receives (in terms of scene) when attempting to generate a material preview. What scene actually are you passing to your render in the videopost data? Have you tried to close the active document and try to generate the material preview?
Looking forward your answer, give best.
Riccardo -
On 23/03/2018 at 11:28, xxxxxxxx wrote:
Thank you knickknack.
In your advice, I noticed my mistake!I used GetActiveDocument () on VideoPost Execute.
I was stupid...Just I did clean up my code and it worked well.
Really thanks a million!!
Cheers
Makoto