是否可以编写新的SpriteBatch.Begin函数

本文关键字:SpriteBatch Begin 函数 是否 | 更新日期: 2023-09-27 18:35:34

我正在创建一个具有等距视图的游戏。我有一个结构,目前使用两个矩阵非常有效地工作。不过,这需要额外的成员和功能,而我想没有这些成员和功能。其中一个SpriteBatch.Begin函数接受转换矩阵作为参数。我想编写一个新的SpriteBatch.Begin函数来接受两个矩阵(一个用于相机变换,一个用于等轴测变换)。我不知道实际的SpriteBatch.Begin功能是如何工作的,也不知道是否有任何可用的来源。有人有想法吗?

是否可以编写新的SpriteBatch.Begin函数

好的,编辑后我搜索了 SpriteBatch.begin() 的源代码功能。我找到了 monogame 的源代码,它是 XNA 的开源实现。

所以这里是:

using System;
using System.Text;
namespace Microsoft.Xna.Framework.Graphics
{
    public class SpriteBatch : GraphicsResource
    {
        readonly SpriteBatcher _batcher;
            SpriteSortMode _sortMode;
            BlendState _blendState;
            SamplerState _samplerState;
            DepthStencilState _depthStencilState; 
            RasterizerState _rasterizerState;                
            Effect _effect;
            bool _beginCalled;
            Effect _spriteEffect;
            readonly EffectParameter _matrixTransform;
            readonly EffectPass _spritePass;
            Matrix _matrix;
            Rectangle _tempRect = new Rectangle (0,0,0,0);
            Vector2 _texCoordTL = new Vector2 (0,0);
            Vector2 _texCoordBR = new Vector2 (0,0);
            public SpriteBatch (GraphicsDevice graphicsDevice)
            {
                if (graphicsDevice == null) 
                {
                        throw new ArgumentException ("graphicsDevice");
                }        
                this.GraphicsDevice = graphicsDevice;
                // Use a custom SpriteEffect so we can control the transformation matrix
                _spriteEffect = new Effect(graphicsDevice, SpriteEffect.Bytecode);
                _matrixTransform = _spriteEffect.Parameters["MatrixTransform"];
                _spritePass = _spriteEffect.CurrentTechnique.Passes[0];
                _batcher = new SpriteBatcher(graphicsDevice);
                _beginCalled = false;
            }
            public void Begin ()
            {
                Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise, null, Matrix.Identity);        
            }
            public void Begin (SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect, Matrix transformMatrix)
            {
                if (_beginCalled)
                    throw new InvalidOperationException("Begin cannot be called again until End has been successfully called.");
                // defaults
                _sortMode = sortMode;
                _blendState = blendState ?? BlendState.AlphaBlend;
                _samplerState = samplerState ?? SamplerState.LinearClamp;
                _depthStencilState = depthStencilState ?? DepthStencilState.None;
                _rasterizerState = rasterizerState ??   RasterizerState.CullCounterClockwise;
                _effect = effect;
                _matrix = transformMatrix;
                // Setup things now so a user can chage them.
                if (sortMode == SpriteSortMode.Immediate)
                    Setup();
                _beginCalled = true;
            }
            public void Begin (SpriteSortMode sortMode, BlendState blendState)
            {
                Begin (sortMode, blendState, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise, null, Matrix.Identity);                        
            }
            public void Begin (SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState)
            {
                Begin (sortMode, blendState, samplerState, depthStencilState, rasterizerState, null, Matrix.Identity);        
            }
            public void Begin (SpriteSortMode sortMode, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, RasterizerState rasterizerState, Effect effect)
            {
                Begin (sortMode, blendState, samplerState, depthStencilState, rasterizerState, effect, Matrix.Identity);                        
            }
            public void End ()
            {        
                _beginCalled = false;
                if (_sortMode != SpriteSortMode.Immediate)
                        Setup();
#if PSM   
        GraphicsDevice.BlendState = _blendState;
        _blendState.ApplyState(GraphicsDevice);
#endif
        _batcher.DrawBatch(_sortMode);
    }
文件

不完整,我没有在结束函数之后粘贴,但如果你想阅读整个文件。链接是:https://github.com/mono/MonoGame/blob/7ec1ec8a0e924eca60588e770121ed3e2593e74d/MonoGame.Framework/Graphics/SpriteBatch.cs

我希望这是您正在寻找的源代码。

祝你好运!

这是我的另一个答案:

你需要在主 Draw() 函数中调用 spriteBatch.Begin() 和 spriteBatch.End(),这样你才能真正绘制。

下面是一个示例:

Game1.cs 中的 Draw() 函数

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);
    // Start drawing
    spriteBatch.Begin();
    player.Draw(spriteBatch);
    // Stop drawing
    spriteBatch.End();
    base.Draw(gameTime);
}

播放器中的 Draw() 函数.cs :

public void Draw(SpriteBatch spriteBatch)
{
    spriteBatch.Draw(playerTexture, playerPosition, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 1f);
}

这会将播放器与播放器中的 Draw() 函数一起吸引到屏幕上.cs 。spriteBatch 在 Game1 的 LoadContent() 函数中初始化.cs 。

我希望这有帮助!

您可以为对象创建自己的"绘制",并从"Game1.cs"的"绘制"中调用它们。

例:

protected override void Draw(GameTime gameTime){
myObject.Draw(gameTime);
}

希望这个帮助!