sharpdx / SharpDX-Samples

Official repository for all SharpDX Samples
348 stars 221 forks source link

DirectWrite + D3D coop #15

Closed QuantumDeveloper closed 10 years ago

QuantumDeveloper commented 10 years ago

Hello, I tried to make coop for DirectWrite with d3d by tutorials, which I found for sharpDX, but as a result I have no text rendered on backbuffer.

Here is my code for initialization:

var _device = (SharpDX.Direct3D11.Device)GraphicsDevice;

                SharpDX.Direct2D1.Device d2dDevice = new SharpDX.Direct2D1.Device(_device.QueryInterface<SharpDX.DXGI.Device2>());
                d2dContext = new SharpDX.Direct2D1.DeviceContext(d2dDevice, SharpDX.Direct2D1.DeviceContextOptions.EnableMultithreadedOptimizations);

                // Specify the properties for the bitmap that we will use as the target of our Direct2D operations.
                // We want a 32-bit BGRA surface with premultiplied alpha.
                BitmapProperties1 properties = new BitmapProperties1(new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied),
                    DisplayProperties.LogicalDpi, DisplayProperties.LogicalDpi, BitmapOptions.Target | BitmapOptions.CannotDraw);

                // Get the default surface as a backbuffer and create the Bitmap1 that will hold the Direct2D drawing target.
                //Surface backBuffer = swapChain.GetBackBuffer<Surface>(0);
                d2dTarget = new Bitmap1(d2dContext, GraphicsDevice.BackBuffer, properties);

                fontFactory = new SharpDX.DirectWrite.Factory();
                textFormat = new TextFormat(fontFactory, "Segoe UI", 24.0f);

                textLayout1 = new TextLayout(fontFactory, "This is an example of a moving TextLayout object with snapped pixel boundaries.", textFormat, 400.0f, 200.0f);
                textBrush = new SolidColorBrush(d2dContext, Color.Black);
                backgroundBrush = new SolidColorBrush(d2dContext, Color.White);
                d2dContext.Target = d2dTarget;

And here is drawing code:

protected override void Draw(GameTime gameTime)
        {
            //Debug.WriteLine("Draw");
            if (_modelLoaded)
            {
                // Clears the screen with the Color.CornflowerBlue
                GraphicsDevice.Clear(Color.CornflowerBlue);
                // Setup the vertices
                GraphicsDevice.SetVertexBuffer(vertices);
                GraphicsDevice.SetIndexBuffer(indices, true);
                GraphicsDevice.SetVertexInputLayout(inputLayout);

                // Apply the basic effect technique and draw the rotating cube
                basicEffect.CurrentTechnique.Passes[0].Apply();
                GraphicsDevice.SetRasterizerState(currentRasterizerState);
                //GraphicsDevice.Draw(PrimitiveType.TriangleList, vertices.ElementCount);
                GraphicsDevice.DrawIndexed(PrimitiveType.TriangleList, indices.ElementCount);

                // Clear the target. 
                d2dContext.BeginDraw();
                //d2dContext.Clear(Color.CornflowerBlue);

                d2dContext.DrawText("Проверка", textFormat, new RectangleF(0, 0, 400, 200), textBrush);

                // Draw a block of text that will be clipped against the specified layout rectangle.
                d2dContext.FillRectangle(new RectangleF(50, 50, 200, 200), backgroundBrush);
                d2dContext.DrawText("This text is long enough to overflow the designed region but will be clipped to the containing rectangle. Lorem ipsum dolor sit amet, consectetur adipiscing elit. ", textFormat, new RectangleF(50, 50, 200, 200), textBrush, DrawTextOptions.Clip);

                // Draw a block of text that will overflow the specified layout rectangle.
                d2dContext.FillRectangle(new RectangleF(50, 300, 200, 200), backgroundBrush);
                d2dContext.DrawText("However, this other text isn't going to be clipped: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean gravida dui id accumsan dictum.", textFormat, new RectangleF(50, 300, 200, 200), textBrush, DrawTextOptions.None);

                // Draw three lines of text with different measuring modes.
                d2dContext.FillRectangle(new RectangleF(300, 50, 400, 200), backgroundBrush);
                d2dContext.DrawText("MeasuringMode: Natural", textFormat, new RectangleF(300, 50, 400, 200), textBrush, DrawTextOptions.None, MeasuringMode.Natural);
                d2dContext.DrawText("MeasuringMode: GDI classic", textFormat, new RectangleF(300, 80, 400, 200), textBrush, DrawTextOptions.None, MeasuringMode.GdiClassic);
                d2dContext.DrawText("MeasuringMode: GDI natural", textFormat, new RectangleF(300, 110, 400, 200), textBrush, DrawTextOptions.None, MeasuringMode.GdiNatural);

                //float layoutYOffset = (float)Math.Cos(layoutY) * 50.0f;

                // Draw moving text.
                d2dContext.FillRectangle(new RectangleF(300, 300, 400, 200), backgroundBrush);
                //d2dContext.DrawTextLayout(new Vector2(300, 350 + layoutYOffset), textLayout1, textBrush);

                // Draw moving text without pixel snapping, thus giving a smoother movement.
                d2dContext.FillRectangle(new RectangleF(750, 300, 400, 200), backgroundBrush);
                //d2dContext.DrawTextLayout(new Vector2(750, 350 + layoutYOffset), textLayout2, textBrush, DrawTextOptions.NoSnap);

                d2dContext.EndDraw();
            }
            // Handle base.Draw
            base.Draw(gameTime);
        }

No text at all. What I am doing wrong here? BTW, no one answer me on this question on gamedev, so I come here to ask you. I tryied to do this as in your tutorials, but seems I missed something important, but I don`t know what exactly.

xoofx commented 10 years ago

I ask only whose questions which I cant find anywhere in the Net and cant understand by myself.

For this particular issue, I gave you here and on gamedev several time the hint: Use a D3D render target to render from D2D to D3D. Do you know how to declare a D3D texture as a render target? You can't really find any resources on internet about this? With plain D3D11 it is a couple of lines, with the toolkit it is only one.

FYI, I just googled "offline render target D3D11", and the first link is on SharpDX about... [[D3D11 / DirectWrite / D2D1]] DirectDraw / DirectWrite into a Texture2D... the answer is at the bottom, he is not using the Toolkit, so it is a bit more verbose, but this is a very basic D3D setup.

So, you need to decide: or you support (at least a little) people who using your framework (good framework I need to mention) or you just leave everything as is and dont improve anything here.

The Toolkit is a bonus on top of existing DirectX APIs. But we don't provide support for it (unless you are ready to pay support).

So please, buy a D3D11 book, deep dive into msdn documentation, into their samples, at least for a couple of weeks if not months. Start from the basis, but don't try to build a house if you don't even know how to use a hammer.

QuantumDeveloper commented 10 years ago

Just for info. I made it and now D2D text drawing to a texture which I load from my drive.