在MonoGame中绘制矩形

7

如何在MonoGame中绘制形状,例如矩形和圆形,而不必将预先绘制的形状保存在Content文件夹中?

DrawRectangle()和DrawEllipse()适用于Windows Form,但在我使用的OpenGL中无法使用。

3个回答

12

使用三维基元和二维投影

这里有一个简单的例子及其说明:

我定义了一个10x10的矩形,并设置世界矩阵,使其看起来像一个二维投影:

注意: BasicEffect 是绘制图元的工具。

protected override void LoadContent()
{
    _vertexPositionColors = new[]
    {
        new VertexPositionColor(new Vector3(0, 0, 1), Color.White),
        new VertexPositionColor(new Vector3(10, 0, 1), Color.White),
        new VertexPositionColor(new Vector3(10, 10, 1), Color.White),
        new VertexPositionColor(new Vector3(0, 10, 1), Color.White)
    };
    _basicEffect = new BasicEffect(GraphicsDevice);
    _basicEffect.World = Matrix.CreateOrthographicOffCenter(
        0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 0, 1);
}

然后我就把整个东西画出来了 :D

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    EffectTechnique effectTechnique = _basicEffect.Techniques[0];
    EffectPassCollection effectPassCollection = effectTechnique.Passes;
    foreach (EffectPass pass in effectPassCollection)
    {
        pass.Apply();
        GraphicsDevice.DrawUserPrimitives(PrimitiveType.LineStrip, _vertexPositionColors, 0, 4);
    }
    base.Draw(gameTime);
}

这里有你的矩形!

enter image description here

现在这只是冰山一角,

或者如上面某个帖子中提到的,您可以使用执行此操作的着色器...

我以前需要绘制超椭圆,最终草草完成了这个着色器:

在HLSL中绘制超椭圆

正如您在帖子中看到的,超椭圆不仅可以绘制椭圆,还可以绘制其他形状,甚至可能是圆(我没有测试),因此您可能会感兴趣。

最终,您将希望有一些类/方法来隐藏所有这些细节,因此您只需调用像DrawCircle()这样的东西。

提示:通过在https://gamedev.stackexchange.com/上发布,您可能会获得更多与Monogame相关的答案

:D


顶点数组不应该包含5个顶点以便绘制4个基本线吗? - Rudey
不,因为它是一条线条 :D - aybe
从MSDN:数据按连续的线段顺序排列;每个线段由一个新顶点和上一个线段的最后一个顶点描述。计数可以是任何正整数.。顶点1和2构成线段,顶点2和3、顶点3和4...第4条线段不需要第5个顶点来连接顶点4吗? - Rudey
我同意这有点令人困惑,但它确实有效...数一下条带的数量:有4个。当我们传递了 4 时,该方法知道要针对数组进行循环以绘制最后一个条带,使用最后一个和第一个顶点。 - aybe
有没有一些库可以为我完成所有这些工作?我正在使用Monogame进行数学可视化(因为喜欢C#而不知道Python),老实说,我根本不想学习HLSL。 - Kemsikov
@Kemsikov,你可以尝试一下Unity,这是一种完全不同的方法。 - aybe

11
如果你需要在2D中创建一个矩形,你可以这样做:
 Color[] data = new Color[rectangle.Width * rectangle.Height];
 Texture2D rectTexture = new Texture2D(GraphicsDevice, rectangle.Width, rectangle.Height);

 for (int i = 0; i < data.Length; ++i) 
      data[i] = Color.White;

 rectTexture.SetData(data);
 var position = new Vector2(rectangle.Left, rectangle.Top);

 spriteBatch.Draw(rectTexture, position, Color.White);

可能比 Aybe 的答案在某些情况下更容易。这将创建一个实心矩形。

1
你也可以用这种方法画出线条。只需拉伸和旋转矩形以绘制“线条”。 - Rudey

4
我发现了一种简单的解决方案,可以绘制填充和非填充形状。我不知道它是否耗费大量资源,但是这里还是提供一下:
    {
        //Filled
        Texture2D _texture;

        _texture = new Texture2D(graphicsDevice, 1, 1);
        _texture.SetData(new Color[] { Color.White });

        spriteBatch.Draw(_texture, Rect, Color.White);
    }


    {
        //Non filled
        Texture2D _texture;

        _texture = new Texture2D(graphicsDevice, 1, 1);
        _texture.SetData(new Color[] { Color.White });

        spriteBatch.Draw(_texture, new Rectangle(Rect.Left, Rect.Top, Rect.Width, 1), Color.White);
        spriteBatch.Draw(_texture, new Rectangle(Rect.Right, Rect.Top, 1, Rect.Height), Color.White);
        spriteBatch.Draw(_texture, new Rectangle(Rect.Left, Rect.Bottom, Rect.Width, 1), Color.White);
        spriteBatch.Draw(_texture, new Rectangle(Rect.Left, Rect.Top, 1, Rect.Height), Color.White);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接