How to work with pixels using Direct2D

Can someone provide an example of an efficient way to work with pixels using Direct2D?

For example, how can I swap all green pixels ( RGB = 0x00FF00 ) with red pixels ( RGB = 0xFF0000 ) for rendering purposes? What is the standard approach? Can I use ID2D1HwndRenderTarget for this? Here I propose to use some kind of hardware acceleration. Should I create another object for manipulating direct pixels?

Using DirectDraw, I would use the BltFast method on IDirectDrawSurface7 with a logical operation. Is there something similar with Direct2D?

Another task is to generate complex images dynamically, where each location and color of a point is the result of a mathematical function. For example, we simplify everything and draw Y = X ^ 2 . How to do this with Direct2D? In the end, I will have to draw complex functions, but if someone can give me a simple example for Y = X ^ 2 .

+6
source share
3 answers

Firstly, it helps to think of ID2D1Bitmap as a “device bitmap”. It may or may not work in the local memory addressed by the CPU, and does not give you a convenient (or at least fast) way to read / write pixels from the side of the bus processor. Therefore, approaching from this angle is probably the wrong approach.

I think what you want is a regular WIC bitmap, IWICBitmap, which you can create using IWICImagingFactory :: CreateBitmap (). From there, you can call Lock () to get in the buffer, and then read / write with pointers and do whatever you want. Then, when you need to draw it on the screen using Direct2D, use ID2D1RenderTarget :: CreateBitmap () to create a new device bitmap or ID2D1Bitmap :: CopyFromMemory () to update an existing device bitmap. You can also do in IWICBitmap using ID2D1Factory :: CreateWicBitmapRenderTarget () (rather than hardware acceleration).

You will not get hardware acceleration for these types of operations. Updated Direct2D in Win8 (should also be available for Win7 in the end) has a few useful things for this, but it is rather complicated.

+11
source

Rick answers conversations about methods that you can use if you don't need to lose hardware acceleration. I am focusing on how to do this using a significant amount of GPU acceleration.

To speed up the rendering of equipment and get maximum performance, you will want to switch from ID2DHwndRenderTarget to use the newer ID2DDevice and ID2DDeviceContext interfaces. This, frankly, does not add that there is much more logic to your code, and the performance benefits are substantial. It also works on Windows 7 with a platform update. To summarize the process:

  • Create a DXGI factory when creating a D2D factory.
  • Create a D3D11 device and a D2D device to match.
  • Create a swap chain using the DXGI factory and the D3D device.
  • Define a swap chain for your back buffer and wrap it in a D2D bitmap.
  • Render, as before, between calls to BeginDraw () and EndDraw (). Remember to untie the back buffer and destroy its bitmap.
  • Call Present () in the swap chain to see the results.
  • Repeat with 4.

Once you do, you have unlocked a number of possible solutions. Probably the easiest and most effective way to solve your exact problem (color channel sharing) is to use the color matrix as one of the other answers mentioned. It is important to recognize that for this you need to use the new ID2DDeviceContext interface, not ID2DHwndRenderTarget. There are many other effects that can perform more complex operations if you want to. Here are some of the most useful for simple pixel manipulation:

To solve the problem of manipulating pixels directly, without discarding hardware acceleration or performing tons of copying, there are two options. First, write a pixel shader and wrap it with a fully customizable D2D effect. This is more than just getting the pixel buffer on the processor and doing the old-fashioned bit-mashing, but all this happens much faster on the GPU. The D2D effects frame also makes it very easy to reuse your effect for other purposes, combine it with other effects, etc.

In those moments when you absolutely need to manipulate the pixels of the processor, but still want to achieve significant acceleration, you can control your displayed D3D11 textures. For example, you can use intermediate textures if you want to manipulate your texture resources asynchronously from the CPU. There is another answer that goes in more detail. See ID3D11Texture2D for more details.

+8
source

The specific problem of replacing all green pixels with red pixels can be solved using ID2D1Effect with Windows 8 and platform updates for Windows 7.

In particular, the effect of the color matrix.

0
source

Source: https://habr.com/ru/post/906953/


All Articles