0
\$\begingroup\$

I'm working on implementing a 2D masking effect in my current game. To do so, I have two textures, one for the source image and one for the mask. The source image is just a regular texture, so that's easy. The mask I'm generating by rendering to a render target through the use of graphicsDevice.DrawUserIndexedPrimitives, but when I try, the following error pops up.

InvalidOperationException caused by an issue with the current vertex declaration.

This is the function that attempts to render to the mask's render target. Vertices are of type VertexPositionColor.

private void RenderMaskTarget(SpriteBatch sb)
{
    graphicsDevice.SetRenderTarget(maskTarget);
    graphicsDevice.Clear(Color.Transparent);

    sb.Begin(SpriteSortMode.Deferred, null, null, null, null, basicEffect, camera.Transform);

    graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineStrip, vertices, 0, vertices.Length, indexData, 0, primitiveCount);

    sb.End();
}

And this is the function that creates my basic effect.

private void CreateBasicEffect()
{
    Matrix projection = Matrix.CreateOrthographicOffCenter(0, Constants.ScreenWidth, Constants.ScreenHeight, 0, 0, 1);
    Matrix halfPixelOffset = Matrix.CreateTranslation(-0.5f, -0.5f, 0);

    basicEffect = new BasicEffect(graphicsDevice)
    {
        World = Matrix.CreateOrthographicOffCenter(0, graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height, 0, 0, 1),
        View = Matrix.Identity,
        Projection = halfPixelOffset * projection,
        VertexColorEnabled = true,
        LightingEnabled = false
    };
}

I've searched everywhere I can on this site and Google in general, but nothing I've tried has worked. I think my problem is a fundamental misunderstanding of what the exception above actually means. Based on its wording, the current vertex declaration doesn't include all required elements, and it then goes on to list the elements I do have, but it doesn't tell me what the required ones are. Further, where is the current vertex declaration defined? Is it VertexPositionColor that defines it or the BasicEffect?

I realize that similar questions to this have been asked before, but like I said, no solutions I've seen have worked. I think part of that is XNA vs. Monogame, where an XNA solution might not work for Monogame. I apologize if this is a true duplicate question.

Thank you :)

\$\endgroup\$
2
\$\begingroup\$

This section is not correct:

sb.Begin(SpriteSortMode.Deferred, null, null, null, null, basicEffect, camera.Transform);

graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineStrip, vertices, 0, vertices.Length, indexData, 0, primitiveCount);

sb.End();

You're using a spriteBatch and then bypass it by calling the DrawUserIndexedPrimitives directly. I'm not entirely sure but it seems to me that your drawcall simply has no shader active at the time you call it. Since the spriteBatch starts drawing at the sb.End().

So what I think happens here is

  1. you start a spriteBatch.
  2. attempt to draw something without the batch.
  3. close the spriteBatch- but it is empty so nothing happens.

At the point 2, no shader is actively set.

Replace the draw section by:

private void RenderMaskTarget()
{
    graphicsDevice.SetRenderTarget(maskTarget);
    graphicsDevice.Clear(Color.Transparent);

    basicEffect.CurrentTechnique.Passes[0].Apply();
    graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.LineStrip, vertices, 0, vertices.Length, indexData, 0, primitiveCount);

}
\$\endgroup\$
  • \$\begingroup\$ That did it. Thank you again Felsir. That's such a strange error message given what the actual problem is. \$\endgroup\$ – Grimelios Sep 23 '16 at 13:01
1
\$\begingroup\$

Your active vertex declaration includes SV_Position0 and COLOR0 elements, as you have surmised. Your active shader expects a different set of elements, and thus cannot be used to render the geometry you are sending.

You need to make your vertex declaration and your shader match (you also need to make sure you actually send the type of data the vertex declaration asserts).

You're using MonoGame's BasicEffect, which I believe is a "built in" shader that expects positions, colors and texture coordinates. Your vertex declaration doesn't contain texture coordinates and you may not actually be sending them in the vertex data, either.

The simplest thing you can probably do is set TexturesEnabled to false on your effect, which should stop it from requiring texture coordinates. Alternatively, provide texture coordinates in your vertex data and declaration.

\$\endgroup\$
  • \$\begingroup\$ Thank you for the answer. Unfortunately, setting TextureEnabled to false didn't change anything. I was able to avoid the exception by using VertexPositionNormalTexture, but 1) that feels wrong since I'm conceptually not texturing anything, and 2) the screen stays black. \$\endgroup\$ – Grimelios Sep 22 '16 at 17:52
  • \$\begingroup\$ I'm not sure why the screen is black based on your current code; there's quite a few reasons it could go wrong. If you can produce a minimal, complete example that recreates the black-screen problem you could ask it as a new question. \$\endgroup\$ – Josh Sep 22 '16 at 17:53
  • \$\begingroup\$ As for the TextureEnabled thing, it's possible that under the hood that doesn't change the shader BasicEffect uses. I don't really know enough about MonoGame's implementation to say, but the BasicEffect source code is available on their GitHub site. If it doesn't change the shader, then unfortunately using a different vertex format is probably the next-best option. Or writing a new shader yourself instead of using BasicEffect. \$\endgroup\$ – Josh Sep 22 '16 at 17:54
  • \$\begingroup\$ Okay. I should have clarified that by "the screen stays black", that I'm clearing the graphics device to black and then nothing else is rendered, despite setting texture coordinates correctly (as far as I can tell). I'll research more into TextureEnabled before considering another question. \$\endgroup\$ – Grimelios Sep 22 '16 at 17:56
  • \$\begingroup\$ I posted a followup question here: gamedev.stackexchange.com/questions/130344/… \$\endgroup\$ – Grimelios Sep 22 '16 at 18:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.