示例#1
0
        // =====
        #region Constructors

        // Designated constructor
        public SpriteTexture(Rectangle rectangle, WrappedTexture texture, WrappedShader shader)
        {
            // Get ID
            this.id = nextID++;

            // Entry logging
      #if IS_LOGGING_METHODS
            Log.Write(String.Format("Entering method for {0}", this.Name));
      #endif

            // Set instance variables
            this.layer      = null;
            this.layerIndex = -1;
            this.depth      = 0;

            this.needsUpdate = false;

            this.rectangle = rectangle;
            this.texture   = texture;
            this.shader    = shader;


            // Initialize vertices
            this.vertices    = new VertexInput[4];
            this.vertices[0] = new VertexInput(rectangle.VertexAt(0), Color.White, new Vector2(0, 0));
            this.vertices[1] = new VertexInput(rectangle.VertexAt(1), Color.White, new Vector2(1, 0));
            this.vertices[2] = new VertexInput(rectangle.VertexAt(2), Color.White, new Vector2(1, 1));
            this.vertices[3] = new VertexInput(rectangle.VertexAt(3), Color.White, new Vector2(0, 1));


            // Exit logging
      #if IS_LOGGING_METHODS
            Log.Write(String.Format("Exiting method for {0}", this.Name));
      #endif
        }
