public void Set(Context context, Mesh mesh) { Verify.ThrowIfNull(context); if (mesh == null) { throw new ArgumentNullException("mesh"); } if (mesh.PrimitiveType != PrimitiveType.Lines && mesh.PrimitiveType != PrimitiveType.LineLoop && mesh.PrimitiveType != PrimitiveType.LineStrip) { throw new ArgumentException("mesh.PrimitiveType must be Lines, LineLoop, or LineStrip.", "mesh"); } if (!mesh.Attributes.Contains("position") && !mesh.Attributes.Contains("color")) { throw new ArgumentException("mesh.Attributes should contain attributes named \"position\" and \"color\".", "mesh"); } if (_drawState.ShaderProgram == null) { _drawState.ShaderProgram = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polyline.Polyline.PolylineVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polyline.Polyline.PolylineGS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Polyline.Polyline.PolylineFS.glsl")); _fillDistance = (Uniform<float>)_drawState.ShaderProgram.Uniforms["u_fillDistance"]; } /////////////////////////////////////////////////////////////////// _drawState.VertexArray = context.CreateVertexArray(mesh, _drawState.ShaderProgram.VertexAttributes, BufferHint.StaticDraw); _primitiveType = mesh.PrimitiveType; }
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 GPURelativeToEye(Context context, Vector3D[] positions, byte[] colors) { _sp = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Examples.GPURelativeToEye.Shaders.VS.glsl"), EmbeddedResources.GetText("OpenGlobe.Examples.Shaders.FS.glsl")); _cameraEyeHigh = (Uniform<Vector3F>)_sp.Uniforms["u_cameraEyeHigh"]; _cameraEyeLow = (Uniform<Vector3F>)_sp.Uniforms["u_cameraEyeLow"]; _modelViewPerspectiveMatrixRelativeToEye = (Uniform<Matrix4F>)(_sp.Uniforms["u_modelViewPerspectiveMatrixRelativeToEye"]); _pointSize = (Uniform<float>)_sp.Uniforms["u_pointSize"]; /////////////////////////////////////////////////////////////////// Mesh mesh = new Mesh(); VertexAttributeFloatVector3 positionsHighAttribute = new VertexAttributeFloatVector3("positionHigh", positions.Length); VertexAttributeFloatVector3 positionsLowAttribute = new VertexAttributeFloatVector3("positionLow", positions.Length); VertexAttributeRGB colorAttribute = new VertexAttributeRGB("color", positions.Length); mesh.Attributes.Add(positionsHighAttribute); mesh.Attributes.Add(positionsLowAttribute); mesh.Attributes.Add(colorAttribute); for (int i = 0; i < positions.Length; ++i) { Vector3F positionHigh; Vector3F positionLow; Vector3DToTwoVector3F(positions[i], out positionHigh, out positionLow); positionsHighAttribute.Values.Add(positionHigh); positionsLowAttribute.Values.Add(positionLow); } for (int i = 0; i < colors.Length; ++i) { colorAttribute.Values.Add(colors[i]); } _va = context.CreateVertexArray(mesh, _sp.VertexAttributes, BufferHint.StaticDraw); /////////////////////////////////////////////////////////////////// RenderState renderState = new RenderState(); renderState.FacetCulling.Enabled = false; renderState.DepthTest.Enabled = false; renderState.ProgramPointSize = ProgramPointSize.Enabled; _drawState = new DrawState(renderState, _sp, _va); }
public Wireframe(Context context, Mesh mesh) { RenderState renderState = new RenderState(); renderState.Blending.Enabled = true; renderState.Blending.SourceRGBFactor = SourceBlendingFactor.SourceAlpha; renderState.Blending.SourceAlphaFactor = SourceBlendingFactor.SourceAlpha; renderState.Blending.DestinationRGBFactor = DestinationBlendingFactor.OneMinusSourceAlpha; renderState.Blending.DestinationAlphaFactor = DestinationBlendingFactor.OneMinusSourceAlpha; renderState.FacetCulling.FrontFaceWindingOrder = mesh.FrontFaceWindingOrder; renderState.DepthTest.Function = DepthTestFunction.LessThanOrEqual; // // This implementation is based on the 2006 SIGGRAPH Sketch: // // Single-pass Wireframe Rendering // http://www2.imm.dtu.dk/pubdb/views/edoc_download.php/4884/pdf/imm4884.pdf // // NVIDIA published a white paper with some enhancements we can consider: // // Solid Wireframe // http://developer.download.nvidia.com/SDK/10.5/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf // // More recent work, which I was not aware of at the time, is: // // Two Methods for Antialiased Wireframe Drawing with Hidden Line Removal // http://orbit.dtu.dk/getResource?recordId=219956&objectId=1&versionId=1 // ShaderProgram sp = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Wireframe.Shaders.WireframeVS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Wireframe.Shaders.WireframeGS.glsl"), EmbeddedResources.GetText("OpenGlobe.Scene.Renderables.Wireframe.Shaders.WireframeFS.glsl")); _lineWidth = (Uniform<float>)sp.Uniforms["u_halfLineWidth"]; Width = 1; _colorUniform = (Uniform<Vector3F>)sp.Uniforms["u_color"]; Color = Color.Black; _drawState = new DrawState(renderState, sp, context.CreateVertexArray(mesh, sp.VertexAttributes, BufferHint.StaticDraw)); _primitiveType = mesh.PrimitiveType; }
public RelativeToCenter(Context context, Vector3D[] positions, byte[] colors) { _sp = Device.CreateShaderProgram( EmbeddedResources.GetText("OpenGlobe.Examples.RelativeToCenter.Shaders.VS.glsl"), EmbeddedResources.GetText("OpenGlobe.Examples.Shaders.FS.glsl")); _modelViewPerspectiveMatrixRelativeToCenter = (Uniform<Matrix4F>)(_sp.Uniforms["u_modelViewPerspectiveMatrixRelativeToCenter"]); _pointSize = (Uniform<float>)_sp.Uniforms["u_pointSize"]; /////////////////////////////////////////////////////////////////// Mesh mesh = new Mesh(); VertexAttributeFloatVector3 positionsAttribute = new VertexAttributeFloatVector3("position", positions.Length); VertexAttributeRGB colorAttribute = new VertexAttributeRGB("color", positions.Length); mesh.Attributes.Add(positionsAttribute); mesh.Attributes.Add(colorAttribute); _center = new AxisAlignedBoundingBox(positions).Center; for (int i = 0; i < positions.Length; ++i) { positionsAttribute.Values.Add((positions[i] - _center).ToVector3F()); } for (int i = 0; i < colors.Length; ++i) { colorAttribute.Values.Add(colors[i]); } _va = context.CreateVertexArray(mesh, _sp.VertexAttributes, BufferHint.StaticDraw); /////////////////////////////////////////////////////////////////// RenderState renderState = new RenderState(); renderState.FacetCulling.Enabled = false; renderState.DepthTest.Enabled = false; renderState.ProgramPointSize = ProgramPointSize.Enabled; _drawState = new DrawState(renderState, _sp, _va); }
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 void MeshIndices() { Mesh mesh = new Mesh(); IndicesUnsignedShort indicesShort = new IndicesUnsignedShort(); mesh.Indices = indicesShort; Assert.AreEqual(IndicesType.UnsignedShort, mesh.Indices.Datatype); IndicesUnsignedInt indicesInt = new IndicesUnsignedInt(); mesh.Indices = indicesInt; Assert.AreEqual(IndicesType.UnsignedInt, mesh.Indices.Datatype); indicesInt.AddTriangle(new TriangleIndicesUnsignedInt(0, 1, 2)); Assert.AreEqual(0, indicesInt.Values[0]); Assert.AreEqual(1, indicesInt.Values[1]); Assert.AreEqual(2, indicesInt.Values[2]); }
public static Mesh Compute(RectangleD rectangle, int numberOfPartitionsX, int numberOfPartitionsY) { if (numberOfPartitionsX < 0) { throw new ArgumentOutOfRangeException("numberOfPartitionsX"); } if (numberOfPartitionsY < 0) { throw new ArgumentOutOfRangeException("numberOfPartitionsY"); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfPositions = (numberOfPartitionsX + 1) * (numberOfPartitionsY + 1); VertexAttributeFloatVector2 positionsAttribute = new VertexAttributeFloatVector2("position", numberOfPositions); IList<Vector2F> positions = positionsAttribute.Values; mesh.Attributes.Add(positionsAttribute); int numberOfIndices = (numberOfPartitionsX * numberOfPartitionsY) * 6; IndicesUnsignedInt indices = new IndicesUnsignedInt(numberOfIndices); mesh.Indices = indices; // // Positions // Vector2D lowerLeft = rectangle.LowerLeft; Vector2D toUpperRight = rectangle.UpperRight - lowerLeft; 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 Vector2D(currentX, currentY).ToVector2F()); } } // // 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; } return mesh; }
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 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; }
private Mesh CreateDegenerateTriangleMesh() { Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.Triangles; mesh.FrontFaceWindingOrder = WindingOrder.Counterclockwise; int numberOfPositions = _clipmapSegments * 4; VertexAttributeFloatVector2 positionsAttribute = new VertexAttributeFloatVector2("position", numberOfPositions); IList<Vector2F> positions = positionsAttribute.Values; mesh.Attributes.Add(positionsAttribute); int numberOfIndices = (_clipmapSegments / 2) * 3 * 4; IndicesUnsignedShort indices = new IndicesUnsignedShort(numberOfIndices); mesh.Indices = indices; for (int i = 0; i < _clipmapPosts; ++i) { positions.Add(new Vector2F(0.0f, i)); } for (int i = 1; i < _clipmapPosts; ++i) { positions.Add(new Vector2F(i, _clipmapSegments)); } for (int i = _clipmapSegments - 1; i >= 0; --i) { positions.Add(new Vector2F(_clipmapSegments, i)); } for (int i = _clipmapSegments - 1; i > 0; --i) { positions.Add(new Vector2F(i, 0.0f)); } for (int i = 0; i < numberOfIndices; i += 2) { indices.AddTriangle(new TriangleIndicesUnsignedShort((ushort)i, (ushort)(i + 1), (ushort)(i + 2))); } return 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 virtual VertexArray CreateVertexArray(Mesh mesh, ShaderVertexAttributeCollection shaderAttributes, BufferHint usageHint) { return CreateVertexArray(Device.CreateMeshBuffers(mesh, shaderAttributes, usageHint)); }
public Triangle() { _window = Device.CreateWindow(800, 600, "Chapter 3: Triangle"); _window.Resize += OnResize; _window.RenderFrame += OnRenderFrame; _sceneState = new SceneState(); _clearState = new ClearState(); string vs = @"#version 330 layout(location = og_positionVertexLocation) in vec4 position; uniform mat4 og_modelViewPerspectiveMatrix; void main() { gl_Position = og_modelViewPerspectiveMatrix * position; }"; string fs = @"#version 330 out vec3 fragmentColor; uniform vec3 u_color; void main() { fragmentColor = u_color; }"; ShaderProgram sp = Device.CreateShaderProgram(vs, fs); ((Uniform<Vector3F>)sp.Uniforms["u_color"]).Value = new Vector3F(1, 0, 0); /////////////////////////////////////////////////////////////////// Mesh mesh = new Mesh(); VertexAttributeFloatVector3 positionsAttribute = new VertexAttributeFloatVector3("position", 3); mesh.Attributes.Add(positionsAttribute); IndicesUnsignedShort indices = new IndicesUnsignedShort(3); mesh.Indices = indices; IList<Vector3F> positions = positionsAttribute.Values; positions.Add(new Vector3F(0, 0, 0)); positions.Add(new Vector3F(1, 0, 0)); positions.Add(new Vector3F(0, 0, 1)); indices.AddTriangle(new TriangleIndicesUnsignedShort(0, 1, 2)); VertexArray va = _window.Context.CreateVertexArray(mesh, sp.VertexAttributes, BufferHint.StaticDraw); /////////////////////////////////////////////////////////////////// RenderState renderState = new RenderState(); renderState.FacetCulling.Enabled = false; renderState.DepthTest.Enabled = false; _drawState = new DrawState(renderState, sp, va); /////////////////////////////////////////////////////////////////// _sceneState.Camera.ZoomToTarget(1); }
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 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; }
public void MeshVertexAttributes() { Mesh mesh = new Mesh(); VertexAttributeHalfFloat halfFloatAttribute = new VertexAttributeHalfFloat("halfFloatAttribute"); mesh.Attributes.Add(halfFloatAttribute); Assert.AreEqual("halfFloatAttribute", mesh.Attributes["halfFloatAttribute"].Name); Assert.AreEqual(VertexAttributeType.HalfFloat, mesh.Attributes["halfFloatAttribute"].Datatype); VertexAttributeHalfFloatVector2 halfFloatAttribute2 = new VertexAttributeHalfFloatVector2("halfFloatAttribute2"); mesh.Attributes.Add(halfFloatAttribute2); Assert.AreEqual("halfFloatAttribute2", mesh.Attributes["halfFloatAttribute2"].Name); Assert.AreEqual(VertexAttributeType.HalfFloatVector2, mesh.Attributes["halfFloatAttribute2"].Datatype); VertexAttributeHalfFloatVector3 halfFloatAttribute3 = new VertexAttributeHalfFloatVector3("halfFloatAttribute3"); mesh.Attributes.Add(halfFloatAttribute3); Assert.AreEqual("halfFloatAttribute3", mesh.Attributes["halfFloatAttribute3"].Name); Assert.AreEqual(VertexAttributeType.HalfFloatVector3, mesh.Attributes["halfFloatAttribute3"].Datatype); VertexAttributeHalfFloatVector4 halfFloatAttribute4 = new VertexAttributeHalfFloatVector4("halfFloatAttribute4"); mesh.Attributes.Add(halfFloatAttribute4); Assert.AreEqual("halfFloatAttribute4", mesh.Attributes["halfFloatAttribute4"].Name); Assert.AreEqual(VertexAttributeType.HalfFloatVector4, mesh.Attributes["halfFloatAttribute4"].Datatype); /////////////////////////////////////////////////////////////////// VertexAttributeFloat floatAttribute = new VertexAttributeFloat("floatAttribute"); mesh.Attributes.Add(floatAttribute); Assert.AreEqual("floatAttribute", mesh.Attributes["floatAttribute"].Name); Assert.AreEqual(VertexAttributeType.Float, mesh.Attributes["floatAttribute"].Datatype); VertexAttributeFloatVector2 floatAttribute2 = new VertexAttributeFloatVector2("floatAttribute2"); mesh.Attributes.Add(floatAttribute2); Assert.AreEqual("floatAttribute2", mesh.Attributes["floatAttribute2"].Name); Assert.AreEqual(VertexAttributeType.FloatVector2, mesh.Attributes["floatAttribute2"].Datatype); VertexAttributeFloatVector3 floatAttribute3 = new VertexAttributeFloatVector3("floatAttribute3"); mesh.Attributes.Add(floatAttribute3); Assert.AreEqual("floatAttribute3", mesh.Attributes["floatAttribute3"].Name); Assert.AreEqual(VertexAttributeType.FloatVector3, mesh.Attributes["floatAttribute3"].Datatype); VertexAttributeFloatVector4 floatAttribute4 = new VertexAttributeFloatVector4("floatAttribute4"); mesh.Attributes.Add(floatAttribute4); Assert.AreEqual("floatAttribute4", mesh.Attributes["floatAttribute4"].Name); Assert.AreEqual(VertexAttributeType.FloatVector4, mesh.Attributes["floatAttribute4"].Datatype); /////////////////////////////////////////////////////////////////// VertexAttributeByte byteAttribute = new VertexAttributeByte("byteAttribute"); mesh.Attributes.Add(byteAttribute); Assert.AreEqual("byteAttribute", mesh.Attributes["byteAttribute"].Name); Assert.AreEqual(VertexAttributeType.UnsignedByte, mesh.Attributes["byteAttribute"].Datatype); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("colorAttribute"); mesh.Attributes.Add(colorAttribute); Assert.AreEqual("colorAttribute", mesh.Attributes["colorAttribute"].Name); Assert.AreEqual(VertexAttributeType.UnsignedByte, mesh.Attributes["colorAttribute"].Datatype); colorAttribute.AddColor(Color.FromArgb(3, 0, 1, 2)); Assert.AreEqual(0, colorAttribute.Values[0]); Assert.AreEqual(1, colorAttribute.Values[1]); Assert.AreEqual(2, colorAttribute.Values[2]); Assert.AreEqual(3, colorAttribute.Values[3]); }
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 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 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); }
private void CreateScene() { DisposeScene(); _ellipsoid = new TessellatedGlobe(); _ellipsoid.Shape = _globeShape; _ellipsoid.NumberOfSlicePartitions = 64; _ellipsoid.NumberOfStackPartitions = 32; /////////////////////////////////////////////////////////////////// Mesh mesh = GeographicGridEllipsoidTessellator.Compute(_globeShape, 64, 32, GeographicGridEllipsoidVertexAttributes.Position); _wireframe = new Wireframe(_window.Context, mesh); _wireframe.Width = 2; /////////////////////////////////////////////////////////////////// _axes = new Axes(); _axes.Length = 1.5; _axes.Width = 3; /////////////////////////////////////////////////////////////////// Vector3D p = _globeShape.ToVector3D(new Geodetic3D(0, Trig.ToRadians(45), 0)); Vector3D deticNormal = _globeShape.GeodeticSurfaceNormal(p); Vector3D centricNormal = Ellipsoid.CentricSurfaceNormal(p); double normalLength = _globeShape.MaximumRadius; Vector3D pDetic = p + (normalLength * deticNormal); Vector3D pCentric = p + (normalLength * centricNormal); VertexAttributeFloatVector3 positionAttribute = new VertexAttributeFloatVector3("position", 4); positionAttribute.Values.Add(p.ToVector3F()); positionAttribute.Values.Add(pDetic.ToVector3F()); positionAttribute.Values.Add(p.ToVector3F()); positionAttribute.Values.Add(pCentric.ToVector3F()); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color", 4); colorAttribute.AddColor(Color.DarkGreen); colorAttribute.AddColor(Color.DarkGreen); colorAttribute.AddColor(Color.DarkCyan); colorAttribute.AddColor(Color.DarkCyan); Mesh polyline = new Mesh(); polyline.PrimitiveType = PrimitiveType.Lines; polyline.Attributes.Add(positionAttribute); polyline.Attributes.Add(colorAttribute); _normals = new Polyline(); _normals.Set(_window.Context, polyline); _normals.Width = 3; /////////////////////////////////////////////////////////////////// Font font = new Font("Arial", 24); IList<Bitmap> labelBitmaps = new List<Bitmap>(2); labelBitmaps.Add(Device.CreateBitmapFromText("Geodetic", font)); labelBitmaps.Add(Device.CreateBitmapFromText("Geocentric", font)); font.Dispose(); TextureAtlas atlas = new TextureAtlas(labelBitmaps); _labels = new BillboardCollection(_window.Context, 2); _labels.Texture = Device.CreateTexture2D(atlas.Bitmap, TextureFormat.RedGreenBlueAlpha8, false); _labels.Add(new Billboard() { Position = pDetic, TextureCoordinates = atlas.TextureCoordinates[0], Color = Color.DarkGreen, HorizontalOrigin = HorizontalOrigin.Right, VerticalOrigin = VerticalOrigin.Bottom }); _labels.Add(new Billboard() { Position = pCentric, TextureCoordinates = atlas.TextureCoordinates[1], Color = Color.DarkCyan, HorizontalOrigin = HorizontalOrigin.Right, VerticalOrigin = VerticalOrigin.Bottom }); atlas.Dispose(); /////////////////////////////////////////////////////////////////// Vector3D east = Vector3D.UnitZ.Cross(deticNormal); Vector3D north = deticNormal.Cross(east); _tangentPlane = new Plane(_window.Context); _tangentPlane.Origin = p; _tangentPlane.XAxis = east; _tangentPlane.YAxis = north; _tangentPlane.OutlineWidth = 3; }
private void CreateScene() { string text = "Granularity: " + _granularityInDegrees + " (left/right)\n"; text += "Points: " + (_sampledPoints.Show ? "on" : "off") + " ('1')\n"; text += "Polyline: " + (_polyline.Show ? "on" : "off") + " ('2')\n"; text += "Plane: " + (_plane.Show ? "on" : "off") + " ('3')\n"; text += "Semi-minor axis (up/down)\n"; _instructions.Texture = Device.CreateTexture2D( Device.CreateBitmapFromText(text, new Font("Arial", 24)), TextureFormat.RedGreenBlueAlpha8, false); /////////////////////////////////////////////////////////////////// IList<Vector3D> positions = _globeShape.ComputeCurve( _p, _q, Trig.ToRadians(_granularityInDegrees)); _sampledPoints.Clear(); _sampledPoints.Add(new Billboard() { Position = positions[0], Color = Color.Orange }); _sampledPoints.Add(new Billboard() { Position = positions[positions.Count - 1], Color = Color.Orange }); for (int i = 1; i < positions.Count - 1; ++i) { _sampledPoints.Add(new Billboard() { Position = positions[i], Color = Color.Yellow }); } /////////////////////////////////////////////////////////////////// _ellipsoid.Shape = _globeShape; /////////////////////////////////////////////////////////////////// VertexAttributeFloatVector3 positionAttribute = new VertexAttributeFloatVector3("position", positions.Count); VertexAttributeRGBA colorAttribute = new VertexAttributeRGBA("color", positions.Count); for (int i = 0; i < positions.Count; ++i) { positionAttribute.Values.Add(positions[i].ToVector3F()); colorAttribute.AddColor(Color.Red); } Mesh mesh = new Mesh(); mesh.PrimitiveType = PrimitiveType.LineStrip; mesh.Attributes.Add(positionAttribute); mesh.Attributes.Add(colorAttribute); _polyline.Set(_window.Context, mesh); /////////////////////////////////////////////////////////////////// double scale = 1.25 * _globeShape.Radii.MaximumComponent; _plane.XAxis = scale * _p.Normalize(); _plane.YAxis = scale * _p.Cross(_q).Cross(_p).Normalize(); }