我的新应用程序将具有丰富的界面,应该可以动态调整使用透明图标/图像等.对于这个应用程序,我正在尝试决定使用新的Direct2D API对抗旧的GDI.其中一个缺点当然是它不能在XP上运行,尽管我发现有一些更糟糕的问题需要决定:
我注意到在Direct2D环境中输出文本似乎有点模糊(虽然作为一个功能销售).只需查看启用了硬件加速(或IE9)的Firefox 4中的文本.这似乎是因为在Direct2D文本中不像GDI那样遵循(像素)网格.有没有办法强制Direct2D使其坚持像素网格,从而解决这个问题?
速度真的有这么大的提升吗?我试图理解这篇文章,我从中得到的是,在Windows 7和XP(而不是Vista?)中,GDI已经硬件加速了.例如,在我的应用程序中,我使用了很多内存DC,它们刚刚被BitBlt
编入到位,并且正在绘制使用的绘制透明图像/抗锯齿线等AlphaBlend
.最后一个肯定是硬件加速,因为我在测试我的例程时测量速度.
那你要把钱放在哪里?Direct2D是值得的麻烦还是你只是坚持好老的GDI?或者你会推荐别的吗?
注意:我用C++编程btw,没有使用MFC.
我出于性能原因试图将应用程序从GDI +移到Direct2D.
我以前在HALFTONE模式下使用StretchBlt(),这会产生很好但很慢的结果.
现在我使用RenderTarget-> DrawBitmap()绘制Direct2D,但它只有两种模式,LINEAR和NEAREST_NEIGHBOR,两者都不是很好.LINEAR更好,但仍会产生可怕的文物.
Direct2D有任何高质量的缩放选项吗?如果没有,我最好坚持使用GDI还是有其他选择?这是一个在带有各种Win32控件的窗口中运行的Windows应用程序.
我目前正在更新 Windows GDI 应用程序以使用 Direct2D 渲染,我需要通过颜色键支持“透明”位图以实现向后兼容性。
现在我正在使用 HWND 渲染目标和转换后的 WIC 位图源(到 GUID_WICPixelFormat32bppPBGRA)。到目前为止,我的计划是从转换后的位图 Lock() 创建一个 IWICBitmap,然后处理每个像素,如果它与颜色键匹配,则将其 alpha 值设置为 0。
这似乎有点“蛮力” - 这是解决这个问题的最佳方法还是有更好的方法?
编辑:为了完整起见,这里是我使用的摘录 - 看起来它工作正常,但我愿意接受任何改进!
// pConvertedBmp contains a IWICFormatConverter* bitmap with the pixel
// format set to GUID_WICPixelFormat32bppPBGRA
IWICBitmap* pColorKeyedBmp = NULL;
HRESULT hr = S_OK;
UINT uBmpW = 0;
UINT uBmpH = 0;
pConvertedBmp->GetSize( &uBmpW, &uBmpH );
WICRect rcLock = { 0, 0, uBmpW, uBmpH };
// GetWIC() returns the WIC Factory instance in this app
hr = GetWIC()->CreateBitmapFromSource( …
Run Code Online (Sandbox Code Playgroud) 对于处理图像并将用C#编写的桌面Vista +应用程序,您会推荐以下哪种技术(或者您推荐的组合:System.Drawing(GDI +)vs System.Windows.Media vs Direct2D + DirectWrite + WIC.图像处理将涉及各种原始绘图,填充,处理文本,旋转,翻译,缩放,使用指针直接处理像素数据.一般来说,上述技术在操作位图方面有多好?
此外,如果有人知道一个好的和详细的比较图表,列出了并排的不同功能和等价物,以及不支持的,这将是伟大的!例如,WPF和Direct2D中是否存在ColorMatrix等价物?例如,在研究了SharpDX对Direct2D的实现后,我留下的印象是即使微软将其定位为GDI +的完全替代品,我也无法在Direct2D中找到所有GDI +的功能.
另外,考虑到它是2014年,你会说至少对于图像处理(如果不是UI的一部分,WPF似乎是一个更好的选择),GDI +在接下来的5年左右会好吗?或者我应该真的考虑使用所有3种技术,哪种方法效果最好?
谢谢.
在使用 GDI 进行图形的传统 Windows 程序中,您将不得不担心只绘制需要重绘的窗口区域;这是“更新矩形”,可PAINTSTRUCT.rcPaint
通过调用或调用GetUpdateRect()
. (这也可以HRGN
通过其他方式获得。)
我需要用 Direct2D 做同样的事情吗?MSDN 上的所有示例都只是随意绘制了整个客户区,而在线搜索并没有发现其他任何内容。
或者换句话说,如果我只在更新矩形内绘制,例如手动或使用PushAxisAlignedClip()
或,更新矩形之外的部分会发生什么不好的事情PushLayer()
?
此外,文档ID2D1HwndRenderTarget::Resize()
说
调用此方法后,即使在创建渲染目标时指定了 D2D1_PRESENT_OPTIONS_RETAIN_CONTENTS 选项,也不会定义渲染目标的后台缓冲区的内容。
这是否意味着,无论更新区域将通过(如所示通过调整引起的这幅画从这个网页)是无效的,我应该重新绘制整个窗口(例如,通过调用InvalidateRect(NULL)
)在一个调整大小?
谢谢。
我需要使用 Direct2D 创建一个透明位图,并使用我的设备上下文在其上绘制。
ID2D1DeviceContext1* d2dContext = ...
ID2D1Bitmap* pBitmap;
d2dContext->CreateBitmap(
bitmapSize,
nullptr,
0,
D2D1::BitmapProperties1(
D2D1_BITMAP_OPTIONS_TARGET,
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
dpiX, dpiY),
&pBitmap);
d2dContext->BeginDraw();
d2dContext->SetTarget(pBitmap);
d2dContext->Clear(D2D1::ColorF(0, 0));
d2dContext->DrawLine(...);
hr = d2dContext->EndDraw();
Run Code Online (Sandbox Code Playgroud)
不幸的是我无法创建任何透明位图。我尝试了几种像素格式组合,包括D2D1_ALPHA_MODE_STRAIGHT
,但没有成功。
有什么解决办法吗?
我是一位经验丰富的计算机图形程序员,主要使用Direct3D 9.0c,OpenGL和通用算法.目前,我正在评估Direct2D作为处理医学图像数据的专业应用程序的渲染技术.至于渲染,它是一个处于窗口模式的x64桌面应用程序(不是全屏).
在我最初的步骤中,我一直在努力完成一项任务,我认为这将是一个明智的选择:在屏幕上渲染单通道位图.
在Windows 8.1机器上运行时,我创建了一个ID2D1DeviceContext
带有Direct3D交换链缓冲区表面作为渲染目标.交换链是从HWND和缓冲区格式创建的DXGI_FORMAT_B8G8R8A8_UNORM
.注意:另请参阅最后的代码段.
然后,我创建了一个像素格式DXGI_FORMAT_R8_UNORM
和alpha模式的位图D2d1_ALPHA_MODE_IGNORE
.调用DrawBitmap(...)
设备上下文时,将使用调试消息"D2d DEBUG ERROR - 此操作与位图的像素格式不兼容"触发调试断点.
我知道这个输出很清楚.此外,更改像素格式时DXGI_FORMAT_R8G8B8A8_UNORM
使用DXGI_ALPHA_MODE_IGNORE
一切正常,我看到了位图呈现.但是,我简直不敢相信!从那时起,显卡就支持单通道纹理 - 每个3D图形应用程序都可以使用它们而无需考虑两次.这不用说.
我试图在谷歌找到任何东西,但没有成功.我能找到的唯一提示是带有(支持的像素格式)的MSDN Direct2D页面.文档建议 - 不提及它 - DXGI_FORMAT_R8_UNORM
确实不支持位图格式.我也发现帖子谈论alpha蒙版(使用DXGI_FORMAT_A8_UNORM
),但那不是我追求的.
我错过了什么,我不能说服Direct2D创建和绘制灰度位图?或者,Direct2D是否支持绘制R8或R16位图?
任何帮助都非常感谢,因为我不知道如何解决这个问题.如果我不能让这些琐碎的基础工作,我想我不得不停止深入研究Direct2D :-(.
以下是相关的代码片段.请注意,自从我将C++/CLI代码移植到普通C++后,它们可能无法编译.另外,我丢弃了所有错误检查和其他噪音:
设备,设备上下文和交换链创建(D3D和Direct2D):
// Direct2D factory creation
D2D1_FACTORY_OPTIONS options = {};
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
ID2D1Factory1* d2dFactory;
D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, options, &d2dFactory);
// Direct3D device creation
const auto type = D3D_DRIVER_TYPE_HARDWARE;
const auto flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
ID3D11Device* d3dDevice;
D3D11CreateDevice(nullptr, …
Run Code Online (Sandbox Code Playgroud) 我正在创建一个简单的Direct2D应用程序.不幸的是,它给出了一个未处理的例外.它发生的功能:
void DemoApp::OnResize(UINT width, UINT height)
{
if (m_pRenderTarget) <----|****The exception occurs here.....****
{
// Note: This method can fail, but it's okay to ignore the
// error here, because the error will be returned again
// the next time EndDraw is called.
m_pRenderTarget->Resize(D2D1::SizeU(width, height));
}
}
Run Code Online (Sandbox Code Playgroud)
调用OnResize()的代码片段是:
DemoApp *pDemoApp = reinterpret_cast<DemoApp *>(static_cast<LONG_PTR>(
::GetWindowLongPtrW(
hwnd,
GWLP_USERDATA
)));
bool wasHandled = false;
if (pDemoApp)
{
switch (message)
{
case WM_SIZE:
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam); …
Run Code Online (Sandbox Code Playgroud) 我正在使用C#中的一个小型2D游戏引擎,并决定使用Direct2D和DirectWrite进行渲染.我知道有Windows API Code Pack和SlimDX,但我真的很喜欢从头开始编写接口.我试图在没有托管C++的情况下这样做,但Direct2D和DirectWrite似乎没有使用传统的COM对象.它们定义了派生自的接口IUnknown
,但似乎没有办法从C#与COM互操作实际使用它们.有IID d2d1.h
,但没有CLSID.
当然,我是COM互操作的新手,所以也许我只是缺少一些东西.有人可以对这种情况有所了解吗?
所以,我有一个 Direct2D Matrix3x2F
,我用它来存储几何上的转换。我希望这些转换是用户可编辑的,并且我不希望用户必须直接编辑矩阵。是否可以将 3x2 矩阵分解为缩放、旋转、倾斜和平移?