예제 #1
0
        /// <summary>
        /// Given a world object, the renderer draws it using the
        /// XNA frameworks
        /// </summary>
        /// <param name="world">The world object to render</param>
        /// <returns></returns>
        public bool RenderWorld(World world)
        {
            world.SortEntities();
            ClearScreen();

            Effect shader = assetManager.GetEffect("shaders/sprite/SimpleSprite");
            Effect channel = assetManager.GetEffect("shaders/ChannelRender");

            Vector2 viewportTrans = new Vector2(graphicsDevice.Viewport.Width / 2, graphicsDevice.Viewport.Height / 2);

            SpriteBatch spriteBatch = new SpriteBatch(graphicsDevice);

            // Step 1: Generate a stencil of which pixels to render

            // Draw the actual sprites
            Color[] t = { Color.White, Color.Yellow, Color.Purple, Color.Blue };
            int i = 0;

            ClearRenderTargets();

            List<Entity> lstEntities = world.GetEntities();

            // First pass: Draw the entities
            // This pass generates the dif, nrm and hgt textures
            // Objects intersect as if in 3D
            RenderEntities(lstEntities, spriteBatch, m_rtDif, m_rtDepthStencil, m_rtNormal, temp);

            // Render the lights!
            RenderLights(lstEntities, spriteBatch, m_rtDif, m_rtDepthStencil, m_rtNormal, m_rtLights, m_rtSpc, temp);

            // Render the overlays!
            Texture2D lightPos = assetManager.GetTexture("sprites/test/lightpos");
            Texture2D lightBulb = assetManager.GetTexture("sprites/test/lightbulb");
            graphicsDevice.SetRenderTarget(m_rtOverlay);
            if (m_bDrawLights)
            {
                spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
                foreach (Entity ent in lstEntities)
                {
                    if (ent.Type != EntityType.Light)
                        continue;

                    Entities.Lights.Light light = (Entities.Lights.Light)ent;
                    Vector2 posBase = Project(new Vector3(light.Position.X, light.Position.Y, 0));
                    Vector2 posBulb = Project(new Vector3(light.Position.X, light.Position.Y, light.Z));

                    spriteBatch.Draw(lightPos, posBase, light.Color);
                    spriteBatch.Draw(lightBulb, posBulb, light.Color);
                }
                spriteBatch.End();
            }

            // Render out 'selection rectangles'
            Texture2D selectionRect = new Texture2D(graphicsDevice, 1, 1);
            selectionRect.SetData<Color>(new[] { Color.Red });

            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
            foreach (Entity ent in lstEntities)
            {
                if (!ent.Selected)
                    continue;

                Vector2 upperLeft = Project(new Vector3(ent.Position.X, ent.Position.Y, ent.Type==EntityType.Sprite?ent.Z:0));
                upperLeft.X -= 2;
                upperLeft.Y -= 2;

                Vector2 size = new Vector2(14, 14);

                if (ent.Type == EntityType.Sprite)
                {
                    Texture2D sprite = assetManager.GetTexture(ent.Sprite + "/dif");
                    size = new Vector2(sprite.Width+4, sprite.Height+4);
                }

                spriteBatch.Draw(selectionRect, new Rectangle((int)upperLeft.X, (int)upperLeft.Y, 1, (int)size.Y), Color.White);
                spriteBatch.Draw(selectionRect, new Rectangle((int)upperLeft.X, (int)upperLeft.Y, (int)size.X, 1), Color.White);
                spriteBatch.Draw(selectionRect, new Rectangle((int)(upperLeft.X+size.X), (int)upperLeft.Y, 1, (int)size.Y), Color.White);
                spriteBatch.Draw(selectionRect, new Rectangle((int)(upperLeft.X), (int)(upperLeft.Y+size.Y), (int)size.X, 1), Color.White);
            }
            spriteBatch.End();

            ////////////////////////////////////////////////////////////////////
            // finalResult stores the final beauty pass
            // That is, a combination of the dif and the lighting outputs
            graphicsDevice.SetRenderTarget(finalResult);
            graphicsDevice.Textures[1] = m_rtLights;
            graphicsDevice.Textures[2] = m_rtSpc;

            Effect combine = assetManager.GetEffect("shaders/Combine");

            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
            combine.Parameters["scalarAdd"].SetValue(m_colAmbient.ToVector4() * m_fAmbientIntensity);
            combine.Techniques[0].Passes[0].Apply();
            spriteBatch.Draw(m_rtDif, Vector2.Zero, Color.White);
            spriteBatch.End();

            //////////////////////////////////////////////////////////////////
            graphicsDevice.SetRenderTarget(null);
            graphicsDevice.Clear(Color.Transparent);
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);

            switch(m_rstType)
            {
                case RenderSceneType.Diffuse:
                    spriteBatch.Draw(m_rtDif, Vector2.Zero, Color.White);
                    break;

                case RenderSceneType.Height:
                    spriteBatch.Draw(m_rtDepthStencil, Vector2.Zero, Color.White);
                    break;

                case RenderSceneType.Normal:
                    spriteBatch.Draw(m_rtNormal, Vector2.Zero, Color.White);
                    break;

                case RenderSceneType.Lights:
                    spriteBatch.Draw(m_rtLights, Vector2.Zero, Color.White);
                    break;

                case RenderSceneType.Beauty:
                    spriteBatch.Draw(finalResult, Vector2.Zero, Color.White);
                    break;
            }
            spriteBatch.Draw(m_rtOverlay, Vector2.Zero, Color.White);
            spriteBatch.End();

            return true;
        }