sharpdx / SharpDX-Samples

Official repository for all SharpDX Samples
346 stars 222 forks source link

DirectWrite and Direct3D11 integration #41

Open JakubK opened 8 years ago

JakubK commented 8 years ago

Hello! I'm really interested in DirectWrite and Direct3D11 but I have never tried to combine them in 1 project. So I tried to combine the MiniTri project from the samples and the AdvancedTextRenderer, also from the samples. But the result is terrible, I can see the Triangle from the MiniTri and also I can see the text from AdvancedTextRenderer App, but the window, with the entire scene is flashing per frame. I just want to render text in my SharpDX games, but rendering from image file and building a texture from it is a little bit too complicated, and it is bugged of course, so I thought using DirectWrite could be easier to implement. It is my mistake while copying the code from Samples, or just combining DirectWrite and Direct3D11 is impossible? Regards!

QuantumDeveloper commented 8 years ago

Combining is definately possible. You probably messed something in your project.

JakubK commented 8 years ago

@QuantumDeveloper No, this is impossible. I've just copied the code from those samples again, with the same result. Maybe I should change something after just copying this ? I will paste here how I've done the RenderLoop:

RenderLoop.Run(mainForm, () =>
            {
                context.ClearRenderTargetView(renderView, Color.Black);
                context.Draw(3, 0);
                swapChain.Present(0, PresentFlags.None);

                renderTarget.BeginDraw();
                renderTarget.Clear(bgcolor);

                renderTarget.FillRectangle(fullTextBackground, backgroundBrush);

                renderTarget.FillRectangle(textRegionRect, redBrush);

                textLayout.Draw(textRenderer, offset.X, offset.Y);

                try
                {
                    renderTarget.EndDraw();
                }
                catch
                {
                    CreateResources();
                }
            });
QuantumDeveloper commented 8 years ago

first of all d2d rendertarget should be created on the backbuffer surface, because you want it to be over D3D. So, you need to pass to D2D a backbuffer as a Surface. Second: you need to move swapchain.Present at the end, because you first need to render your d2d content to backbuffer and THEN show it.

JakubK commented 8 years ago

@QuantumDeveloper It is too hard for me :|. WindowRenderTarget cannot take a backbuffer as a parameter, so I tried to make it a RenderTarget, but then I'm getting the SharpDXException with the message "No such interface supported"

QuantumDeveloper commented 8 years ago

D2D can take Surface as a render target. So, you can cast Backbuffer to Surface type and set it as a render target like this:

var surface = Backbuffer.QueryInterface<Surface2>()
var d2DFactory = ToDispose(new Factory2(SharpDX.Direct2D1.FactoryType.MultiThreaded, DebugLevel.None));
         d2dDevice = ToDispose(new Device1(d2DFactory, dxgiDevice));
         d2dContext = ToDispose(new DeviceContext1(d2dDevice, DeviceContextOptions.EnableMultithreadedOptimizations));
         d2dContext.AntialiasMode = AntialiasMode.Aliased;
         dwFactory = ToDispose(new DWriteFactory(FactoryType.Shared));
         var bitmapProperties =
                new BitmapProperties1(
                    new SharpDX.Direct2D1.PixelFormat(renderTarget.Description.Format, AlphaMode.Premultiplied),
                    d2DFactory.DesktopDpi.Width,
                    d2DFactory.DesktopDpi.Height,
                    BitmapOptions.CannotDraw | BitmapOptions.Target);
         d2dRenderTarget = ToDispose(new Bitmap1(d2dContext, renderTarget, bitmapProperties));
         d2dContext.Target = d2dRenderTarget;
         d2DFactory.Dispose();
JakubK commented 8 years ago

@QuantumDeveloper Where can I get access to the 'ToDispose' method?

QuantumDeveloper commented 8 years ago

Sorry, just ignore it)

JakubK commented 8 years ago

@QuantumDeveloper I'm using the SharpDX 2.6.2 Version and I don't know if something has changed, but many of the constructors in the classes which you are showing me in ur snippet doesnt exist :|. Same as d2dContext.AnitaliasMode - no help from Intellisense when I'm typing it.