示例#2
0
        // Draw a layer
        public void DrawLayer(SpriteLayer layer)
        {
            // Entry logging
      #if IS_LOGGING_METHODS
            Log.Write(String.Format("Entering method for {0}", this.Name));
      #endif

            // If no sprites, skip
            if (layer.SpriteCount <= 0)
            {
                goto exit;
            }

            // Activate layer buffers on device
            this.ActiveVertexBuffer = layer.VertexBuffer;
            this.ActiveIndexBuffer  = layer.IndexBuffer;

            // Below, we will render our sprites in batches.  For performance
            // reasons, we want these batches to be as large as possible.  Recall
            // that our sprites are ordered by depth and texture.  We will iterate
            // over each sprite and ask, 'Can this sprite be batched with the next?'
            // If so, we defer its rendering and add it to the current batch.
            // Otherwise, we immediately render the current batch.

            // Initialization
            Sprite         sprite         = layer.Sprites[0];
            WrappedTexture texture        = sprite.Texture;
            WrappedShader  parameters     = sprite.Shader;
            Sprite         nextSprite     = sprite;
            WrappedTexture nextTexture    = texture;
            WrappedShader  nextParameters = parameters;
            int            vertexStart    = 0;
            int            vertexCount    = sprite.Vertices.Length;
            int            indexStart     = 0;
            int            indexCount     = sprite.Indices.Length;
            int            primitiveCount = sprite.Vertices.Length - 2;

            // Loop
            for (int i = 0; i < layer.SpriteCount; i++)
            {
                // Log
        #if IS_LOGGING_DRAW
                Log.Write(String.Format("Now entering iteration {0} of {1} for {2}", i + 1, layer.SpriteCount, sprite.Name));
                Log.Write(String.Format("vertexStart = {0}", vertexStart));
                Log.Write(String.Format("vertexCount = {0}", vertexCount));
                Log.Write(String.Format("indexStart = {0}", indexStart));
                Log.Write(String.Format("indexCount = {0}", indexCount));
                Log.Write(String.Format("primitiveCount = {0}", primitiveCount));
                Log.Write(String.Format("drawCalls = {0}", drawCalls));
        #endif

                // Initialize canBatch, a boolean that equals true if this sprite can
                // be batched with the next, as false
                bool canBatch = false;

                // On the last iteration, there is no 'next' sprite
                if (i + 1 < layer.SpriteCount)
                {
                    // Get next sprite
                    nextSprite     = layer.Sprites[i + 1];
                    nextTexture    = nextSprite.Texture;
                    nextParameters = nextSprite.Shader;

                    // Check if this sprite can be batched with the next
                    if (texture == nextTexture && parameters == nextParameters)
                    {
                        canBatch = true;
                    }
                }

                // 'Can this sprite be batched with the next?'
                if (canBatch)
                {
                    // If so, add to batch
                    vertexCount    += sprite.Vertices.Length;
                    indexCount     += sprite.Indices.Length;
                    primitiveCount += sprite.Vertices.Length - 2;

                    // Log
          #if IS_LOGGING_DRAW
                    Log.Write(String.Format("This sprite can be grouped with the next.  Adding to batch..."));
          #endif
                }
                else
                {
                    // Otherwise, render current batch

                    // Log
          #if IS_LOGGING_DRAW
                    Log.Write(String.Format("This sprite CANNOT be grouped with the next.  Rendering batch!"));
          #endif

                    // Set the active texture
                    this.ActiveTexture = texture;
                    // Set the active shader
                    this.ActiveShader = sprite.Shader;
                    // Call draw
                    this.Device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, vertexStart, vertexCount, indexStart, primitiveCount);

                    /*
                     * this.ActiveShader.Effect.CurrentTechnique.Passes[0].Apply();
                     * Trace.WriteLine(String.Format("updateCount = {0}, drawCalls = {1}:", Globals.Clock.TotalUpdateCount, this.DrawCalls));
                     * Trace.WriteLine(String.Format("activeShader = {0}", this.ActiveShader.Name));
                     * Trace.WriteLine(String.Format("texWidth = {0}", this.ActiveShader.Effect.Parameters["tex"].GetValueTexture2D().Width));
                     * Trace.WriteLine(String.Format("view = {0}", this.ActiveShader.Effect.Parameters["view"].GetValueMatrix()));
                     * Trace.WriteLine(String.Format("projection = {0}", this.ActiveShader.Effect.Parameters["projection"].GetValueMatrix()));
                     * Trace.WriteLine(String.Format("threshold = {0}", this.ActiveShader.Effect.Parameters["threshold"].GetValueSingle()));
                     * Trace.WriteLine(String.Format("alpha = {0}", this.ActiveShader.Effect.Parameters["alpha"].GetValueSingle()));
                     * Trace.WriteLine("==========");
                     */
                    /*
                     * String s = String.Format("updateCount = {0}, drawCalls = {1}:", Globals.Clock.TotalUpdateCount, this.DrawCalls);
                     * s += String.Format("\nactiveRenderTarget = {0}", this.activeRenderTarget);
                     * s += String.Format("\nactiveVertexBuffer = {0}", this.activeVertexBuffer);
                     * s += String.Format("\nactiveIndexBuffer = {0}", this.activeIndexBuffer);
                     * s += String.Format("\nactiveView = {0}", this.activeView);
                     * s += String.Format("\nactiveProjection = {0}", this.activeProjection);
                     * s += String.Format("\nactiveTexture = {0}", this.activeTexture);
                     * s += String.Format("\nactiveShader = {0}", this.activeShader);
                     * s += String.Format("\nactiveBlendState = {0}", this.activeBlendState);
                     * s += String.Format("\nactiveDepthStencilState = {0}", this.activeDepthStencilState);
                     * s += "\n==========";
                     * Trace.WriteLine(s);
                     */
                    /*
                     * String s = String.Format("updateCount = {0}, device.vB = {1}", Globals.Clock.TotalUpdateCount, this.Device.GetVertexBuffers()[0].VertexBuffer.VertexCount);
                     * Trace.WriteLine(s);
                     */

                    // Log
          #if IS_LOGGING_DRAW
                    Log.Write(String.Format("Just rendered the following buffer data:"));
                    for (int l = vertexStart; l < vertexStart + vertexCount; l++)
                    {
                        Log.Write(String.Format("layer.Vertices[{0}] = {1}", l, layer.Vertices[l]));
                    }
                    for (int l = indexStart; l < indexStart + indexCount; l++)
                    {
                        Log.Write(String.Format("layer.Indices[{0}] = {1}", l, layer.Indices[l]));
                    }
          #endif

                    // This batch is complete
                    this.drawCalls++;

                    // Now, we create a brand new batch
                    vertexStart += vertexCount;
                    indexStart  += indexCount;

                    // So far, it only contains the next sprite
                    vertexCount    = nextSprite.Vertices.Length;
                    indexCount     = nextSprite.Indices.Length;
                    primitiveCount = nextSprite.Vertices.Length - 2;
                }

                // Prepare for next iteration
                sprite     = nextSprite;
                texture    = nextTexture;
                parameters = nextParameters;
            }


            // [*]  Exit trap:
