private void Update(Context context) { if (_dirtyLength) { VertexAttributeDoubleVector3 positionAttribute = new VertexAttributeDoubleVector3("position", 6); positionAttribute.Values.Add(new Vector3D(0, 0, 0)); positionAttribute.Values.Add(new Vector3D(_length, 0, 0)); positionAttribute.Values.Add(new Vector3D(0, 0, 0)); positionAttribute.Values.Add(new Vector3D(0, _length, 0)); positionAttribute.Values.Add(new Vector3D(0, 0, 0)); positionAttribute.Values.Add(new Vector3D(0, 0, _length)); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color", 6); colorAttribute.AddColor(Color.Red); colorAttribute.AddColor(Color.Red); colorAttribute.AddColor(Color.Green); colorAttribute.AddColor(Color.Green); colorAttribute.AddColor(Color.Blue); colorAttribute.AddColor(Color.Blue); Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Lines; mesh.Attributes.Add(positionAttribute); mesh.Attributes.Add(colorAttribute); _polyline.Set(context, mesh); _dirtyLength = false; } _polyline.Width = Width; }
public static Mesh Compute(Vector3D length) { if (length.X < 0 || length.Y < 0 || length.Z < 0) { throw new ArgumentOutOfRangeException("length"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", 8); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedShort indices = new IndicesUnsignedShort(24); mesh.Indices = indices; // // 8 corner points // IList<Vector3D> positions = positionsAttribute.Values; Vector3D corner = 0.5 * length; positions.Add(new Vector3D(-corner.X, -corner.Y, -corner.Z)); positions.Add(new Vector3D(corner.X, -corner.Y, -corner.Z)); positions.Add(new Vector3D(corner.X, corner.Y, -corner.Z)); positions.Add(new Vector3D(-corner.X, corner.Y, -corner.Z)); positions.Add(new Vector3D(-corner.X, -corner.Y, corner.Z)); positions.Add(new Vector3D(corner.X, -corner.Y, corner.Z)); positions.Add(new Vector3D(corner.X, corner.Y, corner.Z)); positions.Add(new Vector3D(-corner.X, corner.Y, corner.Z)); // // 6 faces, 2 triangles each // indices.AddTriangle(new TriangleIndicesUnsignedShort(4, 5, 6)); // Top: plane z = corner.Z indices.AddTriangle(new TriangleIndicesUnsignedShort(4, 6, 7)); indices.AddTriangle(new TriangleIndicesUnsignedShort(1, 0, 3)); // Bottom: plane z = -corner.Z indices.AddTriangle(new TriangleIndicesUnsignedShort(1, 3, 2)); indices.AddTriangle(new TriangleIndicesUnsignedShort(1, 6, 5)); // Side: plane x = corner.X indices.AddTriangle(new TriangleIndicesUnsignedShort(1, 2, 6)); indices.AddTriangle(new TriangleIndicesUnsignedShort(2, 3, 7)); // Side: plane y = corner.Y indices.AddTriangle(new TriangleIndicesUnsignedShort(2, 7, 6)); indices.AddTriangle(new TriangleIndicesUnsignedShort(3, 0, 4)); // Side: plane x = -corner.X indices.AddTriangle(new TriangleIndicesUnsignedShort(3, 4, 7)); indices.AddTriangle(new TriangleIndicesUnsignedShort(0, 1, 5)); // Side: plane y = -corner.Y indices.AddTriangle(new TriangleIndicesUnsignedShort(0, 5, 4)); return mesh; }
public static Mesh Compute(int numberOfSubdivisions) { if (numberOfSubdivisions < 0) { throw new ArgumentOutOfRangeException("numberOfSubdivisions"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3( "position", SubdivisionUtility.NumberOfVertices(numberOfSubdivisions)); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * SubdivisionUtility.NumberOfTriangles(numberOfSubdivisions)); mesh.Indices = indices; // // Initial tetrahedron // double negativeRootTwoOverThree = -Math.Sqrt(2.0) / 3.0; const double negativeOneThird = -1.0 / 3.0; double rootSixOverThree = Math.Sqrt(6.0) / 3.0; IList<Vector3D> positions = positionsAttribute.Values; positions.Add(new Vector3D(0, 0, 1)); positions.Add(new Vector3D(0, (2.0 * Math.Sqrt(2.0)) / 3.0, negativeOneThird)); positions.Add(new Vector3D(-rootSixOverThree, negativeRootTwoOverThree, negativeOneThird)); positions.Add(new Vector3D(rootSixOverThree, negativeRootTwoOverThree, negativeOneThird)); Subdivide(positions, indices, new TriangleIndicesUnsignedInt(0, 1, 2), numberOfSubdivisions); Subdivide(positions, indices, new TriangleIndicesUnsignedInt(0, 2, 3), numberOfSubdivisions); Subdivide(positions, indices, new TriangleIndicesUnsignedInt(0, 3, 1), numberOfSubdivisions); Subdivide(positions, indices, new TriangleIndicesUnsignedInt(1, 3, 2), numberOfSubdivisions); return mesh; }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfSlicePartitions, int numberOfStackPartitions, GeographicGridEllipsoidVertexAttributes vertexAttributes) { if (numberOfSlicePartitions < 3) { throw new ArgumentOutOfRangeException("numberOfSlicePartitions"); } if (numberOfStackPartitions < 2) { throw new ArgumentOutOfRangeException("numberOfStackPartitions"); } if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.Position) != GeographicGridEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = NumberOfVertices(numberOfSlicePartitions, numberOfStackPartitions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * NumberOfTriangles(numberOfSlicePartitions, numberOfStackPartitions)); mesh.Indices = indices; IList<Vector3H> normals = null; if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.Normal) == GeographicGridEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); normals = normalsAttribute.Values; } IList<Vector2H> textureCoordinates = null; if ((vertexAttributes & GeographicGridEllipsoidVertexAttributes.TextureCoordinate) == GeographicGridEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); textureCoordinates = textureCoordinateAttribute.Values; } // // Create lookup table // double[] cosTheta = new double[numberOfSlicePartitions]; double[] sinTheta = new double[numberOfSlicePartitions]; for (int j = 0; j < numberOfSlicePartitions; ++j) { double theta = Trig.TwoPi * (((double)j) / numberOfSlicePartitions); cosTheta[j] = Math.Cos(theta); sinTheta[j] = Math.Sin(theta); } // // Create positions // IList<Vector3D> positions = positionsAttribute.Values; positions.Add(new Vector3D(0, 0, ellipsoid.Radii.Z)); for (int i = 1; i < numberOfStackPartitions; ++i) { double phi = Math.PI * (((double)i) / numberOfStackPartitions); double sinPhi = Math.Sin(phi); double xSinPhi = ellipsoid.Radii.X * sinPhi; double ySinPhi = ellipsoid.Radii.Y * sinPhi; double zCosPhi = ellipsoid.Radii.Z * Math.Cos(phi); for (int j = 0; j < numberOfSlicePartitions; ++j) { positions.Add(new Vector3D(cosTheta[j] * xSinPhi, sinTheta[j] * ySinPhi, zCosPhi)); } } positions.Add(new Vector3D(0, 0, -ellipsoid.Radii.Z)); if ((normals != null) || (textureCoordinates != null)) { for (int i = 0; i < positions.Count; ++i) { Vector3D deticSurfaceNormal = ellipsoid.GeodeticSurfaceNormal(positions[i]); if (normals != null) { normals.Add(deticSurfaceNormal.ToVector3H()); } if (textureCoordinates != null) { textureCoordinates.Add(SubdivisionUtility.ComputeTextureCoordinate(deticSurfaceNormal)); } } } // // Triangle fan top row // for (int j = 1; j < numberOfSlicePartitions; ++j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(0, j, j + 1)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(0, numberOfSlicePartitions, 1)); // // Middle rows are triangle strips // for (int i = 0; i < numberOfStackPartitions - 2; ++i) { int topRowOffset = (i * numberOfSlicePartitions) + 1; int bottomRowOffset = ((i + 1) * numberOfSlicePartitions) + 1; for (int j = 0; j < numberOfSlicePartitions - 1; ++j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + j, bottomRowOffset + j + 1, topRowOffset + j + 1)); indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + j, topRowOffset + j + 1, topRowOffset + j)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + numberOfSlicePartitions - 1, bottomRowOffset, topRowOffset)); indices.AddTriangle(new TriangleIndicesUnsignedInt(bottomRowOffset + numberOfSlicePartitions - 1, topRowOffset, topRowOffset + numberOfSlicePartitions - 1)); } // // Triangle fan bottom row // int lastPosition = positions.Count - 1; for (int j = lastPosition - 1; j > lastPosition - numberOfSlicePartitions; --j) { indices.AddTriangle(new TriangleIndicesUnsignedInt(lastPosition, j, j - 1)); } indices.AddTriangle(new TriangleIndicesUnsignedInt(lastPosition, lastPosition - numberOfSlicePartitions, lastPosition - 1)); return mesh; }
public PolygonShapefile( Shapefile shapefile, Context context, Ellipsoid globeShape, ShapefileAppearance appearance) { Verify.ThrowIfNull(shapefile); Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); _polyline = new OutlinedPolylineTexture(); _polygons = new List <Polygon>(); VertexAttributeDoubleVector3 positionAttribute = new VertexAttributeDoubleVector3("position"); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color"); VertexAttributeRGBA outlineColorAttribute = new VertexAttributeRGBA("outlineColor"); IndicesUnsignedInt indices = new IndicesUnsignedInt(); Random r = new Random(3); IList <Vector3D> positions = new List <Vector3D>(); foreach (Shape shape in shapefile) { if (shape.ShapeType != ShapeType.Polygon) { throw new NotSupportedException("The type of an individual shape does not match the Shapefile type."); } PolygonShape polygonShape = (PolygonShape)shape; for (int j = 0; j < polygonShape.Count; ++j) { Color color = Color.FromArgb(127, r.Next(256), r.Next(256), r.Next(256)); positions.Clear(); ShapePart part = polygonShape[j]; for (int i = 0; i < part.Count; ++i) { Vector2D point = part[i]; positions.Add(globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y)))); // // For polyline // positionAttribute.Values.Add(globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y)))); colorAttribute.AddColor(color); outlineColorAttribute.AddColor(Color.Black); if (i != 0) { indices.Values.Add((uint)positionAttribute.Values.Count - 2); indices.Values.Add((uint)positionAttribute.Values.Count - 1); } } try { Polygon p = new Polygon(context, globeShape, positions); p.Color = color; _polygons.Add(p); } catch (ArgumentOutOfRangeException) // Not enough positions after cleaning { } } } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Lines; mesh.Attributes.Add(positionAttribute); mesh.Attributes.Add(colorAttribute); mesh.Attributes.Add(outlineColorAttribute); mesh.Indices = indices; _polyline.Set(context, mesh); }
public void VertexAttributeDoubleVector3() { Mesh mesh = new Mesh(); VertexAttributeDoubleVector3 attribute = new VertexAttributeDoubleVector3("position"); mesh.Attributes.Add(attribute); Assert.AreEqual("position", mesh.Attributes["position"].Name); Assert.AreEqual(VertexAttributeType.EmulatedDoubleVector3, mesh.Attributes["position"].Datatype); }
public Polygon(Context context, Ellipsoid globeShape, IEnumerable <Vector3D> positions) { Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); // // Pipeline Stage 1a: Clean up - Remove duplicate positions // List <Vector3D> cleanPositions = (List <Vector3D>)SimplePolygonAlgorithms.Cleanup(positions); // // Pipeline Stage 1b: Clean up - Swap winding order // EllipsoidTangentPlane plane = new EllipsoidTangentPlane(globeShape, cleanPositions); ICollection <Vector2D> positionsOnPlane = plane.ComputePositionsOnPlane(cleanPositions); if (SimplePolygonAlgorithms.ComputeWindingOrder(positionsOnPlane) == PolygonWindingOrder.Clockwise) { cleanPositions.Reverse(); //((List<Vector2D>)positionsOnPlane).Reverse(); } // // Pipeline Stage 2: Triangulate // IndicesUnsignedInt indices = EarClippingOnEllipsoid.Triangulate(cleanPositions); //IndicesInt32 indices = EarClipping.Triangulate(positionsOnPlane); // // Pipeline Stage 3: Subdivide // TriangleMeshSubdivisionResult result = TriangleMeshSubdivision.Compute(cleanPositions, indices, Trig.ToRadians(1)); // // Pipeline Stage 4: Set height // VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3( "position", (result.Indices.Values.Count / 3) + 2); foreach (Vector3D position in result.Positions) { positionsAttribute.Values.Add(globeShape.ScaleToGeocentricSurface(position)); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; mesh.Attributes.Add(positionsAttribute); mesh.Indices = result.Indices; ShaderProgram sp = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polygon.Shaders.PolygonVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polygon.Shaders.PolygonFS.glsl")); ((Uniform <Vector3F>)sp.Uniforms["u_globeOneOverRadiiSquared"]).Value = globeShape.OneOverRadiiSquared.ToVector3F(); _colorUniform = (Uniform <Vector4F>)sp.Uniforms["u_color"]; _drawState = new DrawState(); _drawState.RenderState.Blending.Enabled = true; _drawState.RenderState.Blending.SourceRGBFactor = SourceBlendingFactor.SourceAlpha; _drawState.RenderState.Blending.SourceAlphaFactor = SourceBlendingFactor.SourceAlpha; _drawState.RenderState.Blending.DestinationRGBFactor = DestinationBlendingFactor.OneMinusSourceAlpha; _drawState.RenderState.Blending.DestinationAlphaFactor = DestinationBlendingFactor.OneMinusSourceAlpha; _drawState.ShaderProgram = sp; _meshBuffers = Device.CreateMeshBuffers(mesh, _drawState.ShaderProgram.VertexAttributes, BufferHint.StaticDraw); _primitiveType = mesh.PrimitiveType; Color = Color.White; }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfSubdivisions, SubdivisionEllipsoidVertexAttributes vertexAttributes) { if (numberOfSubdivisions < 0) { throw new ArgumentOutOfRangeException("numberOfSubdivisions"); } if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.Position) != SubdivisionEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = SubdivisionUtility.NumberOfVertices(numberOfSubdivisions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * SubdivisionUtility.NumberOfTriangles(numberOfSubdivisions)); mesh.Indices = indices; SubdivisionMesh subdivisionMesh = new SubdivisionMesh(); subdivisionMesh.Ellipsoid = ellipsoid; subdivisionMesh.Positions = positionsAttribute.Values; subdivisionMesh.Indices = indices; if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.Normal) == SubdivisionEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); subdivisionMesh.Normals = normalsAttribute.Values; } if ((vertexAttributes & SubdivisionEllipsoidVertexAttributes.TextureCoordinate) == SubdivisionEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); subdivisionMesh.TextureCoordinate = textureCoordinateAttribute.Values; } // // Initial tetrahedron // double negativeRootTwoOverThree = -Math.Sqrt(2.0) / 3.0; const double negativeOneThird = -1.0 / 3.0; double rootSixOverThree = Math.Sqrt(6.0) / 3.0; Vector3D n0 = new Vector3D(0, 0, 1); Vector3D n1 = new Vector3D(0, (2.0 * Math.Sqrt(2.0)) / 3.0, negativeOneThird); Vector3D n2 = new Vector3D(-rootSixOverThree, negativeRootTwoOverThree, negativeOneThird); Vector3D n3 = new Vector3D(rootSixOverThree, negativeRootTwoOverThree, negativeOneThird); Vector3D p0 = n0.MultiplyComponents(ellipsoid.Radii); Vector3D p1 = n1.MultiplyComponents(ellipsoid.Radii); Vector3D p2 = n2.MultiplyComponents(ellipsoid.Radii); Vector3D p3 = n3.MultiplyComponents(ellipsoid.Radii); subdivisionMesh.Positions.Add(p0); subdivisionMesh.Positions.Add(p1); subdivisionMesh.Positions.Add(p2); subdivisionMesh.Positions.Add(p3); if ((subdivisionMesh.Normals != null) || (subdivisionMesh.TextureCoordinate != null)) { Vector3D d0 = ellipsoid.GeodeticSurfaceNormal(p0); Vector3D d1 = ellipsoid.GeodeticSurfaceNormal(p1); Vector3D d2 = ellipsoid.GeodeticSurfaceNormal(p2); Vector3D d3 = ellipsoid.GeodeticSurfaceNormal(p3); if (subdivisionMesh.Normals != null) { subdivisionMesh.Normals.Add(d0.ToVector3H()); subdivisionMesh.Normals.Add(d1.ToVector3H()); subdivisionMesh.Normals.Add(d2.ToVector3H()); subdivisionMesh.Normals.Add(d3.ToVector3H()); } if (subdivisionMesh.TextureCoordinate != null) { subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d0)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d1)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d2)); subdivisionMesh.TextureCoordinate.Add(SubdivisionUtility.ComputeTextureCoordinate(d3)); } } Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 1, 2), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 2, 3), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(0, 3, 1), numberOfSubdivisions); Subdivide(subdivisionMesh, new TriangleIndicesUnsignedInt(1, 3, 2), numberOfSubdivisions); return mesh; }
public static MeshBuffers CreateMeshBuffers(Mesh mesh, ShaderVertexAttributeCollection shaderAttributes, BufferHint usageHint) { if (mesh == null) { throw new ArgumentNullException("mesh"); } if (shaderAttributes == null) { throw new ArgumentNullException("shaderAttributes"); } MeshBuffers meshBuffers = new MeshBuffers(); if (mesh.Indices != null) { if (mesh.Indices.Datatype == IndicesType.UnsignedShort) { IList <ushort> meshIndices = ((IndicesUnsignedShort)mesh.Indices).Values; ushort[] indices = new ushort[meshIndices.Count]; for (int j = 0; j < meshIndices.Count; ++j) { indices[j] = meshIndices[j]; } IndexBuffer indexBuffer = Device.CreateIndexBuffer(usageHint, indices.Length * sizeof(ushort)); indexBuffer.CopyFromSystemMemory(indices); meshBuffers.IndexBuffer = indexBuffer; } else if (mesh.Indices.Datatype == IndicesType.UnsignedInt) { IList <uint> meshIndices = ((IndicesUnsignedInt)mesh.Indices).Values; uint[] indices = new uint[meshIndices.Count]; for (int j = 0; j < meshIndices.Count; ++j) { indices[j] = meshIndices[j]; } IndexBuffer indexBuffer = Device.CreateIndexBuffer(usageHint, indices.Length * sizeof(uint)); indexBuffer.CopyFromSystemMemory(indices); meshBuffers.IndexBuffer = indexBuffer; } else { throw new NotSupportedException("mesh.Indices.Datatype " + mesh.Indices.Datatype.ToString() + " is not supported."); } } // // Emulated double precision vectors are a special case: one mesh vertex attribute // yields two shader vertex attributes. As such, these are handled separately before // normal attributes. // HashSet <string> ignoreAttributes = new HashSet <string>(); foreach (VertexAttribute attribute in mesh.Attributes) { if (attribute is VertexAttributeDoubleVector3) { VertexAttributeDoubleVector3 emulated = (VertexAttributeDoubleVector3)attribute; int highLocation = -1; int lowLocation = -1; foreach (ShaderVertexAttribute shaderAttribute in shaderAttributes) { if (shaderAttribute.Name == emulated.Name + "High") { highLocation = shaderAttribute.Location; } else if (shaderAttribute.Name == emulated.Name + "Low") { lowLocation = shaderAttribute.Location; } if ((highLocation != -1) && (lowLocation != -1)) { break; } } if ((highLocation == -1) && (lowLocation == -1)) { // // The shader did not have either attribute. No problem. // continue; } else if ((highLocation == -1) || (lowLocation == -1)) { throw new ArgumentException("An emulated double vec3 mesh attribute requires both " + emulated.Name + "High and " + emulated.Name + "Low vertex attributes, but the shader only contains one matching attribute."); } // // Copy both high and low parts into a single vertex buffer. // IList <Vector3D> values = ((VertexAttribute <Vector3D>)attribute).Values; Vector3F[] vertices = new Vector3F[2 * values.Count]; int j = 0; for (int i = 0; i < values.Count; ++i) { EmulatedVector3D v = new EmulatedVector3D(values[i]); vertices[j++] = v.High; vertices[j++] = v.Low; } VertexBuffer vertexBuffer = Device.CreateVertexBuffer(usageHint, ArraySizeInBytes.Size(vertices)); vertexBuffer.CopyFromSystemMemory(vertices); int stride = 2 * SizeInBytes <Vector3F> .Value; meshBuffers.Attributes[highLocation] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 3, false, 0, stride); meshBuffers.Attributes[lowLocation] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 3, false, SizeInBytes <Vector3F> .Value, stride); ignoreAttributes.Add(emulated.Name + "High"); ignoreAttributes.Add(emulated.Name + "Low"); } } // TODO: Not tested exhaustively foreach (ShaderVertexAttribute shaderAttribute in shaderAttributes) { if (ignoreAttributes.Contains(shaderAttribute.Name)) { continue; } if (!mesh.Attributes.Contains(shaderAttribute.Name)) { throw new ArgumentException("Shader requires vertex attribute \"" + shaderAttribute.Name + "\", which is not present in mesh."); } VertexAttribute attribute = mesh.Attributes[shaderAttribute.Name]; if (attribute.Datatype == VertexAttributeType.EmulatedDoubleVector3) { IList <Vector3D> values = ((VertexAttribute <Vector3D>)attribute).Values; Vector3F[] valuesArray = new Vector3F[values.Count]; for (int i = 0; i < values.Count; ++i) { valuesArray[i] = values[i].ToVector3F(); } VertexBuffer vertexBuffer = Device.CreateVertexBuffer(usageHint, ArraySizeInBytes.Size(valuesArray)); vertexBuffer.CopyFromSystemMemory(valuesArray); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 3); } else if (attribute.Datatype == VertexAttributeType.HalfFloat) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Half>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.HalfFloat, 1); } else if (attribute.Datatype == VertexAttributeType.HalfFloatVector2) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector2H>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.HalfFloat, 2); } else if (attribute.Datatype == VertexAttributeType.HalfFloatVector3) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector3H>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.HalfFloat, 3); } else if (attribute.Datatype == VertexAttributeType.HalfFloatVector4) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector4H>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.HalfFloat, 4); } else if (attribute.Datatype == VertexAttributeType.Float) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <float>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 1); } else if (attribute.Datatype == VertexAttributeType.FloatVector2) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector2F>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 2); } else if (attribute.Datatype == VertexAttributeType.FloatVector3) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector3F>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 3); } else if (attribute.Datatype == VertexAttributeType.FloatVector4) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <Vector4F>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.Float, 4); } else if (attribute.Datatype == VertexAttributeType.UnsignedByte) { if (attribute is VertexAttributeRGBA) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <byte>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.UnsignedByte, 4, true, 0, 0); } else if (attribute is VertexAttributeRGB) { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <byte>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.UnsignedByte, 3, true, 0, 0); } else { VertexBuffer vertexBuffer = CreateVertexBuffer(((VertexAttribute <byte>)attribute).Values, usageHint); meshBuffers.Attributes[shaderAttribute.Location] = new VertexBufferAttribute(vertexBuffer, ComponentDatatype.UnsignedByte, 1); } } else { Debug.Fail("attribute.Datatype"); } } return(meshBuffers); }
public TriangleMeshTerrainTile(Context context, TerrainTile tile) { ShaderProgram silhouetteSP = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.SilhouetteVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.SilhouetteGS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.SilhouetteFS.glsl")); Uniform <float> fillDistance = (Uniform <float>)silhouetteSP.Uniforms["u_fillDistance"]; fillDistance.Value = 1.5f; _silhouetteHeightExaggeration = (Uniform <float>)silhouetteSP.Uniforms["u_heightExaggeration"]; ShaderProgram sp = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.TerrainVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.TerrainFS.glsl")); _tileMinimumHeight = tile.MinimumHeight; _tileMaximumHeight = tile.MaximumHeight; _heightExaggeration = (Uniform <float>)sp.Uniforms["u_heightExaggeration"]; _minimumHeight = (Uniform <float>)sp.Uniforms["u_minimumHeight"]; _maximumHeight = (Uniform <float>)sp.Uniforms["u_maximumHeight"]; HeightExaggeration = 1; /////////////////////////////////////////////////////////////////// Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfPositions = tile.Resolution.X * tile.Resolution.Y; VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfPositions); IList <Vector3D> positions = positionsAttribute.Values; mesh.Attributes.Add(positionsAttribute); int numberOfPartitionsX = tile.Resolution.X - 1; int numberOfPartitionsY = tile.Resolution.Y - 1; int numberOfIndices = (numberOfPartitionsX * numberOfPartitionsY) * 6; IndicesUnsignedInt indices = new IndicesUnsignedInt(numberOfIndices); mesh.Indices = indices; // // Positions // Vector2D lowerLeft = tile.Extent.LowerLeft; Vector2D toUpperRight = tile.Extent.UpperRight - lowerLeft; int heightIndex = 0; for (int y = 0; y <= numberOfPartitionsY; ++y) { double deltaY = y / (double)numberOfPartitionsY; double currentY = lowerLeft.Y + (deltaY * toUpperRight.Y); for (int x = 0; x <= numberOfPartitionsX; ++x) { double deltaX = x / (double)numberOfPartitionsX; double currentX = lowerLeft.X + (deltaX * toUpperRight.X); positions.Add(new Vector3D(currentX, currentY, tile.Heights[heightIndex++])); } } // // Indices // int rowDelta = numberOfPartitionsX + 1; int i = 0; for (int y = 0; y < numberOfPartitionsY; ++y) { for (int x = 0; x < numberOfPartitionsX; ++x) { indices.AddTriangle(new TriangleIndicesUnsignedInt(i, i + 1, rowDelta + (i + 1))); indices.AddTriangle(new TriangleIndicesUnsignedInt(i, rowDelta + (i + 1), rowDelta + i)); i += 1; } i += 1; } _drawState = new DrawState(); _drawState.RenderState.FacetCulling.FrontFaceWindingOrder = mesh.FrontFaceWindingOrder; _drawState.ShaderProgram = sp; _drawState.VertexArray = context.CreateVertexArray(mesh, sp.VertexAttributes, BufferHint.StaticDraw); _silhouetteDrawState = new DrawState(); _silhouetteDrawState.RenderState.FacetCulling.Enabled = false; _silhouetteDrawState.RenderState.DepthMask = false; _silhouetteDrawState.VertexArray = _drawState.VertexArray; _silhouetteDrawState.ShaderProgram = silhouetteSP; _primitiveType = mesh.PrimitiveType; _clearColor = new ClearState(); _clearColor.Buffers = ClearBuffers.ColorBuffer; // // Only depth needs to be cleared but include stencil for speed. // _clearDepthStencil = new ClearState(); _clearDepthStencil.Buffers = ClearBuffers.DepthBuffer | ClearBuffers.StencilBuffer; }
public PolylineShapefile( Shapefile shapefile, Context context, Ellipsoid globeShape, ShapefileAppearance appearance) { Verify.ThrowIfNull(shapefile); Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); Verify.ThrowIfNull(appearance); _polyline = new OutlinedPolylineTexture(); int positionsCount = 0; int indicesCount = 0; PolylineCapacities(shapefile, out positionsCount, out indicesCount); VertexAttributeDoubleVector3 positionAttribute = new VertexAttributeDoubleVector3("position", positionsCount); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color", positionsCount); VertexAttributeRGBA outlineColorAttribute = new VertexAttributeRGBA("outlineColor", positionsCount); IndicesUnsignedInt indices = new IndicesUnsignedInt(indicesCount); foreach (Shape shape in shapefile) { if (shape.ShapeType != ShapeType.Polyline) { throw new NotSupportedException("The type of an individual shape does not match the Shapefile type."); } PolylineShape polylineShape = (PolylineShape)shape; for (int j = 0; j < polylineShape.Count; ++j) { ShapePart part = polylineShape[j]; for (int i = 0; i < part.Count; ++i) { Vector2D point = part[i]; positionAttribute.Values.Add(globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y)))); colorAttribute.AddColor(appearance.PolylineColor); outlineColorAttribute.AddColor(appearance.PolylineOutlineColor); if (i != 0) { indices.Values.Add((uint)positionAttribute.Values.Count - 2); indices.Values.Add((uint)positionAttribute.Values.Count - 1); } } } } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Lines; mesh.Attributes.Add(positionAttribute); mesh.Attributes.Add(colorAttribute); mesh.Attributes.Add(outlineColorAttribute); mesh.Indices = indices; _polyline.Set(context, mesh); _polyline.Width = appearance.PolylineWidth; _polyline.OutlineWidth = appearance.PolylineOutlineWidth; }
public PolygonShapefile( Shapefile shapefile, Context context, Ellipsoid globeShape, ShapefileAppearance appearance) { Verify.ThrowIfNull(shapefile); Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); _polyline = new OutlinedPolylineTexture(); _polygons = new List<Polygon>(); VertexAttributeDoubleVector3 positionAttribute = new VertexAttributeDoubleVector3("position"); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color"); VertexAttributeRGBA outlineColorAttribute = new VertexAttributeRGBA("outlineColor"); IndicesUnsignedInt indices = new IndicesUnsignedInt(); Random r = new Random(3); IList<Vector3D> positions = new List<Vector3D>(); foreach (Shape shape in shapefile) { if (shape.ShapeType != ShapeType.Polygon) { throw new NotSupportedException("The type of an individual shape does not match the Shapefile type."); } PolygonShape polygonShape = (PolygonShape)shape; for (int j = 0; j < polygonShape.Count; ++j) { Color color = Color.FromArgb(127, r.Next(256), r.Next(256), r.Next(256)); positions.Clear(); ShapePart part = polygonShape[j]; for (int i = 0; i < part.Count; ++i) { Vector2D point = part[i]; positions.Add(globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y)))); // // For polyline // positionAttribute.Values.Add(globeShape.ToVector3D(Trig.ToRadians(new Geodetic3D(point.X, point.Y)))); colorAttribute.AddColor(color); outlineColorAttribute.AddColor(Color.Black); if (i != 0) { indices.Values.Add((uint)positionAttribute.Values.Count - 2); indices.Values.Add((uint)positionAttribute.Values.Count - 1); } } try { Polygon p = new Polygon(context, globeShape, positions); p.Color = color; _polygons.Add(p); } catch (ArgumentOutOfRangeException) // Not enough positions after cleaning { } } } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Lines; mesh.Attributes.Add(positionAttribute); mesh.Attributes.Add(colorAttribute); mesh.Attributes.Add(outlineColorAttribute); mesh.Indices = indices; _polyline.Set(context, mesh); }
public TriangleMeshTerrainTile(Context context, TerrainTile tile) { ShaderProgram silhouetteSP = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.SilhouetteVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.SilhouetteGS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.SilhouetteFS.glsl")); Uniform<float> fillDistance = (Uniform<float>)silhouetteSP.Uniforms["u_fillDistance"]; fillDistance.Value = 1.5f; _silhouetteHeightExaggeration = (Uniform<float>)silhouetteSP.Uniforms["u_heightExaggeration"]; ShaderProgram sp = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.TerrainVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Terrain.TriangleMeshTerrainTile.TerrainFS.glsl")); _tileMinimumHeight = tile.MinimumHeight; _tileMaximumHeight = tile.MaximumHeight; _heightExaggeration = (Uniform<float>)sp.Uniforms["u_heightExaggeration"]; _minimumHeight = (Uniform<float>)sp.Uniforms["u_minimumHeight"]; _maximumHeight = (Uniform<float>)sp.Uniforms["u_maximumHeight"]; HeightExaggeration = 1; /////////////////////////////////////////////////////////////////// Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfPositions = tile.Resolution.X * tile.Resolution.Y; VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfPositions); IList<Vector3D> positions = positionsAttribute.Values; mesh.Attributes.Add(positionsAttribute); int numberOfPartitionsX = tile.Resolution.X - 1; int numberOfPartitionsY = tile.Resolution.Y - 1; int numberOfIndices = (numberOfPartitionsX * numberOfPartitionsY) * 6; IndicesUnsignedInt indices = new IndicesUnsignedInt(numberOfIndices); mesh.Indices = indices; // // Positions // Vector2D lowerLeft = tile.Extent.LowerLeft; Vector2D toUpperRight = tile.Extent.UpperRight - lowerLeft; int heightIndex = 0; for (int y = 0; y <= numberOfPartitionsY; ++y) { double deltaY = y / (double)numberOfPartitionsY; double currentY = lowerLeft.Y + (deltaY * toUpperRight.Y); for (int x = 0; x <= numberOfPartitionsX; ++x) { double deltaX = x / (double)numberOfPartitionsX; double currentX = lowerLeft.X + (deltaX * toUpperRight.X); positions.Add(new Vector3D(currentX, currentY, tile.Heights[heightIndex++])); } } // // Indices // int rowDelta = numberOfPartitionsX + 1; int i = 0; for (int y = 0; y < numberOfPartitionsY; ++y) { for (int x = 0; x < numberOfPartitionsX; ++x) { indices.AddTriangle(new TriangleIndicesUnsignedInt(i, i + 1, rowDelta + (i + 1))); indices.AddTriangle(new TriangleIndicesUnsignedInt(i, rowDelta + (i + 1), rowDelta + i)); i += 1; } i += 1; } _drawState = new DrawState(); _drawState.RenderState.FacetCulling.FrontFaceWindingOrder = mesh.FrontFaceWindingOrder; _drawState.ShaderProgram = sp; _drawState.VertexArray = context.CreateVertexArray(mesh, sp.VertexAttributes, BufferHint.StaticDraw); _silhouetteDrawState = new DrawState(); _silhouetteDrawState.RenderState.FacetCulling.Enabled = false; _silhouetteDrawState.RenderState.DepthMask = false; _silhouetteDrawState.VertexArray = _drawState.VertexArray; _silhouetteDrawState.ShaderProgram = silhouetteSP; _primitiveType = mesh.PrimitiveType; _clearColor = new ClearState(); _clearColor.Buffers = ClearBuffers.ColorBuffer; // // Only depth needs to be cleared but include stencil for speed. // _clearDepthStencil = new ClearState(); _clearDepthStencil.Buffers = ClearBuffers.DepthBuffer | ClearBuffers.StencilBuffer; }
public void Set(Context context, IList<Vector3D> positions) { // // This method expects that the positions are ordered in a repeated pattern of // below terrain, above terrain pairs. // // Wall mesh // Mesh wallMesh = new Mesh(); wallMesh.PrimitiveType = PrimitiveType.TriangleStrip; // // Positions // int numberOfLineSegments = (positions.Count / 2) - 1; int numberOfVertices = 2 + numberOfLineSegments + numberOfLineSegments; VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); IList<Vector3D> tempPositions = positionsAttribute.Values; wallMesh.Attributes.Add(positionsAttribute); foreach (Vector3D v in positions) { tempPositions.Add(v); } // // Vertex array // _wallVA = context.CreateVertexArray(wallMesh, _wallSP.VertexAttributes, BufferHint.StaticDraw); // // Line mesh // Mesh lineMesh = new Mesh(); lineMesh.PrimitiveType = PrimitiveType.LineStrip; // // Positions // positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); tempPositions = positionsAttribute.Values; lineMesh.Attributes.Add(positionsAttribute); foreach (Vector3D v in positions) { tempPositions.Add(v); } // // Indices // int numIndices = 4 * numberOfLineSegments; ushort[] indices = new ushort[numIndices]; int baseIndex = 1; for (int i = 0; i < numIndices; i += 4, baseIndex += 2) { indices[i] = (ushort)baseIndex; indices[i + 1] = (ushort)(baseIndex - 1); indices[i + 2] = (ushort)(baseIndex + 1); indices[i + 3] = (ushort)(baseIndex + 2); } IndexBuffer indexBuffer = Device.CreateIndexBuffer(BufferHint.StaticDraw, numIndices * sizeof(ushort)); indexBuffer.CopyFromSystemMemory(indices); // // Vertex array // _lineVA = context.CreateVertexArray(lineMesh, _wallSP.VertexAttributes, BufferHint.StaticDraw); _lineVA.IndexBuffer = indexBuffer; // // State // _wallDrawState = new DrawState(); _wallDrawState.RenderState.FacetCulling.Enabled = false; _wallDrawState.RenderState.DepthTest.Enabled = false; _wallDrawState.RenderState.DepthMask = false; _wallDrawState.VertexArray = _lineVA; _wallDrawState.ShaderProgram = _wallSP; _shadowVolumePassOne = new DrawState(); _shadowVolumePassOne.VertexArray = _lineVA; _shadowVolumePassOne.ShaderProgram = _shadowVolumeSP; _shadowVolumePassOne.RenderState.FacetCulling.Enabled = false; _shadowVolumePassOne.RenderState.DepthMask = false; _shadowVolumePassOne.RenderState.ColorMask = new ColorMask(false, false, false, false); StencilTest stOne = _shadowVolumePassOne.RenderState.StencilTest; stOne.Enabled = true; stOne.FrontFace.DepthFailStencilPassOperation = StencilOperation.Decrement; stOne.BackFace.DepthFailStencilPassOperation = StencilOperation.Increment; _shadowVolumePassTwo = new DrawState(); _shadowVolumePassTwo.VertexArray = _lineVA; _shadowVolumePassTwo.ShaderProgram = _shadowVolumeSP; _shadowVolumePassTwo.RenderState.DepthMask = false; StencilTest stTwo = _shadowVolumePassTwo.RenderState.StencilTest; stTwo.Enabled = true; stTwo.FrontFace.DepthFailStencilPassOperation = StencilOperation.Zero; stTwo.FrontFace.DepthPassStencilPassOperation = StencilOperation.Zero; stTwo.FrontFace.Function = StencilTestFunction.NotEqual; stTwo.BackFace.DepthFailStencilPassOperation = StencilOperation.Zero; stTwo.BackFace.DepthPassStencilPassOperation = StencilOperation.Zero; stTwo.BackFace.Function = StencilTestFunction.NotEqual; }
public Polygon(Context context, Ellipsoid globeShape, IEnumerable<Vector3D> positions) { Verify.ThrowIfNull(context); Verify.ThrowIfNull(globeShape); // // Pipeline Stage 1a: Clean up - Remove duplicate positions // List<Vector3D> cleanPositions = (List<Vector3D>)SimplePolygonAlgorithms.Cleanup(positions); // // Pipeline Stage 1b: Clean up - Swap winding order // EllipsoidTangentPlane plane = new EllipsoidTangentPlane(globeShape, cleanPositions); ICollection<Vector2D> positionsOnPlane = plane.ComputePositionsOnPlane(cleanPositions); if (SimplePolygonAlgorithms.ComputeWindingOrder(positionsOnPlane) == PolygonWindingOrder.Clockwise) { cleanPositions.Reverse(); //((List<Vector2D>)positionsOnPlane).Reverse(); } // // Pipeline Stage 2: Triangulate // IndicesUnsignedInt indices = EarClippingOnEllipsoid.Triangulate(cleanPositions); //IndicesInt32 indices = EarClipping.Triangulate(positionsOnPlane); // // Pipeline Stage 3: Subdivide // TriangleMeshSubdivisionResult result = TriangleMeshSubdivision.Compute(cleanPositions, indices, Trig.ToRadians(1)); // // Pipeline Stage 4: Set height // VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3( "position", (result.Indices.Values.Count / 3) + 2); foreach (Vector3D position in result.Positions) { positionsAttribute.Values.Add(globeShape.ScaleToGeocentricSurface(position)); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; mesh.Attributes.Add(positionsAttribute); mesh.Indices = result.Indices; ShaderProgram sp = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polygon.Shaders.PolygonVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polygon.Shaders.PolygonFS.glsl")); ((Uniform<Vector3F>)sp.Uniforms["u_globeOneOverRadiiSquared"]).Value = globeShape.OneOverRadiiSquared.ToVector3F(); _colorUniform = (Uniform<Vector4F>)sp.Uniforms["u_color"]; _drawState = new DrawState(); _drawState.RenderState.Blending.Enabled = true; _drawState.RenderState.Blending.SourceRGBFactor = SourceBlendingFactor.SourceAlpha; _drawState.RenderState.Blending.SourceAlphaFactor = SourceBlendingFactor.SourceAlpha; _drawState.RenderState.Blending.DestinationRGBFactor = DestinationBlendingFactor.OneMinusSourceAlpha; _drawState.RenderState.Blending.DestinationAlphaFactor = DestinationBlendingFactor.OneMinusSourceAlpha; _drawState.ShaderProgram = sp; _meshBuffers = Device.CreateMeshBuffers(mesh, _drawState.ShaderProgram.VertexAttributes, BufferHint.StaticDraw); _primitiveType = mesh.PrimitiveType; Color = Color.White; }
public void Set(Context context, IList <Vector3D> positions) { // // This method expects that the positions are ordered in a repeated pattern of // below terrain, above terrain pairs. // // Wall mesh // Mesh wallMesh = new Mesh(); wallMesh.PrimitiveType = PrimitiveType.TriangleStrip; // // Positions // int numberOfLineSegments = (positions.Count / 2) - 1; int numberOfVertices = 2 + numberOfLineSegments + numberOfLineSegments; VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); IList <Vector3D> tempPositions = positionsAttribute.Values; wallMesh.Attributes.Add(positionsAttribute); foreach (Vector3D v in positions) { tempPositions.Add(v); } // // Vertex array // _wallVA = context.CreateVertexArray(wallMesh, _wallSP.VertexAttributes, BufferHint.StaticDraw); // // Line mesh // Mesh lineMesh = new Mesh(); lineMesh.PrimitiveType = PrimitiveType.LineStrip; // // Positions // positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); tempPositions = positionsAttribute.Values; lineMesh.Attributes.Add(positionsAttribute); foreach (Vector3D v in positions) { tempPositions.Add(v); } // // Indices // int numIndices = 4 * numberOfLineSegments; ushort[] indices = new ushort[numIndices]; int baseIndex = 1; for (int i = 0; i < numIndices; i += 4, baseIndex += 2) { indices[i] = (ushort)baseIndex; indices[i + 1] = (ushort)(baseIndex - 1); indices[i + 2] = (ushort)(baseIndex + 1); indices[i + 3] = (ushort)(baseIndex + 2); } IndexBuffer indexBuffer = Device.CreateIndexBuffer(BufferHint.StaticDraw, numIndices * sizeof(ushort)); indexBuffer.CopyFromSystemMemory(indices); // // Vertex array // _lineVA = context.CreateVertexArray(lineMesh, _wallSP.VertexAttributes, BufferHint.StaticDraw); _lineVA.IndexBuffer = indexBuffer; // // State // _wallDrawState = new DrawState(); _wallDrawState.RenderState.FacetCulling.Enabled = false; _wallDrawState.RenderState.DepthTest.Enabled = false; _wallDrawState.RenderState.DepthMask = false; _wallDrawState.VertexArray = _lineVA; _wallDrawState.ShaderProgram = _wallSP; _shadowVolumePassOne = new DrawState(); _shadowVolumePassOne.VertexArray = _lineVA; _shadowVolumePassOne.ShaderProgram = _shadowVolumeSP; _shadowVolumePassOne.RenderState.FacetCulling.Enabled = false; _shadowVolumePassOne.RenderState.DepthMask = false; _shadowVolumePassOne.RenderState.ColorMask = new ColorMask(false, false, false, false); StencilTest stOne = _shadowVolumePassOne.RenderState.StencilTest; stOne.Enabled = true; stOne.FrontFace.DepthFailStencilPassOperation = StencilOperation.Decrement; stOne.BackFace.DepthFailStencilPassOperation = StencilOperation.Increment; _shadowVolumePassTwo = new DrawState(); _shadowVolumePassTwo.VertexArray = _lineVA; _shadowVolumePassTwo.ShaderProgram = _shadowVolumeSP; _shadowVolumePassTwo.RenderState.DepthMask = false; StencilTest stTwo = _shadowVolumePassTwo.RenderState.StencilTest; stTwo.Enabled = true; stTwo.FrontFace.DepthFailStencilPassOperation = StencilOperation.Zero; stTwo.FrontFace.DepthPassStencilPassOperation = StencilOperation.Zero; stTwo.FrontFace.Function = StencilTestFunction.NotEqual; stTwo.BackFace.DepthFailStencilPassOperation = StencilOperation.Zero; stTwo.BackFace.DepthPassStencilPassOperation = StencilOperation.Zero; stTwo.BackFace.Function = StencilTestFunction.NotEqual; }
public static Mesh Compute(Ellipsoid ellipsoid, int numberOfPartitions, CubeMapEllipsoidVertexAttributes vertexAttributes) { if (numberOfPartitions < 0) { throw new ArgumentOutOfRangeException("numberOfPartitions"); } if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.Position) != CubeMapEllipsoidVertexAttributes.Position) { throw new ArgumentException("Positions must be provided.", "vertexAttributes"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfVertices = NumberOfVertices(numberOfPartitions); VertexAttributeDoubleVector3 positionsAttribute = new VertexAttributeDoubleVector3("position", numberOfVertices); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedInt indices = new IndicesUnsignedInt(3 * NumberOfTriangles(numberOfPartitions)); mesh.Indices = indices; CubeMapMesh CubeMapMesh = new CubeMapMesh(); CubeMapMesh.Ellipsoid = ellipsoid; CubeMapMesh.NumberOfPartitions = numberOfPartitions; CubeMapMesh.Positions = positionsAttribute.Values; CubeMapMesh.Indices = indices; if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.Normal) == CubeMapEllipsoidVertexAttributes.Normal) { VertexAttributeHalfFloatVector3 normalsAttribute = new VertexAttributeHalfFloatVector3("normal", numberOfVertices); mesh.Attributes.Add(normalsAttribute); CubeMapMesh.Normals = normalsAttribute.Values; } if ((vertexAttributes & CubeMapEllipsoidVertexAttributes.TextureCoordinate) == CubeMapEllipsoidVertexAttributes.TextureCoordinate) { VertexAttributeHalfFloatVector2 textureCoordinateAttribute = new VertexAttributeHalfFloatVector2("textureCoordinate", numberOfVertices); mesh.Attributes.Add(textureCoordinateAttribute); CubeMapMesh.TextureCoordinate = textureCoordinateAttribute.Values; } // // Initial cube. In the plane, z = -1: // // +y // | // Q2 * p3 Q1 // / | \ // p0 *--+--* p2 +x // \ | / // Q3 * p1 Q4 // | // // Similarly, p4 to p7 are in the plane z = 1. // CubeMapMesh.Positions.Add(new Vector3D(-1, 0, -1)); CubeMapMesh.Positions.Add(new Vector3D(0, -1, -1)); CubeMapMesh.Positions.Add(new Vector3D(1, 0, -1)); CubeMapMesh.Positions.Add(new Vector3D(0, 1, -1)); CubeMapMesh.Positions.Add(new Vector3D(-1, 0, 1)); CubeMapMesh.Positions.Add(new Vector3D(0, -1, 1)); CubeMapMesh.Positions.Add(new Vector3D(1, 0, 1)); CubeMapMesh.Positions.Add(new Vector3D(0, 1, 1)); // // Edges // // 0 -> 1, 1 -> 2, 2 -> 3, 3 -> 0. Plane z = -1 // 4 -> 5, 5 -> 6, 6 -> 7, 7 -> 4. Plane z = 1 // 0 -> 4, 1 -> 5, 2 -> 6, 3 -> 7. From plane z = -1 to plane z - 1 // int[] edge0to1 = AddEdgePositions(0, 1, CubeMapMesh); int[] edge1to2 = AddEdgePositions(1, 2, CubeMapMesh); int[] edge2to3 = AddEdgePositions(2, 3, CubeMapMesh); int[] edge3to0 = AddEdgePositions(3, 0, CubeMapMesh); int[] edge4to5 = AddEdgePositions(4, 5, CubeMapMesh); int[] edge5to6 = AddEdgePositions(5, 6, CubeMapMesh); int[] edge6to7 = AddEdgePositions(6, 7, CubeMapMesh); int[] edge7to4 = AddEdgePositions(7, 4, CubeMapMesh); int[] edge0to4 = AddEdgePositions(0, 4, CubeMapMesh); int[] edge1to5 = AddEdgePositions(1, 5, CubeMapMesh); int[] edge2to6 = AddEdgePositions(2, 6, CubeMapMesh); int[] edge3to7 = AddEdgePositions(3, 7, CubeMapMesh); AddFaceTriangles(edge0to4, edge0to1, edge1to5, edge4to5, CubeMapMesh); // Q3 Face AddFaceTriangles(edge1to5, edge1to2, edge2to6, edge5to6, CubeMapMesh); // Q4 Face AddFaceTriangles(edge2to6, edge2to3, edge3to7, edge6to7, CubeMapMesh); // Q1 Face AddFaceTriangles(edge3to7, edge3to0, edge0to4, edge7to4, CubeMapMesh); // Q2 Face AddFaceTriangles(ReversedArray(edge7to4), edge4to5, edge5to6, ReversedArray(edge6to7), CubeMapMesh); // Plane z = 1 AddFaceTriangles(edge1to2, ReversedArray(edge0to1), ReversedArray(edge3to0), edge2to3, CubeMapMesh); // Plane z = -1 CubeToEllipsoid(CubeMapMesh); return mesh; }