void C4GraphicsOverlay::Draw(C4TargetFacet &cgo, C4Object *pForObj, int32_t iByPlayer) { assert(!IsPicture()); assert(pForObj); // get target pos float offX, offY; float newzoom; pForObj->GetDrawPosition(cgo, offX, offY, newzoom); ZoomDataStackItem zdsi(newzoom); // special blit mode if (dwBlitMode == C4GFXBLIT_PARENT) (OverlayObj ? static_cast<C4Object*>(OverlayObj) : pForObj)->PrepareDrawing(); else { pDraw->SetBlitMode(dwBlitMode); if (dwClrModulation != 0xffffff) pDraw->ActivateBlitModulation(dwClrModulation); if (pMeshInstance) pMeshInstance->SetFaceOrderingForClrModulation(dwClrModulation); } if (eMode == MODE_Rank) { C4TargetFacet ccgo; ccgo.Set(cgo.Surface, offX+pForObj->Shape.x,offY+pForObj->Shape.y,pForObj->Shape.Wdt,pForObj->Shape.Hgt, cgo.TargetX, cgo.TargetY); DrawRankSymbol(ccgo, OverlayObj); } // drawing specific object? else if (OverlayObj) { // TODO: Shouldn't have called PrepareDrawing/set ClrModulation here, since // OverlayObj drawing will do it on its own. if (eMode == MODE_ObjectPicture) { C4Facet fctTarget; fctTarget.Set(cgo.Surface, offX+pForObj->Shape.x, offY+pForObj->Shape.y, pForObj->Shape.Wdt, pForObj->Shape.Hgt); OverlayObj->DrawPicture(fctTarget, false, &C4DrawTransform(Transform, fctTarget.X+float(fctTarget.Wdt)/2, fctTarget.Y+float(fctTarget.Hgt)/2)); } else { // Draw specified object at target pos of this object; offset by transform. OverlayObj->Draw(cgo, iByPlayer, C4Object::ODM_Overlay, offX + Transform.GetXOffset(), offY + Transform.GetYOffset()); OverlayObj->DrawTopFace(cgo, iByPlayer, C4Object::ODM_Overlay, offX + Transform.GetXOffset(), offY + Transform.GetYOffset()); } } else if (eMode == MODE_ExtraGraphics) { // draw self with specified gfx if (pSourceGfx) { C4DefGraphics *pPrevGfx = pForObj->GetGraphics(); C4DrawTransform *pPrevTrf = pForObj->pDrawTransform; C4DrawTransform trf; if (pPrevTrf) { trf = *pPrevTrf; trf *= Transform; } else { trf = Transform; } pForObj->SetGraphics(pSourceGfx, true); pForObj->pDrawTransform = &trf; pForObj->Draw(cgo, iByPlayer, C4Object::ODM_BaseOnly); pForObj->DrawTopFace(cgo, iByPlayer, C4Object::ODM_BaseOnly); pForObj->SetGraphics(pPrevGfx, true); pForObj->pDrawTransform = pPrevTrf; } } else if(eMode == MODE_Picture || eMode == MODE_IngamePicture) { float twdt, thgt; if (fZoomToShape) { twdt = pForObj->Shape.Wdt; thgt = pForObj->Shape.Hgt; } else { twdt = pSourceGfx->pDef->Shape.Wdt; thgt = pSourceGfx->pDef->Shape.Hgt; } C4TargetFacet ccgo; ccgo.Set(cgo.Surface, offX-twdt/2, offY-thgt/2, twdt, thgt, cgo.TargetX, cgo.TargetY); C4DrawTransform trf(Transform, offX, offY); // Don't set pForObj because we don't draw the picture of pForObj, but the picture of another definition on top of pForObj: pSourceGfx->Draw(ccgo, pForObj->Color, NULL, iPhase, 0, &trf); } else { // no object specified: Draw from fctBlit // update by object color if (fctBlit.Surface) fctBlit.Surface->SetClr(pForObj->Color); if (!pMeshInstance) { // draw there C4DrawTransform trf(Transform, offX, offY); if (fZoomToShape) { float fZoom = std::min(pForObj->Shape.Wdt / std::max(fctBlit.Wdt, 1.0f), pForObj->Shape.Hgt / std::max(fctBlit.Hgt, 1.0f)); trf.ScaleAt(fZoom, fZoom, offX, offY); } fctBlit.DrawT(cgo.Surface, offX - fctBlit.Wdt/2 + fctBlit.TargetX, offY - fctBlit.Hgt/2 + fctBlit.TargetY, iPhase, 0, &trf); } else { C4Def *pDef = pSourceGfx->pDef; // draw there C4DrawTransform trf(Transform, offX, offY); if (fZoomToShape) { float fZoom = std::min((float)pForObj->Shape.Wdt / std::max(pDef->Shape.Wdt, 1), (float)pForObj->Shape.Hgt / std::max(pDef->Shape.Hgt, 1)); trf.ScaleAt(fZoom, fZoom, offX, offY); } C4Value value; pDef->GetProperty(P_MeshTransformation, &value); StdMeshMatrix matrix; if (C4ValueToMatrix(value, &matrix)) pDraw->SetMeshTransform(&matrix); pDraw->RenderMesh(*pMeshInstance, cgo.Surface, offX - pDef->Shape.Wdt/2.0, offY - pDef->Shape.Hgt/2.0, pDef->Shape.Wdt, pDef->Shape.Hgt, pForObj->Color, &trf); pDraw->SetMeshTransform(NULL); } } // cleanup if (dwBlitMode == C4GFXBLIT_PARENT) (OverlayObj ? static_cast<C4Object*>(OverlayObj) : pForObj)->FinishedDrawing(); else { pDraw->ResetBlitMode(); pDraw->DeactivateBlitModulation(); } }
void C4GraphicsOverlay::UpdateFacet() { // special: Nothing to update for object and pSourceGfx may be NULL // If there will ever be something to init here, UpdateFacet() will also need to be called when objects have been loaded if (eMode == MODE_Object) return; // otherwise, source graphics must be specified if (!pSourceGfx) return; C4Def *pDef = pSourceGfx->pDef; assert(pDef); fZoomToShape = false; // Clear old mesh instance, if any delete pMeshInstance; pMeshInstance = NULL; // update by mode switch (eMode) { case MODE_None: break; case MODE_Base: // def base graphics if (pSourceGfx->Type == C4DefGraphics::TYPE_Bitmap) fctBlit.Set(pSourceGfx->GetBitmap(), 0, 0, pDef->Shape.Wdt, pDef->Shape.Hgt, pDef->Shape.x+pDef->Shape.Wdt/2, pDef->Shape.y+pDef->Shape.Hgt/2); else if (pSourceGfx->Type == C4DefGraphics::TYPE_Mesh) pMeshInstance = new StdMeshInstance(*pSourceGfx->Mesh, 1.0f); break; case MODE_Action: // graphics of specified action { // Clear old facet fctBlit.Default(); // Ensure there is actually an action set if (!Action[0]) return; C4Value v; pDef->GetProperty(P_ActMap, &v); C4PropList *actmap = v.getPropList(); if (!actmap) return; actmap->GetPropertyByS(::Strings.RegString(Action), &v); C4PropList *action = v.getPropList(); if (!action) return; if (pSourceGfx->Type == C4DefGraphics::TYPE_Bitmap) { fctBlit.Set(pSourceGfx->GetBitmap(), action->GetPropertyInt(P_X), action->GetPropertyInt(P_Y), action->GetPropertyInt(P_Wdt), action->GetPropertyInt(P_Hgt)); // FIXME: fctBlit.TargetX has to be set here } else if (pSourceGfx->Type == C4DefGraphics::TYPE_Mesh) { C4String* AnimationName = action->GetPropertyStr(P_Animation); if (!AnimationName) return; pMeshInstance = new StdMeshInstance(*pSourceGfx->Mesh, 1.0f); const StdMeshAnimation* Animation = pSourceGfx->Mesh->GetSkeleton().GetAnimationByName(AnimationName->GetData()); if (!Animation) return; pMeshInstance->PlayAnimation(*Animation, 0, NULL, new C4ValueProviderRef<int32_t>(iPhase, ftofix(Animation->Length / action->GetPropertyInt(P_Length))), new C4ValueProviderConst(itofix(1)), true); } break; } case MODE_ObjectPicture: // ingame picture of object // calculated at runtime break; case MODE_IngamePicture: case MODE_Picture: // def picture fZoomToShape = true; // drawn at runtime break; case MODE_ExtraGraphics: // like ColorByOwner-sfc // calculated at runtime break; case MODE_Rank: // drawn at runtime break; case MODE_Object: // TODO break; } }