Client LuaCsForBarotrauma
LevelRenderer.cs
2 using Microsoft.Xna.Framework;
3 using Microsoft.Xna.Framework.Graphics;
4 using System;
5 using System.Collections.Generic;
6 using System.Linq;
7 using Voronoi2;
8 
9 namespace Barotrauma
10 {
11  class LevelWallVertexBuffer : IDisposable
12  {
13  public VertexBuffer WallEdgeBuffer, WallBuffer;
14  public readonly Texture2D WallTexture, EdgeTexture;
15  private VertexPositionColorTexture[] wallVertices;
16  private VertexPositionColorTexture[] wallEdgeVertices;
17 
18  public bool IsDisposed
19  {
20  get;
21  private set;
22  }
23 
24  public LevelWallVertexBuffer(VertexPositionTexture[] wallVertices, VertexPositionTexture[] wallEdgeVertices, Texture2D wallTexture, Texture2D edgeTexture, Color color)
25  {
26  if (wallVertices.Length == 0)
27  {
28  throw new ArgumentException("Failed to instantiate a LevelWallVertexBuffer (no wall vertices).");
29  }
30  if (wallVertices.Length == 0)
31  {
32  throw new ArgumentException("Failed to instantiate a LevelWallVertexBuffer (no wall edge vertices).");
33  }
34  this.wallVertices = LevelRenderer.GetColoredVertices(wallVertices, color);
35  WallBuffer = new VertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, wallVertices.Length, BufferUsage.WriteOnly);
36  WallBuffer.SetData(this.wallVertices);
37  WallTexture = wallTexture;
38 
39  this.wallEdgeVertices = LevelRenderer.GetColoredVertices(wallEdgeVertices, color);
40  WallEdgeBuffer = new VertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, wallEdgeVertices.Length, BufferUsage.WriteOnly);
41  WallEdgeBuffer.SetData(this.wallEdgeVertices);
42  EdgeTexture = edgeTexture;
43  }
44 
45  public void Append(VertexPositionTexture[] wallVertices, VertexPositionTexture[] wallEdgeVertices, Color color)
46  {
47  WallBuffer.Dispose();
48  WallBuffer = new VertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, this.wallVertices.Length + wallVertices.Length, BufferUsage.WriteOnly);
49  int originalWallVertexCount = this.wallVertices.Length;
50  Array.Resize(ref this.wallVertices, originalWallVertexCount + wallVertices.Length);
51  Array.Copy(LevelRenderer.GetColoredVertices(wallVertices, color), 0, this.wallVertices, originalWallVertexCount, wallVertices.Length);
52  WallBuffer.SetData(this.wallVertices);
53 
54  WallEdgeBuffer.Dispose();
55  WallEdgeBuffer = new VertexBuffer(GameMain.Instance.GraphicsDevice, VertexPositionColorTexture.VertexDeclaration, this.wallEdgeVertices.Length + wallEdgeVertices.Length, BufferUsage.WriteOnly);
56  int originalWallEdgeVertexCount = this.wallEdgeVertices.Length;
57  Array.Resize(ref this.wallEdgeVertices, originalWallEdgeVertexCount + wallEdgeVertices.Length);
58  Array.Copy(LevelRenderer.GetColoredVertices(wallEdgeVertices, color), 0, this.wallEdgeVertices, originalWallEdgeVertexCount, wallEdgeVertices.Length);
59  WallEdgeBuffer.SetData(this.wallEdgeVertices);
60  }
61 
62  public void Dispose()
63  {
64  IsDisposed = true;
65  WallEdgeBuffer?.Dispose();
66  WallBuffer?.Dispose();
67  }
68  }
69 
70  class LevelRenderer : IDisposable
71  {
72  private static BasicEffect wallEdgeEffect, wallCenterEffect;
73 
74  private Vector2 waterParticleOffset;
75  private Vector2 waterParticleVelocity;
76 
77  private float flashCooldown;
78  private float flashTimer;
79  public Color FlashColor { get; private set; }
80 
81  private readonly RasterizerState cullNone;
82 
83  private readonly Level level;
84 
85  private readonly List<LevelWallVertexBuffer> vertexBuffers = new List<LevelWallVertexBuffer>();
86 
87  private float chromaticAberrationStrength;
89  {
90  get { return chromaticAberrationStrength; }
91  set { chromaticAberrationStrength = MathHelper.Clamp(value, 0.0f, 100.0f); }
92  }
94  {
95  get;
96  set;
97  }
98  public Vector2 CollapseEffectOrigin
99  {
100  get;
101  set;
102  }
103 
104 
105  public LevelRenderer(Level level)
106  {
107  cullNone = new RasterizerState() { CullMode = CullMode.None };
108 
109  if (wallEdgeEffect == null)
110  {
111  wallEdgeEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
112  {
113  DiffuseColor = new Vector3(0.8f, 0.8f, 0.8f),
114  VertexColorEnabled = true,
115  TextureEnabled = true,
116  Texture = level.GenerationParams.WallEdgeSprite.Texture
117  };
118  wallEdgeEffect.CurrentTechnique = wallEdgeEffect.Techniques["BasicEffect_Texture"];
119  }
120 
121  if (wallCenterEffect == null)
122  {
123  wallCenterEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
124  {
125  VertexColorEnabled = true,
126  TextureEnabled = true,
127  Texture = level.GenerationParams.WallSprite.Texture
128  };
129  wallCenterEffect.CurrentTechnique = wallCenterEffect.Techniques["BasicEffect_Texture"];
130  }
131 
132  this.level = level;
133  }
134 
135  public void ReloadTextures()
136  {
137  level.GenerationParams.WallEdgeSprite.ReloadTexture();
138  wallEdgeEffect.Texture = level.GenerationParams.WallEdgeSprite.Texture;
139  level.GenerationParams.WallSprite.ReloadTexture();
140  wallCenterEffect.Texture = level.GenerationParams.WallSprite.Texture;
141  }
142 
143  public void Flash()
144  {
145  flashTimer = 1.0f;
146  }
147 
148  public void Update(float deltaTime, Camera cam)
149  {
150  if (CollapseEffectStrength > 0.0f)
151  {
152  CollapseEffectStrength = Math.Max(0.0f, CollapseEffectStrength - deltaTime);
153  }
154  if (ChromaticAberrationStrength > 0.0f)
155  {
156  ChromaticAberrationStrength = Math.Max(0.0f, ChromaticAberrationStrength - deltaTime * 10.0f);
157  }
158 
159  if (level.GenerationParams.FlashInterval.Y > 0)
160  {
161  flashCooldown -= deltaTime;
162  if (flashCooldown <= 0.0f)
163  {
164  flashTimer = 1.0f;
165  if (level.GenerationParams.FlashSound != null)
166  {
167  level.GenerationParams.FlashSound.Play(1.0f, "default");
168  }
169  flashCooldown = Rand.Range(level.GenerationParams.FlashInterval.X, level.GenerationParams.FlashInterval.Y, Rand.RandSync.Unsynced);
170  }
171  if (flashTimer > 0.0f)
172  {
173  float brightness = flashTimer * 1.1f - PerlinNoise.GetPerlin((float)Timing.TotalTime, (float)Timing.TotalTime * 0.66f) * 0.1f;
174  FlashColor = level.GenerationParams.FlashColor.Multiply(MathHelper.Clamp(brightness, 0.0f, 1.0f));
175  flashTimer -= deltaTime * 0.5f;
176  }
177  else
178  {
179  FlashColor = Color.TransparentBlack;
180  }
181  }
182 
183  //calculate the sum of the forces of nearby level triggers
184  //and use it to move the water texture and water distortion effect
185  Vector2 currentWaterParticleVel = level.GenerationParams.WaterParticleVelocity;
186  foreach (LevelObject levelObject in level.LevelObjectManager.GetVisibleObjects())
187  {
188  if (levelObject.Triggers == null) { continue; }
189  //use the largest water flow velocity of all the triggers
190  Vector2 objectMaxFlow = Vector2.Zero;
191  foreach (LevelTrigger trigger in levelObject.Triggers)
192  {
193  Vector2 vel = trigger.GetWaterFlowVelocity(cam.WorldViewCenter);
194  if (vel.LengthSquared() > objectMaxFlow.LengthSquared())
195  {
196  objectMaxFlow = vel;
197  }
198  }
199  currentWaterParticleVel += objectMaxFlow;
200  }
201 
202  waterParticleVelocity = Vector2.Lerp(waterParticleVelocity, currentWaterParticleVel, deltaTime);
203 
204  WaterRenderer.Instance?.ScrollWater(waterParticleVelocity, deltaTime);
205 
206  if (level.GenerationParams.WaterParticles != null)
207  {
208  Vector2 waterTextureSize = level.GenerationParams.WaterParticles.size * level.GenerationParams.WaterParticleScale;
209  waterParticleOffset += new Vector2(waterParticleVelocity.X, -waterParticleVelocity.Y) * level.GenerationParams.WaterParticleScale * deltaTime;
210  while (waterParticleOffset.X <= -waterTextureSize.X) { waterParticleOffset.X += waterTextureSize.X; }
211  while (waterParticleOffset.X >= waterTextureSize.X){ waterParticleOffset.X -= waterTextureSize.X; }
212  while (waterParticleOffset.Y <= -waterTextureSize.Y) { waterParticleOffset.Y += waterTextureSize.Y; }
213  while (waterParticleOffset.Y >= waterTextureSize.Y) { waterParticleOffset.Y -= waterTextureSize.Y; }
214  }
215  }
216 
217  public static VertexPositionColorTexture[] GetColoredVertices(VertexPositionTexture[] vertices, Color color)
218  {
219  VertexPositionColorTexture[] verts = new VertexPositionColorTexture[vertices.Length];
220  for (int i = 0; i < vertices.Length; i++)
221  {
222  verts[i] = new VertexPositionColorTexture(vertices[i].Position, color, vertices[i].TextureCoordinate);
223  }
224  return verts;
225  }
226 
227  public void SetVertices(VertexPositionTexture[] wallVertices, VertexPositionTexture[] wallEdgeVertices, Texture2D wallTexture, Texture2D edgeTexture, Color color)
228  {
229  var existingBuffer = vertexBuffers.Find(vb => vb.WallTexture == wallTexture && vb.EdgeTexture == edgeTexture);
230  if (existingBuffer != null)
231  {
232  existingBuffer.Append(wallVertices, wallEdgeVertices,color);
233  }
234  else
235  {
236  vertexBuffers.Add(new LevelWallVertexBuffer(wallVertices, wallEdgeVertices, wallTexture, edgeTexture, color));
237  }
238  }
239 
240  public void DrawBackground(SpriteBatch spriteBatch, Camera cam,
241  LevelObjectManager backgroundSpriteManager = null,
242  BackgroundCreatureManager backgroundCreatureManager = null)
243  {
244  spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied, SamplerState.LinearWrap);
245 
246  Vector2 backgroundPos = cam.WorldViewCenter;
247 
248  backgroundPos.Y = -backgroundPos.Y;
249  backgroundPos *= 0.05f;
250 
251  if (level.GenerationParams.BackgroundTopSprite != null)
252  {
253  int backgroundSize = (int)level.GenerationParams.BackgroundTopSprite.size.Y;
254  if (backgroundPos.Y < backgroundSize)
255  {
256  if (backgroundPos.Y < 0)
257  {
258  var backgroundTop = level.GenerationParams.BackgroundTopSprite;
259  backgroundTop.SourceRect = new Rectangle((int)backgroundPos.X, (int)backgroundPos.Y, backgroundSize, (int)Math.Min(-backgroundPos.Y, backgroundSize));
260  backgroundTop.DrawTiled(spriteBatch, Vector2.Zero, new Vector2(GameMain.GraphicsWidth, Math.Min(-backgroundPos.Y, GameMain.GraphicsHeight)),
261  color: level.BackgroundTextureColor);
262  }
263  if (-backgroundPos.Y < GameMain.GraphicsHeight && level.GenerationParams.BackgroundSprite != null)
264  {
265  var background = level.GenerationParams.BackgroundSprite;
266  background.SourceRect = new Rectangle((int)backgroundPos.X, (int)Math.Max(backgroundPos.Y, 0), backgroundSize, backgroundSize);
267  background.DrawTiled(spriteBatch,
268  (backgroundPos.Y < 0) ? new Vector2(0.0f, (int)-backgroundPos.Y) : Vector2.Zero,
269  new Vector2(GameMain.GraphicsWidth, (int)Math.Min(Math.Ceiling(backgroundSize - backgroundPos.Y), backgroundSize)),
270  color: level.BackgroundTextureColor);
271  }
272  }
273  }
274 
275  spriteBatch.End();
276 
277  spriteBatch.Begin(SpriteSortMode.Deferred,
278  BlendState.NonPremultiplied,
279  SamplerState.LinearWrap, DepthStencilState.DepthRead, null, null,
280  cam.Transform);
281 
282  backgroundSpriteManager?.DrawObjectsBack(spriteBatch, cam);
283  if (cam.Zoom > 0.05f)
284  {
285  backgroundCreatureManager?.Draw(spriteBatch, cam);
286  }
287 
288  if (level.GenerationParams.WaterParticles != null && cam.Zoom > 0.05f)
289  {
290  float textureScale = level.GenerationParams.WaterParticleScale;
291 
292  Rectangle srcRect = new Rectangle(0, 0, 2048, 2048);
293  Vector2 origin = new Vector2(cam.WorldView.X, -cam.WorldView.Y);
294  Vector2 offset = -origin + waterParticleOffset;
295  while (offset.X <= -srcRect.Width * textureScale) offset.X += srcRect.Width * textureScale;
296  while (offset.X > 0.0f) offset.X -= srcRect.Width * textureScale;
297  while (offset.Y <= -srcRect.Height * textureScale) offset.Y += srcRect.Height * textureScale;
298  while (offset.Y > 0.0f) offset.Y -= srcRect.Height * textureScale;
299  for (int i = 0; i < 4; i++)
300  {
301  float scale = (1.0f - i * 0.2f);
302 
303  //alpha goes from 1.0 to 0.0 when scale is in the range of 0.1 - 0.05
304  float alpha = (cam.Zoom * scale) < 0.1f ? (cam.Zoom * scale - 0.05f) * 20.0f : 1.0f;
305  if (alpha <= 0.0f) continue;
306 
307  Vector2 offsetS = offset * scale
308  + new Vector2(cam.WorldView.Width, cam.WorldView.Height) * (1.0f - scale) * 0.5f
309  - new Vector2(256.0f * i);
310 
311  float texScale = scale * textureScale;
312 
313  while (offsetS.X <= -srcRect.Width * texScale) offsetS.X += srcRect.Width * texScale;
314  while (offsetS.X > 0.0f) offsetS.X -= srcRect.Width * texScale;
315  while (offsetS.Y <= -srcRect.Height * texScale) offsetS.Y += srcRect.Height * texScale;
316  while (offsetS.Y > 0.0f) offsetS.Y -= srcRect.Height * texScale;
317 
318  level.GenerationParams.WaterParticles.DrawTiled(
319  spriteBatch, origin + offsetS,
320  new Vector2(cam.WorldView.Width - offsetS.X, cam.WorldView.Height - offsetS.Y),
321  color: level.GenerationParams.WaterParticleColor * alpha, textureScale: new Vector2(texScale));
322  }
323  }
324  spriteBatch.End();
325 
326  RenderWalls(GameMain.Instance.GraphicsDevice, cam);
327 
328  spriteBatch.Begin(SpriteSortMode.Deferred,
329  BlendState.NonPremultiplied,
330  SamplerState.LinearClamp, DepthStencilState.DepthRead, null, null,
331  cam.Transform);
332  backgroundSpriteManager?.DrawObjectsMid(spriteBatch, cam);
333  spriteBatch.End();
334  }
335 
336  public void DrawForeground(SpriteBatch spriteBatch, Camera cam, LevelObjectManager backgroundSpriteManager = null)
337  {
338  spriteBatch.Begin(SpriteSortMode.Deferred,
339  BlendState.NonPremultiplied,
340  SamplerState.LinearClamp, DepthStencilState.DepthRead, null, null,
341  cam.Transform);
342  backgroundSpriteManager?.DrawObjectsFront(spriteBatch, cam);
343  spriteBatch.End();
344  }
345 
346  public void DrawDebugOverlay(SpriteBatch spriteBatch, Camera cam)
347  {
348  if (GameMain.DebugDraw && cam.Zoom > 0.1f)
349  {
350  var cells = level.GetCells(cam.WorldViewCenter, 2);
351  foreach (VoronoiCell cell in cells)
352  {
353  GUI.DrawRectangle(spriteBatch, new Vector2(cell.Center.X - 10.0f, -cell.Center.Y - 10.0f), new Vector2(20.0f, 20.0f), Color.Cyan, true);
354 
355  GUI.DrawLine(spriteBatch,
356  new Vector2(cell.Edges[0].Point1.X + cell.Translation.X, -(cell.Edges[0].Point1.Y + cell.Translation.Y)),
357  new Vector2(cell.Center.X, -(cell.Center.Y)),
358  Color.Blue * 0.5f);
359 
360  foreach (GraphEdge edge in cell.Edges)
361  {
362  GUI.DrawLine(spriteBatch, new Vector2(edge.Point1.X + cell.Translation.X, -(edge.Point1.Y + cell.Translation.Y)),
363  new Vector2(edge.Point2.X + cell.Translation.X, -(edge.Point2.Y + cell.Translation.Y)), edge.NextToCave ? Color.Red : (cell.Body == null ? Color.Cyan * 0.5f : (edge.IsSolid ? Color.White : Color.Gray)),
364  width: edge.NextToCave ? 8 : 1);
365 
366  Vector2 normal = edge.GetNormal(cell);
367  GUI.DrawLine(spriteBatch,
368  (edge.Center + cell.Translation).FlipY(),
369  (edge.Center + cell.Translation + normal * 32).FlipY(),
370  Color.Red * 0.5f,
371  width: 3);
372  }
373 
374  foreach (Vector2 point in cell.BodyVertices)
375  {
376  GUI.DrawRectangle(spriteBatch, new Vector2(point.X + cell.Translation.X, -(point.Y + cell.Translation.Y)), new Vector2(10.0f, 10.0f), Color.White, true);
377  }
378  }
379 
380  /*foreach (List<Point> nodeList in level.SmallTunnels)
381  {
382  for (int i = 1; i < nodeList.Count; i++)
383  {
384  GUI.DrawLine(spriteBatch,
385  new Vector2(nodeList[i - 1].X, -nodeList[i - 1].Y),
386  new Vector2(nodeList[i].X, -nodeList[i].Y),
387  Color.Lerp(Color.Yellow, GUIStyle.Red, i / (float)nodeList.Count), 0, 10);
388  }
389  }*/
390 
391  foreach (var abyssIsland in level.AbyssIslands)
392  {
393  GUI.DrawRectangle(spriteBatch, new Vector2(abyssIsland.Area.X, -abyssIsland.Area.Y - abyssIsland.Area.Height), abyssIsland.Area.Size.ToVector2(), Color.Cyan, thickness: 5);
394  }
395 
396  foreach (var ruin in level.Ruins)
397  {
398  ruin.DebugDraw(spriteBatch);
399  }
400  }
401 
402  Vector2 pos = new Vector2(0.0f, -level.Size.Y);
403  if (cam.WorldView.Y >= -pos.Y - 1024)
404  {
405  int topBarrierWidth = level.GenerationParams.WallEdgeSprite.Texture.Width;
406  int topBarrierHeight = level.GenerationParams.WallEdgeSprite.Texture.Height;
407 
408  pos.X = cam.WorldView.X - topBarrierWidth;
409  int width = (int)(Math.Ceiling(cam.WorldView.Width / 1024 + 4.0f) * topBarrierWidth);
410 
411  GUI.DrawRectangle(spriteBatch, new Rectangle(
412  (int)MathUtils.Round(pos.X, topBarrierWidth),
413  -cam.WorldView.Y,
414  width,
415  (int)(cam.WorldView.Y + pos.Y) - 60),
416  Color.Black, true);
417 
418  spriteBatch.Draw(level.GenerationParams.WallEdgeSprite.Texture,
419  new Rectangle((int)MathUtils.Round(pos.X, topBarrierWidth), (int)(pos.Y - topBarrierHeight + level.GenerationParams.WallEdgeExpandOutwardsAmount), width, topBarrierHeight),
420  new Rectangle(0, 0, width, -topBarrierHeight),
421  GameMain.LightManager?.LightingEnabled ?? false ? GameMain.LightManager.AmbientLight : level.WallColor, 0.0f,
422  Vector2.Zero,
423  SpriteEffects.None, 0.0f);
424  }
425 
426  if (cam.WorldView.Y - cam.WorldView.Height < level.SeaFloorTopPos + 1024)
427  {
428  int bottomBarrierWidth = level.GenerationParams.WallEdgeSprite.Texture.Width;
429  int bottomBarrierHeight = level.GenerationParams.WallEdgeSprite.Texture.Height;
430  pos = new Vector2(cam.WorldView.X - bottomBarrierWidth, -level.BottomPos);
431  int width = (int)(Math.Ceiling(cam.WorldView.Width / bottomBarrierWidth + 4.0f) * bottomBarrierWidth);
432 
433  GUI.DrawRectangle(spriteBatch, new Rectangle(
434  (int)(MathUtils.Round(pos.X, bottomBarrierWidth)),
435  -(level.BottomPos - 60),
436  width,
437  level.BottomPos - (cam.WorldView.Y - cam.WorldView.Height)),
438  Color.Black, true);
439 
440  spriteBatch.Draw(level.GenerationParams.WallEdgeSprite.Texture,
441  new Rectangle((int)MathUtils.Round(pos.X, bottomBarrierWidth), -level.BottomPos - (int)level.GenerationParams.WallEdgeExpandOutwardsAmount, width, bottomBarrierHeight),
442  new Rectangle(0, 0, width, -bottomBarrierHeight),
443  GameMain.LightManager?.LightingEnabled ?? false ? GameMain.LightManager.AmbientLight : level.WallColor, 0.0f,
444  Vector2.Zero,
445  SpriteEffects.FlipVertically, 0.0f);
446  }
447  }
448 
449 
450  public void RenderWalls(GraphicsDevice graphicsDevice, Camera cam)
451  {
452  if (!vertexBuffers.Any()) { return; }
453 
454  var defaultRasterizerState = graphicsDevice.RasterizerState;
455 
456  Matrix transformMatrix = cam.ShaderTransform
457  * Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 100) * 0.5f;
458 
459  graphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
460  graphicsDevice.RasterizerState = cullNone;
461 
462  //render destructible walls
463  for (int i = 0; i < 2; i++)
464  {
465  var wallList = i == 0 ? level.ExtraWalls : level.UnsyncedExtraWalls;
466  foreach (LevelWall wall in wallList)
467  {
468  if (!(wall is DestructibleLevelWall destructibleWall) || destructibleWall.Destroyed) { continue; }
469 
470  wallCenterEffect.Texture = level.GenerationParams.DestructibleWallSprite?.Texture ?? level.GenerationParams.WallSprite.Texture;
471  wallCenterEffect.World = wall.GetTransform() * transformMatrix;
472  wallCenterEffect.Alpha = wall.Alpha;
473  wallCenterEffect.CurrentTechnique.Passes[0].Apply();
474  graphicsDevice.SetVertexBuffer(wall.WallBuffer);
475  graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallBuffer.VertexCount / 3.0f));
476 
477  if (destructibleWall.Damage > 0.0f)
478  {
479  wallCenterEffect.Texture = level.GenerationParams.WallSpriteDestroyed.Texture;
480  wallCenterEffect.Alpha = MathHelper.Lerp(0.2f, 1.0f, destructibleWall.Damage / destructibleWall.MaxHealth) * wall.Alpha;
481  wallCenterEffect.CurrentTechnique.Passes[0].Apply();
482  graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallEdgeBuffer.VertexCount / 3.0f));
483  }
484 
485  wallEdgeEffect.Texture = level.GenerationParams.DestructibleWallEdgeSprite?.Texture ?? level.GenerationParams.WallEdgeSprite.Texture;
486  wallEdgeEffect.World = wall.GetTransform() * transformMatrix;
487  wallEdgeEffect.Alpha = wall.Alpha;
488  wallEdgeEffect.CurrentTechnique.Passes[0].Apply();
489  graphicsDevice.SetVertexBuffer(wall.WallEdgeBuffer);
490  graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallEdgeBuffer.VertexCount / 3.0f));
491  }
492  }
493 
494  wallEdgeEffect.Alpha = 1.0f;
495  wallCenterEffect.Alpha = 1.0f;
496 
497  wallCenterEffect.World = transformMatrix;
498  wallEdgeEffect.World = transformMatrix;
499 
500  //render static walls
501  foreach (var vertexBuffer in vertexBuffers)
502  {
503  wallCenterEffect.Texture = vertexBuffer.WallTexture;
504  wallCenterEffect.CurrentTechnique.Passes[0].Apply();
505  graphicsDevice.SetVertexBuffer(vertexBuffer.WallBuffer);
506  graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(vertexBuffer.WallBuffer.VertexCount / 3.0f));
507 
508  wallEdgeEffect.Texture = vertexBuffer.EdgeTexture;
509  wallEdgeEffect.CurrentTechnique.Passes[0].Apply();
510  graphicsDevice.SetVertexBuffer(vertexBuffer.WallEdgeBuffer);
511  graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(vertexBuffer.WallEdgeBuffer.VertexCount / 3.0f));
512  }
513 
514  wallCenterEffect.Texture = level.GenerationParams.WallSprite.Texture;
515  wallEdgeEffect.Texture = level.GenerationParams.WallEdgeSprite.Texture;
516 
517  //render non-destructible extra walls
518  for (int i = 0; i < 2; i++)
519  {
520  var wallList = i == 0 ? level.ExtraWalls : level.UnsyncedExtraWalls;
521  foreach (LevelWall wall in wallList)
522  {
523  if (wall is DestructibleLevelWall) { continue; }
524  //TODO: use LevelWallVertexBuffers for extra walls as well
525  wallCenterEffect.World = wall.GetTransform() * transformMatrix;
526  wallCenterEffect.Alpha = wall.Alpha;
527  wallCenterEffect.CurrentTechnique.Passes[0].Apply();
528  graphicsDevice.SetVertexBuffer(wall.WallBuffer);
529  graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallBuffer.VertexCount / 3.0f));
530 
531  wallEdgeEffect.World = wall.GetTransform() * transformMatrix;
532  wallEdgeEffect.Alpha = wall.Alpha;
533  wallEdgeEffect.CurrentTechnique.Passes[0].Apply();
534  graphicsDevice.SetVertexBuffer(wall.WallEdgeBuffer);
535  graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList, 0, (int)Math.Floor(wall.WallEdgeBuffer.VertexCount / 3.0f));
536  }
537  }
538 
539  graphicsDevice.RasterizerState = defaultRasterizerState;
540  }
541 
542  public void Dispose()
543  {
544  foreach (var vertexBuffer in vertexBuffers)
545  {
546  vertexBuffer.Dispose();
547  }
548  vertexBuffers.Clear();
549  }
550  }
551 }
float? Zoom
Definition: Camera.cs:78
Matrix Transform
Definition: Camera.cs:136
Rectangle WorldView
Definition: Camera.cs:123
Vector2 WorldViewCenter
Definition: Camera.cs:126
Matrix ShaderTransform
Definition: Camera.cs:141
static int GraphicsWidth
Definition: GameMain.cs:162
static int GraphicsHeight
Definition: GameMain.cs:168
static Lights.LightManager LightManager
Definition: GameMain.cs:78
static bool DebugDraw
Definition: GameMain.cs:29
static GameMain Instance
Definition: GameMain.cs:144
void DrawForeground(SpriteBatch spriteBatch, Camera cam, LevelObjectManager backgroundSpriteManager=null)
static VertexPositionColorTexture[] GetColoredVertices(VertexPositionTexture[] vertices, Color color)
void RenderWalls(GraphicsDevice graphicsDevice, Camera cam)
void DrawBackground(SpriteBatch spriteBatch, Camera cam, LevelObjectManager backgroundSpriteManager=null, BackgroundCreatureManager backgroundCreatureManager=null)
void DrawDebugOverlay(SpriteBatch spriteBatch, Camera cam)
void SetVertices(VertexPositionTexture[] wallVertices, VertexPositionTexture[] wallEdgeVertices, Texture2D wallTexture, Texture2D edgeTexture, Color color)
void Update(float deltaTime, Camera cam)
LevelWallVertexBuffer(VertexPositionTexture[] wallVertices, VertexPositionTexture[] wallEdgeVertices, Texture2D wallTexture, Texture2D edgeTexture, Color color)
void Append(VertexPositionTexture[] wallVertices, VertexPositionTexture[] wallEdgeVertices, Color color)
readonly Texture2D WallTexture
void ScrollWater(Vector2 vel, float deltaTime)
static WaterRenderer Instance
Vector2 GetNormal(VoronoiCell cell)
Returns the normal of the edge that points outwards from the specified cell
List< GraphEdge > Edges
List< Vector2 > BodyVertices