Krythic

BrushVolume

Jun 10th, 2020
306
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.88 KB | None | 0 0
  1. using SharpDX;
  2. using SharpDX.Direct3D11;
  3. using VoidwalkerEngine.Framework.Interfaces;
  4. using VoidwalkerEngine.Framework.Logic;
  5.  
  6. namespace VoidwalkerEngine.Framework.DirectX.Rendering
  7. {
  8.  
  9.     public class BrushVolume : GameEntity, IDrawable
  10.     {
  11.         private int _width;
  12.         private int _height;
  13.         private int _depth;
  14.         public int Width
  15.         {
  16.             get { return _width; }
  17.             set
  18.             {
  19.                 _width = value;
  20.                 Resize(_width, _height, _depth);
  21.             }
  22.         }
  23.         public int Height
  24.         {
  25.             get { return _height; }
  26.             set
  27.             {
  28.                 _height = value;
  29.                 Resize(_width, _height, _depth);
  30.             }
  31.         }
  32.         public int Depth
  33.         {
  34.             get { return _depth; }
  35.             set
  36.             {
  37.                 _depth = value;
  38.                 Resize(_width, _height, _depth);
  39.             }
  40.         }
  41.         public Material Tileset { get; set; }
  42.         public Device Device;
  43.         public Rectangle NorthFaceGraphic;
  44.         public Rectangle SouthFaceGraphic;
  45.         public Rectangle WestFaceGraphic;
  46.         public Rectangle EastFaceGraphic;
  47.         public Rectangle TopFaceGraphic;
  48.         public Rectangle BottomFaceGraphic;
  49.         // 36 Vertices maximum
  50.         private int _drawCount;
  51.         private VertexBufferBinding _buffer;
  52.         private const float _stride = 16;
  53.  
  54.         private CubeFaceVisibility _faces;
  55.         public CubeFaceVisibility Faces
  56.         {
  57.             get { return _faces; }
  58.             set
  59.             {
  60.                 _faces = value;
  61.                 Rebuild();
  62.             }
  63.         }
  64.  
  65.         public BrushVolume(Device device, Material diffuseMaterial,
  66.             int width, int height, int depth, CubeFaceVisibility faceVisibility,
  67.             Rectangle northRectangle, Rectangle eastRectangle,
  68.             Rectangle southRectangle, Rectangle westRectangle,
  69.             Rectangle topRectangle, Rectangle bottomRectangle)
  70.         {
  71.             this.Device = device;
  72.             this._width = width;
  73.             this._height = height;
  74.             this._depth = depth;
  75.             this._faces = faceVisibility;
  76.             this.Tileset = diffuseMaterial;
  77.             UpdateFaceGraphics(
  78.                 northRectangle,
  79.                 eastRectangle,
  80.                 southRectangle,
  81.                 westRectangle,
  82.                 topRectangle,
  83.                 bottomRectangle);
  84.             Rebuild();
  85.         }
  86.  
  87.         public void UpdateFaceGraphics(Rectangle northRectangle, Rectangle eastRectangle,
  88.             Rectangle southRectangle, Rectangle westRectangle,
  89.             Rectangle topRectangle, Rectangle bottomRectangle)
  90.         {
  91.             this.NorthFaceGraphic = northRectangle;
  92.             this.SouthFaceGraphic = southRectangle;
  93.             this.WestFaceGraphic = westRectangle;
  94.             this.EastFaceGraphic = eastRectangle;
  95.             this.TopFaceGraphic = topRectangle;
  96.             this.BottomFaceGraphic = bottomRectangle;
  97.         }
  98.  
  99.         public void Resize(int width, int height, int depth)
  100.         {
  101.             this._width = width;
  102.             this._height = height;
  103.             this._depth = depth;
  104.             Rebuild();
  105.         }
  106.  
  107.         private int CountVisibleFaces()
  108.         {
  109.             int value = (int)Faces;
  110.             value -= ((value >> 1) & 1431655765);
  111.             value = (value & 858993459) + ((value >> 2) & 858993459);
  112.             int count = ((value + (value >> 4) & 252645135) * 16843009) >> 24;
  113.             return count;
  114.         }
  115.  
  116.         public void CalculateTextureCoordinates(Rectangle textureRectangle, out float x, out float y, out float width, out float height)
  117.         {
  118.             x = textureRectangle.X / (float)this.Tileset.Width;
  119.             y = textureRectangle.Y / (float)this.Tileset.Height;
  120.             width = textureRectangle.Right / (float)this.Tileset.Width;
  121.             height = textureRectangle.Bottom / (float)this.Tileset.Height;
  122.         }
  123.  
  124.         public void Rebuild()
  125.         {
  126.             if(Faces == CubeFaceVisibility.None)
  127.             {
  128.                 return;
  129.             }
  130.             Vertex[] vertices = new Vertex[CountVisibleFaces() * 6];
  131.             float width = _stride * this.Width;
  132.             float height = _stride * this.Height;
  133.             float depth = _stride * this.Depth;
  134.             int index = 0;
  135.  
  136.             // Generate North Face
  137.             if (this.Faces.HasFlag(CubeFaceVisibility.North))
  138.             {
  139.                 Vector3 normal = new Vector3(0, 0, -1);
  140.                 CalculateTextureCoordinates(
  141.                     this.NorthFaceGraphic,
  142.                     out float uvX, out float uvY,
  143.                     out float uvWidth, out float uvHeight);
  144.                 vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(uvWidth, uvY), normal);
  145.                 vertices[index++] = new Vertex(new Vector3(width, height, -depth), new Vector2(uvX, uvY), normal);
  146.                 vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(uvX, uvHeight), normal);
  147.                 vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(uvWidth, uvY), normal);
  148.                 vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(uvWidth, uvHeight), normal);
  149.                 vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(uvX, uvHeight), normal);
  150.             }
  151.  
  152.             // Generate East Face
  153.             if (this.Faces.HasFlag(CubeFaceVisibility.East))
  154.             {
  155.                 Vector3 normal = new Vector3(1, 0, 0);
  156.                 CalculateTextureCoordinates(
  157.                     this.EastFaceGraphic,
  158.                     out float uvX, out float uvY,
  159.                     out float uvWidth, out float uvHeight);
  160.                 vertices[index++] = new Vertex(new Vector3(width, -height, depth), new Vector2(uvX, uvHeight), normal);
  161.                 vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(uvWidth, uvHeight), normal);
  162.                 vertices[index++] = new Vertex(new Vector3(width, height, -depth), new Vector2(uvWidth, uvY), normal);
  163.                 vertices[index++] = new Vertex(new Vector3(width, height, -depth), new Vector2(uvWidth, uvY), normal);
  164.                 vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvX, uvY), normal);
  165.                 vertices[index++] = new Vertex(new Vector3(width, -height, depth), new Vector2(uvX, uvHeight), normal);
  166.             }
  167.  
  168.             // Generate South Face
  169.             if (this.Faces.HasFlag(CubeFaceVisibility.South))
  170.             {
  171.                 Vector3 normal = new Vector3(0, 0, 1);
  172.                 CalculateTextureCoordinates(
  173.                     this.SouthFaceGraphic,
  174.                     out float uvX, out float uvY,
  175.                     out float uvWidth, out float uvHeight);
  176.                 vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvWidth, uvY), normal);
  177.                 vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(uvX, uvY), normal);
  178.                 vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvX, uvHeight), normal);
  179.                 vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvX, uvHeight), normal);
  180.                 vertices[index++] = new Vertex(new Vector3(width, -height, depth), new Vector2(uvWidth, uvHeight), normal);
  181.                 vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvWidth, uvY), normal);
  182.             }
  183.  
  184.             // Generate West Face
  185.             if (this.Faces.HasFlag(CubeFaceVisibility.West))
  186.             {
  187.                 Vector3 normal = new Vector3(-1, 0, 0);
  188.                 CalculateTextureCoordinates(
  189.                     this.WestFaceGraphic,
  190.                     out float uvX, out float uvY,
  191.                     out float uvWidth, out float uvHeight);
  192.                 vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(uvX, uvHeight), normal);
  193.                 vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvWidth, uvHeight), normal);
  194.                 vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(uvWidth, uvY), normal);
  195.                 vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(uvWidth, uvY), normal);
  196.                 vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(uvX, uvY), normal);
  197.                 vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(uvX, uvHeight), normal);
  198.             }
  199.  
  200.             // Generate Top Face
  201.             if (this.Faces.HasFlag(CubeFaceVisibility.Top))
  202.             {
  203.                 Vector3 normal = new Vector3(0, 1, 0);
  204.                 CalculateTextureCoordinates(
  205.                     this.TopFaceGraphic,
  206.                     out float uvX, out float uvY,
  207.                     out float uvWidth, out float uvHeight);
  208.                 vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvWidth, uvHeight), normal);
  209.                 vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(uvX, uvHeight), normal);
  210.                 vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(uvX, uvY), normal);
  211.                 vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(uvX, uvY), normal);
  212.                 vertices[index++] = new Vertex(new Vector3(width, height, -depth), new Vector2(uvWidth, uvY), normal);
  213.                 vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvWidth, uvHeight), normal);
  214.  
  215.             }
  216.  
  217.             // Generate Bottom Face
  218.             if (this.Faces.HasFlag(CubeFaceVisibility.Bottom))
  219.             {
  220.                 Vector3 normal = new Vector3(0, -1, 0);
  221.                 CalculateTextureCoordinates(
  222.                     this.BottomFaceGraphic,
  223.                     out float uvX, out float uvY,
  224.                     out float uvWidth, out float uvHeight);
  225.                 vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvWidth, uvHeight), normal);
  226.                 vertices[index++] = new Vertex(new Vector3(width, -height, depth), new Vector2(uvX, uvHeight), normal);
  227.                 vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(uvX, uvY), normal);
  228.                 vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvWidth, uvHeight), normal);
  229.                 vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(uvWidth, uvY), normal);
  230.                 vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(uvX, uvY), normal);
  231.             }
  232.  
  233.  
  234.             if (this._buffer.Buffer != null)
  235.             {
  236.                 this._buffer.Buffer.Dispose();
  237.             }
  238.             this._drawCount = vertices.Length;
  239.             Buffer vertexBuffer = Buffer.Create(Device, BindFlags.VertexBuffer, vertices);
  240.             const int vertexSizeInBytes = 32; // Precalculated
  241.             this._buffer = new VertexBufferBinding(vertexBuffer, vertexSizeInBytes, 0);
  242.         }
  243.  
  244.         public void Draw(DeviceContext context)
  245.         {
  246.             if(Faces == CubeFaceVisibility.None)
  247.             {
  248.                 return;
  249.             }
  250.             context.InputAssembler.SetVertexBuffers(0, this._buffer);
  251.             if (Tileset != null)
  252.             {
  253.                 context.PixelShader.SetShaderResource(0, Tileset.ResourceView);
  254.                 //context.PixelShader.SetSampler(0, DiffuseMaterial.SamplerState);
  255.             }
  256.             context.Draw(_drawCount, 0);
  257.         }
  258.  
  259.     }
  260. }
Add Comment
Please, Sign In to add comment