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