Text with triangle (SlimDX)

Oct 2, 2014 at 12:01 PM
Hi,

Thanks for all your work on the SpriteTextRenderer.

I'm having trouble rendering text using the SpriteTextRenderer and the SlimDX sample code for drawing a triangle, together. The text render seems to completely clear the screen. What am I doing wrong?

I've incorporated both in the code here:

http://pastebin.com/iUhRS90C

And here's the SimpleTriangle.fx I'm using:
float4 VShader(float4 position : POSITION) : SV_POSITION
{
    return position;
}

float4 PShader(float4 position : SV_POSITION) : SV_Target
{
    return float4(1.0f, 1.0f, 0.0f, 1.0f);
}
I'm pretty sure the problem is the use of:
        context.VertexShader.Set(vertexShader);
        context.PixelShader.Set(pixelShader);
I believe a prior version of this SlimDX demo used EffectPass and Technique and called pass.Apply() in the draw loop.

Do you think you could take a look and see what I'm doing wrong? It's pretty elementary stuff, and I'm probably doing something stupid. Or maybe a recent change to SlimDX has broken something.

Cheers,
David
Coordinator
Oct 2, 2014 at 1:51 PM
Hi David,

thanks for using the SDX SpriteTextRenderer. Your problem can be easily solved by providing the necessary information before the draw call. In fact, you need to set the correct shaders and the vertex buffer, including input layout. The lines 79 thru 86 can be removed if you insert them in the message pump:
MessagePump.Run(form, () =>
{
    // clear the render target to a soothing blue
    context.ClearRenderTargetView(renderTarget, new Color4(0.5f, 0.5f, 1.0f));

    textBlock.DrawString("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + Environment.NewLine + "abcdefghijklmnopqrstuvwxyz", Vector2.Zero, new Color4(1.0f, 1.0f, 0.0f));
    sprite.Flush();

    // configure the Input Assembler portion of the pipeline with the vertex data
    context.InputAssembler.InputLayout = layout;
    context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
    context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, 12, 0));

    // set the shaders
    context.VertexShader.Set(vertexShader);
    context.PixelShader.Set(pixelShader);

    // draw the triangle
    context.Draw(3, 0);
    swapChain.Present(0, PresentFlags.None);
});
The SpriteRenderer changes these values when it renders something. And it does not reset them to their previous state. The reason for this decision is that most applications (except such very simple sample applications like yours) set different shaders and vertex buffers within a single frame. Therefore, it is not very likely that after drawing some text the same vertex buffer, shader etc. is used that had been set before. If this is the case anyway, the developer is responsible for setting the correct state. But you'll notice as your project evolves that you will most probably set the correct state before rendering anything. Relying on a certain state can be quite hard to manage.

Nico
Marked as answer by Nico201 on 10/4/2014 at 12:15 AM
Oct 3, 2014 at 10:30 AM
Hi Nico,

Thanks for the help, but I've applied what you've recommended but it's still behaving the same way.
Rendering the text stops the triangle from appearing. If I comment out the text render, the triangle appears.

Here's what I've got after I included your changes:

http://pastebin.com/y30HshRw

It's changed slightly, the ShaderByteCode compile is sourced from Properties.Resources.SimpleTriangle11.
It's the same as in my first post, in its entirety.

I forgot some crucial information, some library versions:
SlimDX: v4.0.13.43 (sourced through nuget - nuget reports it as version 4.0.13.44 however)
SpriteTextRenderer: v2.0.0.0 beta (current as of today)
.NET framework: v4.5.1
Compiling on Windows 7 64 bit.

Is there a specific version of SlimDX you built the framework against? I could try using that version and see how it goes. Although I'm betting I'm just doing something silly.

I've also tried specifying the color of each vertex, but I get the same result - it only renders the tri when I don't draw the text.
I've updated my graphics drivers, rebooted, and still no joy.

Thanks for your help, hoping you might have some ideas on this one.

Cheers,
David
Coordinator
Oct 3, 2014 at 11:12 AM
You're right. I forgot that the sprite renderer sets a geometry shader. Reset this too and you're ready to go:
context.GeometryShader.Set(null);
Nico
Marked as answer by Nico201 on 10/4/2014 at 12:15 AM
Oct 4, 2014 at 12:25 AM
That did the trick! Thanks a lot!