exit:

            // Exit logging
      #if IS_LOGGING_METHODS
            Log.Write(String.Format("Exiting method for {0}", this.Name));
      #endif

            // Exit
            return;
        }
示例#3
0
 // Set a texture parameter
 public void SetParameter(String parameterName, WrappedTexture value)
 {
     this.Effect.Parameters[parameterName].SetValue(value.Texture);
 }
示例#4
0
        // =====
        #region Constructors

        // Default constructor
        public WrappedGraphicsDevice()
        {
            // Get ID
            this.id = nextID++;

            // Entry logging
      #if IS_LOGGING_METHODS
            Log.Write(String.Format("Entering method for {0}", this.Name));
      #endif

            // Set screen size in pixels
            // WARNING:  ApplyChanges() will empty out all vertex and index buffers?!
            int w = 1280;
            int h = 720;
            Globals.Game1.Graphics.PreferredBackBufferWidth    = w;
            Globals.Game1.Graphics.PreferredBackBufferHeight   = h;
            Globals.Game1.Graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;
            Globals.Game1.Graphics.ApplyChanges();
            Globals.Game1.IsMouseVisible           = true;
            Globals.Game1.Window.AllowUserResizing = true;


            // Set instance variables
            this.activeRenderTarget      = null;
            this.activeVertexBuffer      = null;
            this.activeIndexBuffer       = null;
            this.activeView              = Matrix.Identity;
            this.activeProjection        = Matrix.Identity;
            this.activeTexture           = null;
            this.activeShader            = null;
            this.activeBlendState        = null;
            this.activeDepthStencilState = null;

            this.backBuffer          = new WrappedBackBuffer();
            this.renderTargetManager = new RenderTargetManager();
            this.quadVertexBuffer    = new WrappedVertexBuffer(4);
            this.quadIndexBuffer     = new WrappedIndexBuffer(6);
            this.quadIndexBuffer.SetData(new int[6] {
                0, 1, 2, 0, 2, 3
            });
            this.backgroundColor = Color.White;
            this.drawCalls       = 0;

            this.device      = Globals.Game1.GraphicsDevice;
            this.spriteBatch = new SpriteBatch(this.device);
            // this.device.DepthStencilState = new DepthStencilState() { DepthBufferEnable = false };

            this.blendStateAlpha = new BlendState()
            {
                AlphaDestinationBlend = Blend.InverseSourceAlpha,
                ColorDestinationBlend = Blend.InverseSourceAlpha,
                ColorWriteChannels    = ColorWriteChannels.All
            };
            this.blendStateNone = new BlendState()
            {
                AlphaDestinationBlend = Blend.InverseSourceAlpha,
                ColorDestinationBlend = Blend.InverseSourceAlpha,
                ColorWriteChannels    = ColorWriteChannels.None
            };
            this.stencilStateIncrement = new DepthStencilState()
            {
                StencilEnable    = true,
                StencilFunction  = CompareFunction.LessEqual,
                ReferenceStencil = 0,
                StencilPass      = StencilOperation.Increment
            };
            this.stencilStateKeep = new DepthStencilState()
            {
                StencilEnable    = true,
                StencilFunction  = CompareFunction.LessEqual,
                ReferenceStencil = 0,
                StencilPass      = StencilOperation.Keep
            };

            // Exit logging
      #if IS_LOGGING_METHODS
            Log.Write(String.Format("Exiting method for {0}", this.Name));
      #endif
        }