/// <summary> /// Initializes a new instance of the <see cref="Cube"/> class. /// </summary> /// <param name="graphics">The graphics object used to create the buffers needed by this object.</param> /// <param name="inputLayout">The input layout describing how a vertex is laid out.</param> public Cube(GorgonGraphics graphics, GorgonInputLayout inputLayout) { CubeVertex[] vertices = { new CubeVertex(new DX.Vector3(-0.5f, 0.5f, -0.5f), new DX.Vector3(0, 0, 0)), new CubeVertex(new DX.Vector3(0.5f, 0.5f, -0.5f), new DX.Vector3(1.0f, 1.0f, 0)), new CubeVertex(new DX.Vector3(0.5f, -0.5f, -0.5f), new DX.Vector3(0.0f, 1.0f, 0)), new CubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector3(1.0f, 0.0f, 0)), new CubeVertex(new DX.Vector3(-0.5f, 0.5f, 0.5f), new DX.Vector3(0, 0, 0)), new CubeVertex(new DX.Vector3(0.5f, 0.5f, 0.5f), new DX.Vector3(1.0f, 1.0f, 0)), new CubeVertex(new DX.Vector3(0.5f, -0.5f, 0.5f), new DX.Vector3(0.0f, 1.0f, 0)), new CubeVertex(new DX.Vector3(-0.5f, -0.5f, 0.5f), new DX.Vector3(1.0f, 0.0f, 0)), }; ushort[] indices = { // Front face. 0, 1, 2, 2, 3, 0, // Back face. 5, 4, 6, 4, 7, 6, // Left face. 4, 0, 3, 3, 7, 4, // Right face. 1, 5, 6, 6, 2, 1, // Top face 4, 5, 1, 1, 0, 4, // Bottom face 2, 6, 7, 7, 3, 2 }; // Create our index buffer and vertex buffer and populate with our cube data. using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(indices)) using (var vertexPtr = GorgonNativeBuffer <CubeVertex> .Pin(vertices)) { IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("Volume Index Buffer") { Usage = ResourceUsage.Immutable, IndexCount = indices.Length, Use16BitIndices = true }, indexPtr); VertexBuffer = new GorgonVertexBufferBindings(inputLayout) { [0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics, vertices.Length, ResourceUsage.Immutable, initialData: vertexPtr, bufferName: "Volume Vertex Buffer") }; } }
/// <summary> /// Initializes a new instance of the <see cref="Plane" /> class. /// </summary> /// <param name="graphics">The graphics interface used to create the buffers for this object.</param> /// <param name="inputLayout">The input layout for the vertices in this mesh.</param> /// <param name="size">The width and height of the plane.</param> /// <param name="textureCoordinates">Texture coordinates.</param> public Plane(GorgonGraphics graphics, GorgonInputLayout inputLayout, DX.Vector2 size, DX.RectangleF textureCoordinates) : base(inputLayout) { Size = size; // Create our vertices. Vertices = new[] { new BoingerVertex(new DX.Vector3(-size.X, size.Y, 0.0f), textureCoordinates.Location), new BoingerVertex(new DX.Vector3(size.X, size.Y, 0.0f), new DX.Vector2(textureCoordinates.Right, textureCoordinates.Top)), new BoingerVertex(new DX.Vector3(-size.X, -size.Y, 0.0f), new DX.Vector2(textureCoordinates.Left, textureCoordinates.Bottom)), new BoingerVertex(new DX.Vector3(size.X, -size.Y, 0.0f), new DX.Vector2(textureCoordinates.Right, textureCoordinates.Bottom)) }; // Create our indices. Indices = new ushort[] { 0, 1, 2, 2, 1, 3 }; // Copy the above vertex/index data into a vertex and index buffer so we can render our plane. using (var vertexPtr = GorgonNativeBuffer <BoingerVertex> .Pin(Vertices)) using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(Indices)) { VertexBufferBindings[0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics, new GorgonVertexBufferInfo("Plane Vertex Buffer") { SizeInBytes = Vertices.Length * BoingerVertex.Size, Usage = ResourceUsage.Immutable }, vertexPtr); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("Plane Index Buffer") { Usage = ResourceUsage.Immutable, IndexCount = Indices.Length, Use16BitIndices = true }, indexPtr); } }
/// <summary> /// Function to build the Icosphere. /// </summary> /// <param name="graphics">Graphics interface to use.</param> /// <param name="radius">Radius of the sphere.</param> /// <param name="tesselation">Tessellation factor for the sphere.</param> /// <param name="textureCoordinates">Texture coordinate offset and scale.</param> private void BuildSphere(GorgonGraphics graphics, float radius, int tesselation, DX.RectangleF textureCoordinates) { GetBaseVertices(); List <int[]> indices = GetBaseIndices(); for (int i = 0; i < tesselation; ++i) { var subIndices = new List <int[]>(); foreach (int[] index in indices) { int index0 = GetMiddlePoint(index[0], index[1]); int index1 = GetMiddlePoint(index[1], index[2]); int index2 = GetMiddlePoint(index[2], index[0]); subIndices.Add(new [] { index[0], index0, index2 }); subIndices.Add(new[] { index[1], index1, index0 }); subIndices.Add(new[] { index[2], index2, index1 }); subIndices.Add(new[] { index0, index1, index2 }); } indices = subIndices; _cachedSplits.Clear(); } // Perform texture coordinate calculations and vertex/normal transformations. const float piRecip = 1.0f / (float)System.Math.PI; const float pi2Recip = 1.0f / (2.0f * (float)System.Math.PI); // Final list. var vertexList = new List <Vertex3D>(); var indexList = new List <int>(); foreach (DX.Vector3 vector in _vertices) { DX.Vector3 position = vector; DX.Vector3 normal = position; DX.Vector2 uv = DX.Vector2.Zero; uv.X = ((0.5f - (position.X.ATan(position.Z) * pi2Recip)) * textureCoordinates.Width) + textureCoordinates.X; uv.Y = ((0.5f - (position.Y.ASin() * piRecip)) * textureCoordinates.Height) + textureCoordinates.Y; DX.Vector3.Multiply(ref position, radius, out position); DX.Vector3.TransformCoordinate(ref position, ref _orientation, out position); DX.Vector3.TransformCoordinate(ref normal, ref _orientation, out normal); normal.Normalize(); vertexList.Add(new Vertex3D { Position = new DX.Vector4(position, 1.0f), Normal = normal, UV = uv }); } foreach (int[] index in indices) { for (int j = 0; j < 3; ++j) { indexList.Add(index[j]); } } FixSeam(vertexList, indexList); using (var vertexData = GorgonNativeBuffer <Vertex3D> .Pin(vertexList.ToArray())) using (var indexData = GorgonNativeBuffer <int> .Pin(indexList.ToArray())) { VertexCount = vertexList.Count; IndexCount = indexList.Count; TriangleCount = IndexCount / 3; CalculateTangents(vertexData, indexData); VertexBuffer = new GorgonVertexBuffer(graphics, new GorgonVertexBufferInfo("IcoSphereVertexBuffer") { SizeInBytes = vertexData.SizeInBytes, Usage = ResourceUsage.Immutable }, vertexData.Cast <byte>()); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo { Usage = ResourceUsage.Immutable, Use16BitIndices = false, IndexCount = IndexCount }, indexData); } }
/// <summary> /// Initializes a new instance of the <see cref="Sphere" /> class. /// </summary> /// <param name="graphics">The graphics interface used to create the buffers for this object.</param> /// <param name="inputLayout">The input layout for the vertices in this mesh.</param> /// <param name="radius">Radius of the sphere</param> /// <param name="textureOffset">Offset of the texture.</param> /// <param name="textureScale">Scale of the texture.</param> /// <param name="ringCount">Number of rings in the sphere.</param> /// <param name="segmentCount">Number of segments in the sphere.</param> public Sphere(GorgonGraphics graphics, GorgonInputLayout inputLayout, float radius, DX.Vector2 textureOffset, DX.Size2F textureScale, int ringCount = 8, int segmentCount = 16) : base(inputLayout) { ushort index = 0; // Current index. int vertexIndex = 0; // Current vertex index. int indexIndex = 0; // Current index array index. float deltaRingAngle = ((float)System.Math.PI) / ringCount; float deltaSegAngle = (((float)System.Math.PI) * 2.0f) / segmentCount; // Calculate number of vertices and indices required for our sphere. int vertexCount = (ringCount + 1) * (segmentCount + 1); int indexCount = 6 * ringCount * (segmentCount + 1); Vertices = new BoingerVertex[vertexCount]; Indices = new ushort[indexCount]; Radius = radius; // Build our sphere. for (int ring = 0; ring <= ringCount; ring++) { float angle = deltaRingAngle * ring; float ringSin = angle.Sin(); var position = new DX.Vector3(0, angle.Cos() * radius, 0); for (int segment = 0; segment <= segmentCount; segment++) { var textureDelta = new DX.Vector2(1.0f - (segment / (float)segmentCount), 1.0f - (ring / (float)ringCount)); float segmentAngle = deltaSegAngle * segment; position.X = ringSin * segmentAngle.Sin() * radius; position.Z = ringSin * segmentAngle.Cos() * radius; // Create the vertex. textureDelta.X *= textureScale.Width; textureDelta.Y *= textureScale.Height; textureDelta.X += textureOffset.X; textureDelta.Y += textureOffset.Y; Vertices[vertexIndex++] = new BoingerVertex( position, textureDelta ); // Add the indices and skip the last ring. if (ring == ringCount) { continue; } Indices[indexIndex++] = (ushort)(index + segmentCount + 1); Indices[indexIndex++] = index; Indices[indexIndex++] = (ushort)(index + segmentCount); Indices[indexIndex++] = (ushort)(index + segmentCount + 1); Indices[indexIndex++] = (ushort)(index + 1); Indices[indexIndex++] = index; index++; } } // Copy the above vertex/index data into a vertex and index buffer so we can render our sphere. using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(Indices)) using (var vertexPtr = GorgonNativeBuffer <BoingerVertex> .Pin(Vertices)) { VertexBufferBindings[0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics, new GorgonVertexBufferInfo("Sphere Vertex Buffer") { SizeInBytes = Vertices.Length * BoingerVertex.Size, Usage = ResourceUsage.Immutable }, vertexPtr); IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("Sphere Index Buffer") { Usage = ResourceUsage.Immutable, IndexCount = Indices.Length }, indexPtr); } }
/// <summary> /// Initializes a new instance of the <see cref="Cube"/> class. /// </summary> /// <param name="graphics">The graphics object used to create the buffers needed by this object.</param> /// <param name="inputLayout">The input layout describing how a vertex is laid out.</param> public Cube(GorgonGraphics graphics, GorgonInputLayout inputLayout) { GlassCubeVertex[] vertices = { // Front face. new GlassCubeVertex(new DX.Vector3(-0.5f, 0.5f, -0.5f), new DX.Vector2(0, 0)), new GlassCubeVertex(new DX.Vector3(0.5f, -0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(0.5f, 0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f)), // Right face. new GlassCubeVertex(new DX.Vector3(0.5f, 0.5f, -0.5f), new DX.Vector2(0, 0)), new GlassCubeVertex(new DX.Vector3(0.5f, -0.5f, 0.5f), new DX.Vector2(1.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(0.5f, -0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(0.5f, 0.5f, 0.5f), new DX.Vector2(1.0f, 0.0f)), // Back face. new GlassCubeVertex(new DX.Vector3(0.5f, 0.5f, 0.5f), new DX.Vector2(0, 0)), new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, 0.5f), new DX.Vector2(1.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(0.5f, -0.5f, 0.5f), new DX.Vector2(0.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(-0.5f, 0.5f, 0.5f), new DX.Vector2(1.0f, 0.0f)), // Left face. new GlassCubeVertex(new DX.Vector3(-0.5f, 0.5f, 0.5f), new DX.Vector2(0, 0)), new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, 0.5f), new DX.Vector2(0.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(-0.5f, 0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f)), // Top face. new GlassCubeVertex(new DX.Vector3(-0.5f, 0.5f, 0.5f), new DX.Vector2(0, 0)), new GlassCubeVertex(new DX.Vector3(0.5f, 0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(-0.5f, 0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(0.5f, 0.5f, 0.5f), new DX.Vector2(1.0f, 0.0f)), // Bottom face. new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(0, 0)), new GlassCubeVertex(new DX.Vector3(0.5f, -0.5f, 0.5f), new DX.Vector2(1.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, 0.5f), new DX.Vector2(0.0f, 1.0f)), new GlassCubeVertex(new DX.Vector3(0.5f, -0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f)) }; ushort[] indices = { 8, 9, 10, 8, 11, 9, 12, 13, 14, 12, 15, 13, 4, 5, 6, 4, 7, 5, 16, 17, 18, 16, 19, 17, 20, 21, 22, 20, 23, 21, 0, 1, 2, 0, 3, 1 }; // Create our index buffer and vertex buffer and populate with our cube data. using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(indices)) using (var vertexPtr = GorgonNativeBuffer <GlassCubeVertex> .Pin(vertices)) { IndexBuffer = new GorgonIndexBuffer(graphics, new GorgonIndexBufferInfo("GlassCube Index Buffer") { Usage = ResourceUsage.Immutable, IndexCount = indices.Length, Use16BitIndices = true }, indexPtr); VertexBuffer = new GorgonVertexBufferBindings(inputLayout) { [0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics, vertices.Length, ResourceUsage.Immutable, initialData: vertexPtr, bufferName: "GlassCube Vertex Buffer") }; } }