void C4DefGraphics::Draw(C4Facet &cgo, DWORD iColor, C4Object *pObj, int32_t iPhaseX, int32_t iPhaseY, C4DrawTransform* trans) { // default: def picture rect C4Rect fctPicRect = pDef->PictureRect; C4Facet fctPicture; // if assigned: use object specific rect and graphics if (pObj) if (pObj->PictureRect.Wdt) fctPicRect = pObj->PictureRect; // specific object color? if (pObj) pObj->PrepareDrawing(); switch(Type) { case C4DefGraphics::TYPE_None: // Def has no graphics break; case C4DefGraphics::TYPE_Bitmap: fctPicture.Set(GetBitmap(iColor),fctPicRect.x,fctPicRect.y,fctPicRect.Wdt,fctPicRect.Hgt); fctPicture.DrawTUnscaled(cgo,true,iPhaseX,iPhaseY,trans); break; case C4DefGraphics::TYPE_Mesh: // TODO: Allow rendering of a mesh directly, without instance (to render pose; no animation) std::unique_ptr<StdMeshInstance> dummy; StdMeshInstance* instance; C4Value value; if (pObj) { instance = pObj->pMeshInstance; pObj->GetProperty(P_PictureTransformation, &value); } else { dummy.reset(new StdMeshInstance(*Mesh, 1.0f)); instance = dummy.get(); pDef->GetProperty(P_PictureTransformation, &value); } StdMeshMatrix matrix; if (C4ValueToMatrix(value, &matrix)) pDraw->SetMeshTransform(&matrix); pDraw->SetPerspective(true); pDraw->RenderMesh(*instance, cgo.Surface, cgo.X,cgo.Y, cgo.Wdt, cgo.Hgt, pObj ? pObj->Color : iColor, trans); pDraw->SetPerspective(false); pDraw->SetMeshTransform(NULL); break; } if (pObj) pObj->FinishedDrawing(); // draw overlays if (pObj && pObj->pGfxOverlay) for (C4GraphicsOverlay *pGfxOvrl = pObj->pGfxOverlay; pGfxOvrl; pGfxOvrl = pGfxOvrl->GetNext()) if (pGfxOvrl->IsPicture()) pGfxOvrl->DrawPicture(cgo, pObj, trans); }
void C4DefGraphicsPtrBackup::AssignRemoval() { // Reset all mesh materials to what they were before the update MeshMaterialUpdate.Cancel(); UpdateMeshes(); // only if graphics are assigned if (pGraphicsPtr) { // check all objects for (C4Object *pObj : Objects) if (pObj && pObj->Status) { if (pObj->pGraphics == pGraphicsPtr) { // same graphics found. If these are mesh graphics then remove // the object because the StdMesh has already been unloaded. if(pObj->pMeshInstance) { assert(&pObj->pMeshInstance->GetMesh() == &pMeshUpdate->GetOldMesh()); pObj->AssignRemoval(); delete pObj->pMeshInstance; pObj->pMeshInstance = NULL; pObj->pGraphics = NULL; } // sprite graphics; reset them else if (!pObj->SetGraphics()) { pObj->AssignRemoval(); pObj->pGraphics=NULL; } } // remove any overlay graphics for (;;) { C4GraphicsOverlay *pGfxOverlay; for (pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext()) if (pGfxOverlay->GetGfx() == pGraphicsPtr) { // then remove this overlay and redo the loop, because iterator has become invalid pObj->RemoveGraphicsOverlay(pGfxOverlay->GetID()); break; } // looped through w/o removal? if (!pGfxOverlay) break; } // remove menu frame decorations C4GUI::FrameDecoration *pDeco; if (pDef && pObj->Menu && (pDeco = pObj->Menu->GetFrameDecoration())) if (pDeco->idSourceDef == pDef->id) pObj->Menu->SetFrameDeco(NULL); } // done; reset field to indicate finished update pGraphicsPtr = NULL; } // check next graphics if (pNext) pNext->AssignRemoval(); }
void C4DefGraphicsPtrBackup::AssignUpdate() { // Update mesh materials for all meshes for(C4DefList::Table::iterator iter = Definitions.table.begin(); iter != Definitions.table.end(); ++iter) if(iter->second->Graphics.Type == C4DefGraphics::TYPE_Mesh) MeshMaterialUpdate.Update(iter->second->Graphics.Mesh); // Then, update mesh references in instances, attach bones by name, and update sprite gfx for(std::list<C4DefGraphicsPtrBackupEntry*>::iterator iter = Entries.begin(); iter != Entries.end(); ++iter) (*iter)->AssignUpdate(); // Update mesh materials and animations for all mesh instances. for (C4Object *pObj : Objects) { if (pObj && pObj->Status) { if(pObj->pMeshInstance) UpdateMesh(pObj->pMeshInstance); for (C4GraphicsOverlay* pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext()) if(pGfxOverlay->pMeshInstance) UpdateMesh(pGfxOverlay->pMeshInstance); } } fApplied = true; }
void C4DefGraphicsPtrBackupEntry::UpdateAttachedMeshes() { for (C4Object *pObj : Objects) { if (pObj && pObj->Status) { if(pObj->pMeshInstance) UpdateAttachedMesh(pObj->pMeshInstance); for (C4GraphicsOverlay* pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext()) if(pGfxOverlay->pMeshInstance) UpdateAttachedMesh(pGfxOverlay->pMeshInstance); } } }
void C4DefGraphicsPtrBackup::UpdateMeshes() { // Update mesh materials for all meshes for(C4DefList::Table::iterator iter = Definitions.table.begin(); iter != Definitions.table.end(); ++iter) if(iter->second->Graphics.Type == C4DefGraphics::TYPE_Mesh) MeshMaterialUpdate.Update(iter->second->Graphics.Mesh); // Update mesh materials for all mesh instances. for (C4Object *pObj : Objects) { if (pObj && pObj->Status) { if(pObj->pMeshInstance) UpdateMesh(pObj->pMeshInstance); for (C4GraphicsOverlay* pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext()) if(pGfxOverlay->pMeshInstance) UpdateMesh(pGfxOverlay->pMeshInstance); } } }
void C4DefGraphicsPtrBackupEntry::AssignUpdate() { // Update all attached meshes that were using this mesh UpdateAttachedMeshes(); // only if graphics are assigned if (pGraphicsPtr) { // check all objects for (C4Object *pObj : Objects) { if (pObj && pObj->Status) { if (pObj->pGraphics == pGraphicsPtr) { // same graphics found. Update mesh graphics if any. if(pMeshUpdate) { assert(pObj->pMeshInstance != NULL); // object had mesh graphics, so mesh instance should be present assert(&pObj->pMeshInstance->GetMesh() == &pMeshUpdate->GetOldMesh()); // mesh instance of correct type even // Get new mesh from reloaded graphics C4DefGraphics *pGrp = pDef->Graphics.Get(Name); if(pGrp && pGrp->Type == C4DefGraphics::TYPE_Mesh) pMeshUpdate->Update(pObj->pMeshInstance, *pGrp->Mesh); } // try to set new graphics if (!pObj->SetGraphics(Name, pDef)) if (!pObj->SetGraphics(Name, pObj->Def)) { // shouldn't happen pObj->AssignRemoval(); pObj->pGraphics=NULL; } } // remove any overlay graphics for (;;) { C4GraphicsOverlay *pGfxOverlay; for (pGfxOverlay = pObj->pGfxOverlay; pGfxOverlay; pGfxOverlay = pGfxOverlay->GetNext()) if (pGfxOverlay->GetGfx() == pGraphicsPtr) { // then remove this overlay and redo the loop, because iterator has become invalid pObj->RemoveGraphicsOverlay(pGfxOverlay->GetID()); break; } // looped through w/o removal? if (!pGfxOverlay) break; } // update menu frame decorations - may do multiple updates to the same deco if multiple menus share it... C4GUI::FrameDecoration *pDeco; if (pDef && pObj->Menu && (pDeco = pObj->Menu->GetFrameDecoration())) if (pDeco->idSourceDef == pDef->id) if (!pDeco->UpdateGfx()) pObj->Menu->SetFrameDeco(NULL); } } // done; reset field to indicate finished update pGraphicsPtr = NULL; } }
void C4GraphicsOverlayListAdapt::CompileFunc(StdCompiler *pComp) { bool fNaming = pComp->hasNaming(); if (pComp->isCompiler()) { // clear list delete [] pOverlay; pOverlay = NULL; // read the whole list C4GraphicsOverlay *pLast = NULL; bool fContinue; do { C4GraphicsOverlay *pNext = new C4GraphicsOverlay(); try { // read an overlay pComp->Value(*pNext); } catch (StdCompiler::NotFoundException *e) { delete e; // delete unused overlay delete pNext; pNext = NULL; // clear up if (!pLast) pOverlay = NULL; // done return; } // link it if (pLast) pLast->SetNext(pNext); else pOverlay = pNext; // step pLast = pNext; // continue? if (fNaming) fContinue = pComp->Separator(StdCompiler::SEP_SEP2) || pComp->Separator(StdCompiler::SEP_SEP); else pComp->Value(fContinue); } while (fContinue); } else { // write everything bool fContinue = true; for (C4GraphicsOverlay *pPos = pOverlay; pPos; pPos = pPos->GetNext()) { // separate if (pPos != pOverlay) { if (fNaming) pComp->Separator(StdCompiler::SEP_SEP2); else pComp->Value(fContinue); } // write pComp->Value(*pPos); } // terminate if (!fNaming) { fContinue = false; pComp->Value(fContinue); } } }