我创建了一个简单的 Direct2D Effect,它可以翻转传入的图像(可以水平或垂直翻转或同时翻转)。自定义效果看起来效果不错。当我尝试将效果的两个实例依次链接时,问题就开始了:
ID2D1Effect *flip1; // initialized
ID2D1Effect *flip2; // initialized
ID2D1Bitmap1 *bmp; // initialized
flip1->SetInput(0, bmp);
flip2->SetInputEffect(0, flip1);
// ...
ID2D1DeviceContext *pContext; // initialized
pContext->BeginDraw();
pContext->DrawImage(flip2);
pContext->EndDraw();
因此,我有时会得到“垃圾”图像作为输出。我注意到,只要将“第二个”翻转配置为保持图像不变,该链就可以工作。当第二次翻转修改图像时,我将整个或部分目标图像“垃圾化”。 我的怀疑是,由于翻转效果使用复杂的采样(像素
xy
的目标颜色取决于不同位置的原始像素),第二个翻转效果以某种方式尝试访问第一个翻转的输出像素,这不是准备好了。
这个假设有道理吗?有办法避免吗?我总是有一个后备方案,即在不同的目标位图上渲染每个效果,但我认为这比简单地将效果链接在一起需要更长的时间。
class foo
{
public:
static int cls_counter;
foo()
{
static int func_counter;
int obj_counter = 0;
// some code that affects the three variables
++cls_counter;
++func_counter;
++obj_counter;
}
};
int foo::clss_counter = 0;
foo fighter1; // obj_counter last value 1, foo::foo::func_counter = 1, foo::cls_counter = 1
foo fighter2; // obj_counter last value 1, foo::foo::func_counter = 2, foo::cls_counter = 2
foo fighter3; // obj_counter last value 1, foo::foo::func_counter = 3, foo::cls_counter = 3
如果失败,请暂时返回绘图板,将自定义效果的内部逻辑和结果与此代码进行比较。
dvctxt->BeginDraw();
// clear any previous errors
dvctxt->Flush();
// always reset to the bgnd buffer
dvctxt->SetTarget(hwnd_bgnd_bmp1);
// optional
dvctxt->Clear(bgnd_colr);
// optional
dvctxt->DrawBitmap(bgnd_bmp1);
// always default to the identity matrix or a preferred matrix before drawing
D2D1_MATRIX_3x2_F final_mtrx = D2D1::Matrix3x2F::Identity();
float hsize = 1.0f;
float vsize = 1.0f;
if (flag_hflip || flag_vflip)
{
if (flag_hflip) { hsize = -1.0f; }
if (flag_vflip) { vsize = -1.0f; }
D2D1_POINT_2F scale_pt = { 0.0f };
final_mtrx = D2D1::Martix3x2F::Scale(hsize, vsize, scale_pt);
}
dvctxt->SetTransform(&final_mtrx);
dvctxt->DrawImage(src_image);
// draw overlays
dvctxt->EndDraw();
// external BeginDraw()...EndDraw() overlays
swp_chain->Present(0,0);