source: 2013/30/MiskaK/MW2(My Warfare 2)/Krypton/KryptonRenderHelper.cs @ 4507

Revision 4507, 16.8 KB checked in by anlakane, 6 years ago (diff)

Talletus.

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6using Microsoft.Xna.Framework;
7using Microsoft.Xna.Framework.Graphics;
8
9using Krypton.Lights;
10
11namespace Krypton
12{
13    public enum BlendTechnique
14    {
15        Add = 1,
16        Multiply = 2,
17    };
18
19    public enum BlurTechnique
20    {
21        Horizontal = 1,
22        Vertical = 2,
23    };
24
25    public class KryptonRenderHelper
26    {
27        #region Static Unit Quad
28
29        private static VertexPositionTexture[] UnitQuad = new VertexPositionTexture[]
30        {
31            new VertexPositionTexture()
32            {
33                Position = new Vector3(-1, 1, 0),
34                TextureCoordinate = new Vector2(0, 0),
35            },
36            new VertexPositionTexture()
37            {
38                Position = new Vector3(1, 1, 0),
39                TextureCoordinate = new Vector2(1, 0),
40            },
41            new VertexPositionTexture()
42            {
43                Position = new Vector3(-1, -1, 0),
44                TextureCoordinate = new Vector2(0, 1),
45            },
46            new VertexPositionTexture()
47            {
48                Position = new Vector3(1, -1, 0),
49                TextureCoordinate = new Vector2(1, 1),
50            },
51        };
52
53        #endregion Static Unit Quad
54
55        private GraphicsDevice mGraphicsDevice;
56        private Effect mEffect;
57        private List<ShadowHullVertex> mShadowHullVertices = new List<ShadowHullVertex>();
58        private List<Int32> mShadowHullIndicies = new List<Int32>();
59
60        public GraphicsDevice GraphicsDevice
61        {
62            get { return this.mGraphicsDevice; }
63        }
64        public Effect Effect
65        {
66            get { return this.mEffect; }
67        }
68
69        public List<ShadowHullVertex> ShadowHullVertices
70        {
71            get { return this.mShadowHullVertices; }
72        }
73        public List<Int32> ShadowHullIndicies
74        {
75            get { return this.mShadowHullIndicies; }
76        }
77
78        public KryptonRenderHelper(GraphicsDevice graphicsDevice, Effect effect)
79        {
80            this.mGraphicsDevice = graphicsDevice;
81            this.mEffect = effect;
82        }
83
84        public void BufferAddShadowHull(ShadowHull hull)
85        {
86            // Why do we need all of these again? (hint: we don't)
87
88            Matrix vertexMatrix = Matrix.Identity;
89            Matrix normalMatrix = Matrix.Identity;
90
91            float cos, sin;
92
93            ShadowHullPoint point;
94            ShadowHullVertex hullVertex;
95
96            // Create the matrices (3X speed boost versus prior version)
97            cos = (float)Math.Cos(hull.Angle);
98            sin = (float)Math.Sin(hull.Angle);
99
100            // vertexMatrix = scale * rotation * translation;
101            vertexMatrix.M11 = hull.Scale.X * cos;
102            vertexMatrix.M12 = hull.Scale.X * sin;
103            vertexMatrix.M21 = hull.Scale.Y * -sin;
104            vertexMatrix.M22 = hull.Scale.Y * cos;
105            vertexMatrix.M41 = hull.Position.X;
106            vertexMatrix.M42 = hull.Position.Y;
107
108            // normalMatrix = scaleInv * rotation;
109            normalMatrix.M11 = (1f / hull.Scale.X) * cos;
110            normalMatrix.M12 = (1f / hull.Scale.X) * sin;
111            normalMatrix.M21 = (1f / hull.Scale.Y) * -sin;
112            normalMatrix.M22 = (1f / hull.Scale.Y) * cos;
113
114            // Where are we in the buffer?
115            var vertexCount = this.mShadowHullVertices.Count;
116
117            // Add the vertices to the buffer
118            for (int i = 0; i < hull.NumPoints; i++)
119            {
120
121                // Transform the vertices to screen coordinates
122                point = hull.Points[i];
123                Vector2.Transform(ref point.Position, ref vertexMatrix, out hullVertex.Position);
124                Vector2.TransformNormal(ref point.Normal, ref normalMatrix, out hullVertex.Normal);
125
126                hullVertex.Color = Color.Black;
127
128                this.mShadowHullVertices.Add(hullVertex); // could this be sped up... ?
129            }
130
131            //// Add the indicies to the buffer
132            foreach (int index in hull.Indicies)
133            {
134                mShadowHullIndicies.Add(vertexCount + index); // what about this? Add range?
135            }
136        }
137
138        public void DrawSquareQuad(Vector2 position, float rotation, float size, Color color)
139        {
140            size /= 2;
141
142            size = (float)Math.Sqrt(Math.Pow(size, 2) + Math.Pow(size, 2));
143
144            rotation += (float)Math.PI / 4;
145
146            var cos = (float)Math.Cos(rotation) * size;
147            var sin = (float)Math.Sin(rotation) * size;
148
149            var v1 = new Vector3(+cos, +sin, 0) + new Vector3(position, 0);
150            var v2 = new Vector3(-sin, +cos, 0) + new Vector3(position, 0);
151            var v3 = new Vector3(-cos, -sin, 0) + new Vector3(position, 0);
152            var v4 = new Vector3(+sin, -cos, 0) + new Vector3(position, 0);
153
154            var quad = new VertexPositionColorTexture[]
155            {
156                new VertexPositionColorTexture()
157                {
158                    Position = v2,
159                    Color = color,
160                    TextureCoordinate = new Vector2(0,0),
161                },
162                new VertexPositionColorTexture()
163                {
164                    Position = v1,
165                    Color = color,
166                    TextureCoordinate = new Vector2(1,0),
167                },
168                new VertexPositionColorTexture()
169                {
170                    Position = v3,
171                    Color = color,
172                    TextureCoordinate = new Vector2(0,1),
173                },
174                new VertexPositionColorTexture()
175                {
176                    Position = v4,
177                    Color = color,
178                    TextureCoordinate = new Vector2(1,1),
179                },
180            };
181
182            this.mGraphicsDevice.DrawUserPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleStrip, quad, 0, 2);
183        }
184
185        public void DrawClippedFov(Vector2 position, float rotation, float size, Color color, float fov)
186        {
187            fov = MathHelper.Clamp(fov, 0, MathHelper.TwoPi);
188
189            if (fov == 0)
190            {
191                return;
192            }
193            else if (fov == MathHelper.TwoPi)
194            {
195                this.DrawSquareQuad(position, rotation, size, color);
196                return;
197            }
198            else
199            {
200                var ccw = ClampToBox(fov / 2);
201                var cw = ClampToBox(-fov / 2);
202
203                var ccwTex = new Vector2(ccw.X + 1, -ccw.Y + 1) / 2f;
204                var cwTex = new Vector2(cw.X + 1, -cw.Y + 1) / 2f;
205
206                VertexPositionColorTexture[] vertices;
207
208                #region Vertices
209                vertices = new VertexPositionColorTexture[]
210            {
211                new VertexPositionColorTexture()
212                {
213                    Position = Vector3.Zero,
214                    Color = color,
215                    TextureCoordinate = new Vector2(0.5f, 0.5f),
216                },
217                new VertexPositionColorTexture()
218                {
219                    Position = new Vector3(ccw,0),
220                    Color = color,
221                    TextureCoordinate = ccwTex
222                },
223                new VertexPositionColorTexture()
224                {
225                    Position = new Vector3(-1, 1, 0),
226                    Color = color,
227                    TextureCoordinate = new Vector2(0, 0),
228                },
229                new VertexPositionColorTexture()
230                {
231                    Position = new Vector3(1, 1, 0),
232                    Color = color,
233                    TextureCoordinate = new Vector2(1, 0),
234                },
235                new VertexPositionColorTexture()
236                {
237                    Position = new Vector3(1, -1, 0),
238                    Color = color,
239                    TextureCoordinate = new Vector2(1, 1),
240                },
241                new VertexPositionColorTexture()
242                {
243                    Position = new Vector3(-1, -1, 0),
244                    Color = color,
245                    TextureCoordinate = new Vector2(0, 1),
246                },
247                new VertexPositionColorTexture()
248                {
249                    Position = new Vector3(cw, 0),
250                    Color = color,
251                    TextureCoordinate = cwTex,
252                },
253            };
254
255                var r = Matrix.CreateRotationZ(rotation) * Matrix.CreateScale(size / 2) * Matrix.CreateTranslation(new Vector3(position, 0));
256
257                for (int i = 0; i < vertices.Length; i++)
258                {
259                    var vertex = vertices[i];
260
261                    Vector3.Transform(ref vertex.Position, ref r, out vertex.Position);
262
263                    vertices[i] = vertex;
264                }
265
266                #endregion Vertices
267
268                Int32[] indicies;
269
270                #region Indicies
271
272                if (fov <= MathHelper.Pi / 2)
273                {
274                    indicies = new Int32[]
275                    {
276                        0, 1, 6,
277                    };
278                }
279                else if (fov <= 3 * MathHelper.Pi / 2)
280                {
281                    indicies = new Int32[]
282                    {
283                        0, 1, 3,
284                        0, 3, 4,
285                        0, 4, 6,
286                    };
287                }
288                else
289                {
290                    indicies = new Int32[]
291                    {
292                        0, 1, 2,
293                        0, 2, 3,
294                        0, 3, 4,
295                        0, 4, 5,
296                        0, 5, 6,
297                    };
298                }
299                #endregion Indicies
300
301                this.mGraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColorTexture>(PrimitiveType.TriangleList, vertices, 0, vertices.Length, indicies, 0, indicies.Length / 3);
302            }
303        }
304
305        public static Vector2 ClampToBox(float angle)
306        {
307            var x = Math.Cos(angle);
308            var y = Math.Sin(angle);
309            var absMax = Math.Max(Math.Abs(x), Math.Abs(y));
310
311            return new Vector2((float)(x / absMax), (float)(y / absMax));
312        }
313
314        public void BufferDraw()
315        {
316            if (this.mShadowHullIndicies.Count >= 3)
317            {
318                this.mGraphicsDevice.DrawUserIndexedPrimitives<ShadowHullVertex>(PrimitiveType.TriangleList, this.mShadowHullVertices.ToArray(), 0, this.mShadowHullVertices.Count, this.mShadowHullIndicies.ToArray(), 0, this.mShadowHullIndicies.Count / 3);
319            }
320        }
321
322        public void DrawFullscreenQuad()
323        {
324            // Obtain the original rendering states
325            var originalRasterizerState = this.mGraphicsDevice.RasterizerState;
326
327            // Draw the quad
328            this.mEffect.CurrentTechnique = this.mEffect.Techniques["ScreenCopy"];
329            //this.mGraphicsDevice.RasterizerState = RasterizerState.CullNone;
330
331            this.mEffect.Parameters["TexelBias"].SetValue(new Vector2(0.5f / this.mGraphicsDevice.Viewport.Width, 0.5f / this.mGraphicsDevice.Viewport.Height));
332
333            foreach (var effectPass in this.mEffect.CurrentTechnique.Passes)
334            {
335                effectPass.Apply();
336                this.mGraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, KryptonRenderHelper.UnitQuad, 0, 2);
337            }
338
339            // Reset to the original rendering states
340            //this.mGraphicsDevice.RasterizerState = originalRasterizerState;
341        }
342
343        public void BlurTextureToTarget(Texture2D texture, LightMapSize mapSize, BlurTechnique blurTechnique, float bluriness)
344        {
345            // Get the pass to use
346            string passName = "";
347
348            switch (blurTechnique)
349            {
350                case (BlurTechnique.Horizontal):
351                    this.mEffect.Parameters["BlurFactorU"].SetValue(1f / this.GraphicsDevice.PresentationParameters.BackBufferWidth);
352                    passName = "HorizontalBlur";
353                    break;
354
355                case (BlurTechnique.Vertical):
356                    this.mEffect.Parameters["BlurFactorV"].SetValue(1f / this.mGraphicsDevice.PresentationParameters.BackBufferHeight);
357                    passName = "VerticalBlur";
358                    break;
359            }
360
361            var biasFactor = KryptonRenderHelper.BiasFactorFromLightMapSize(mapSize);
362
363            // Calculate the texel bias
364            Vector2 texelBias = new Vector2()
365            {
366                X = biasFactor / this.mGraphicsDevice.Viewport.Width,
367                Y = biasFactor / this.mGraphicsDevice.Viewport.Height,
368            };
369
370
371            this.mEffect.Parameters["Texture0"].SetValue(texture);
372            this.mEffect.Parameters["TexelBias"].SetValue(texelBias);
373            this.mEffect.Parameters["Bluriness"].SetValue(bluriness);
374            this.mEffect.CurrentTechnique = this.mEffect.Techniques["Blur"];
375
376            mEffect.CurrentTechnique.Passes[passName].Apply();
377            this.mGraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, KryptonRenderHelper.UnitQuad, 0, 2);
378        }
379
380        public void DrawTextureToTarget(Texture2D texture, LightMapSize mapSize, BlendTechnique blend)
381        {
382            // Get the technique to use
383            string techniqueName = "";
384
385            switch (blend)
386            {
387                case(BlendTechnique.Add):
388                    techniqueName = "TextureToTarget_Add";
389                    break;
390
391                case(BlendTechnique.Multiply):
392                    techniqueName = "TextureToTarget_Multiply";
393                    break;
394            }
395
396            var biasFactor = KryptonRenderHelper.BiasFactorFromLightMapSize(mapSize);
397
398            // Calculate the texel bias
399            Vector2 texelBias = new Vector2()
400            {
401                X = biasFactor / this.mGraphicsDevice.ScissorRectangle.Width,
402                Y = biasFactor / this.mGraphicsDevice.ScissorRectangle.Height,
403            };
404
405            this.mEffect.Parameters["Texture0"].SetValue(texture);
406            this.mEffect.Parameters["TexelBias"].SetValue(texelBias);
407            this.mEffect.CurrentTechnique = this.mEffect.Techniques[techniqueName];
408
409            // Draw the quad
410            foreach (var effectPass in this.mEffect.CurrentTechnique.Passes)
411            {
412                effectPass.Apply();
413                this.mGraphicsDevice.DrawUserPrimitives<VertexPositionTexture>(PrimitiveType.TriangleStrip, KryptonRenderHelper.UnitQuad, 0, 2);
414            }
415        }
416
417        private static float BiasFactorFromLightMapSize(LightMapSize mapSize)
418        {
419            switch (mapSize)
420            {
421                case (LightMapSize.Full):
422                    return 0.5f;
423
424                case (LightMapSize.Fourth):
425                    return 0.6f;
426
427                case (LightMapSize.Eighth):
428                    return 0.7f;
429
430                default:
431                    return 0.0f;
432            }
433        }
434
435        public void BufferAddBoundOutline(Common.BoundingRect boundingRect)
436        {
437            var vertexCount = this.mShadowHullVertices.Count;
438
439            this.mShadowHullVertices.Add(new ShadowHullVertex()
440            {
441                Color = Color.Black,
442                Normal = Vector2.Zero,
443                Position = new Vector2(boundingRect.Left, boundingRect.Top)
444            });
445
446            this.mShadowHullVertices.Add(new ShadowHullVertex()
447            {
448                Color = Color.Black,
449                Normal = Vector2.Zero,
450                Position = new Vector2(boundingRect.Right, boundingRect.Top)
451            });
452
453            this.mShadowHullVertices.Add(new ShadowHullVertex()
454            {
455                Color = Color.Black,
456                Normal = Vector2.Zero,
457                Position = new Vector2(boundingRect.Right, boundingRect.Bottom)
458            });
459
460            this.mShadowHullVertices.Add(new ShadowHullVertex()
461            {
462                Color = Color.Black,
463                Normal = Vector2.Zero,
464                Position = new Vector2(boundingRect.Left, boundingRect.Bottom)
465            });
466
467            this.mShadowHullIndicies.Add(vertexCount + 0);
468            this.mShadowHullIndicies.Add(vertexCount + 1);
469            this.mShadowHullIndicies.Add(vertexCount + 2);
470
471            this.mShadowHullIndicies.Add(vertexCount + 0);
472            this.mShadowHullIndicies.Add(vertexCount + 2);
473            this.mShadowHullIndicies.Add(vertexCount + 3);
474        }
475    }
476}
Note: See TracBrowser for help on using the repository browser.