public override void ProduceOutput(ZContent content) { Shape shape = new Shape(); if (Grid2DOnly) { //Create a simple 2d-grid shape.MakeNet(XCount, YCount); shape.Scale(new Vector3(2, 2, 1)); } else { Shape temp = new Shape(); temp.MakeNet(XCount, YCount); shape.CreateData(temp.Vertices.Length * 6, (temp.Indices.Length * 6) / 3, true, false); int vertexOffset = 0; int indexOffset = 0; // MakeNet makes a network from -0.5 to 0.5 // Increase to -1 .. 1, and move forward towards the camera //Default matrix Matrix4 mx = Matrix4.Scale(2, 2, 1) * Matrix4.CreateTranslation(0, 0, 1); //Sides for (int i = 0; i < 4; i++) { Matrix4 m = mx * Matrix4.CreateRotationY(i * MathHelper.PiOver2); shape.CopyMeshWithTransform(temp, m, vertexOffset, indexOffset); vertexOffset += temp.Vertices.Length; indexOffset += temp.Indices.Length; } //Top and bottom for (int i = 0; i < 2; i++) { Matrix4 m = mx * Matrix4.CreateRotationX((-1.0f + i * 2) * MathHelper.PiOver2); shape.CopyMeshWithTransform(temp, m, vertexOffset, indexOffset); vertexOffset += temp.Vertices.Length; indexOffset += temp.Indices.Length; } } shape.Scale(Scale); shape.ComputeNormals(); Mesh mesh = content as Mesh; mesh.CreateVBO(shape); }
public void CopyMeshWithTransform(Shape source, Matrix4 mx, int vertexOffset, int indexOffset) { int i; int vx = vertexOffset; int ix = indexOffset; for (i = 0; i < source.vertices.Length; i++) { Vector3.Transform(ref source.vertices[i], ref mx, out vertices[vx]); vx++; } for (i = 0; i < source.indices.Length; i++) { indices[ix] = source.indices[i] + vertexOffset; ix++; } if (texcoords != null && source.texcoords != null) { vx = vertexOffset; for (i = 0; i < source.texcoords.Length; i++) { texcoords[vx] = source.texcoords[i]; vx++; } } }
public override void ProduceOutput(ZContent content) { if (Heightmap == null) return; Heightmap.OnRefresh -= Refresh; //Avoid double subscription Heightmap.OnRefresh += Refresh; Shape shape = new Shape(); Heightmap.Prepare(); int w = Heightmap.Width; int h = Heightmap.Height; float[,] hm = Heightmap.data; //Create a simple 2d-grid, and scale it up to [-1, 1] shape.MakeNet(w - 2, h - 2); shape.Scale(new Vector3(2, 2, 1)); shape.ApplyHeightMap(hm, w, h); shape.Scale(Scale); shape.ComputeNormals(); Mesh mesh = content as Mesh; mesh.CreateVBO(shape); }
public override void ProduceOutput(ZContent content) { const float Radius = 1.0f; if (ZSamples <= 2 || RadialSamples <= 2) return; Shape shape = new Shape(); int ZSm1 = ZSamples - 1; int ZSm2 = ZSamples - 2; int ZSm3 = ZSamples - 3; int RSp1 = RadialSamples + 1; int VQuantity = ZSm2 * RSp1 + 2; int TQuantity = 2 * ZSm2 * RadialSamples; shape.CreateData(VQuantity, TQuantity, false, false); // generate geometry float InvRS = 1.0f / RadialSamples; float ZFactor = 2.0f / ZSm1; // Generate points on the unit circle to be used in computing the shape // points on a cylinder slice. var afSin = new float[RSp1]; var afCos = new float[RSp1]; for (int r = 0; r <= RadialSamples - 1; r++) { float angle = (MathHelper.TwoPi) * InvRS * r; afCos[r] = (float) Math.Cos(angle); afSin[r] = (float) Math.Sin(angle); } afSin[RadialSamples] = afSin[0]; afCos[RadialSamples] = afCos[0]; // generate the cylinder itself int i = 0; for (int z = 1; z <= ZSm1 - 1; z++) { float ZFraction = -1.0f + ZFactor * z; // in (-1,1) float fZ = Radius * ZFraction; // compute center of slice Vector3 SliceCenter = new Vector3(0.0f, 0.0f, fZ); // compute radius of slice float SliceRadius = (float) Math.Sqrt(Math.Abs(Radius * Radius - fZ * fZ)); // compute slice vertices with duplication at end point int save = i; for (int r = 0; r <= RadialSamples - 1; r++) { // RadialFraction = R*InvRS; // in [0,1) Vector3 radial = new Vector3(afCos[r], afSin[r], 0.0f); shape.Vertices[i] = SliceCenter + SliceRadius * radial; Vector3.Normalize(ref shape.Vertices[i], out shape.Normals[i]); i++; } shape.Vertices[i] = shape.Vertices[save]; shape.Normals[i] = shape.Normals[save]; i++; } // south pole shape.Vertices[i] = -Radius * Vector3.UnitZ; shape.Normals[i] = -1.0f * Vector3.UnitZ; i++; // north pole shape.Vertices[i] = Radius * Vector3.UnitZ; shape.Normals[i] = Vector3.UnitZ; // Assert( i == VQuantity ); // generate connectivity int idx = 0; int zstart = 0; for (int z = 0; z <= ZSm3 - 1; z++) { int i0 = zstart; int i1 = i0 + 1; zstart += RSp1; int i2 = zstart; int i3 = i2 + 1; for (i = 0; i <= RadialSamples - 1; i++) { shape.Indices[idx + 0] = i0; i0++; shape.Indices[idx + 1] = i1; shape.Indices[idx + 2] = i2; shape.Indices[idx + 3] = i1; i1++; shape.Indices[idx + 4] = i3; i3++; shape.Indices[idx + 5] = i2; i2++; idx += 6; } } // south pole triangles int VQm2 = VQuantity - 2; for (i = 0; i <= RadialSamples - 1; i++) { shape.Indices[idx + 0] = i; shape.Indices[idx + 1] = VQm2; shape.Indices[idx + 2] = i + 1; idx += 3; } // north pole triangles int VQm1 = VQuantity - 1; int offset = ZSm3 * RSp1; for (i = 0; i <= RadialSamples - 1; i++) { shape.Indices[idx + 0] = VQm1; shape.Indices[idx + 1] = i + offset; shape.Indices[idx + 2] = i + 1 + offset; idx += 3; } // assert( aiLocalIndex == m_aiIndex + 3*iTQuantity ); shape.Scale(Scale); Mesh mesh = content as Mesh; mesh.CreateVBO(shape); }
/// <summary> /// Generate a VertexBuffer for each of Color, Normal, TextureCoordinate, Vertex, and Indices /// </summary> public void CreateVBO(Shape shape) { ReleaseBuffers(); vbo = new Vbo(); if (shape.Vertices == null) return; if (shape.Indices == null) return; int bufferSize; // Color Array Buffer if (shape.Colors != null) { // Generate Array Buffer Id GL.GenBuffers(1, out vbo.ColorBufferID); // Bind current context to Array Buffer ID GL.BindBuffer(BufferTarget.ARRAY_BUFFER, vbo.ColorBufferID); // Send data to buffer GL.BufferData(BufferTarget.ARRAY_BUFFER, (IntPtr) (shape.Colors.Length * sizeof(int)), shape.Colors, BufferUsageHint.STATIC_DRAW); // Validate that the buffer is the correct size GL.GetBufferParameter(BufferTarget.ARRAY_BUFFER, BufferParameterName.BUFFER_SIZE, out bufferSize); if (shape.Colors.Length * sizeof(int) != bufferSize) throw new ApplicationException("Vertex array not uploaded correctly"); // Clear the buffer Binding GL.BindBuffer(BufferTarget.ARRAY_BUFFER, 0); } // Normal Array Buffer if (shape.Normals != null) { // Generate Array Buffer Id GL.GenBuffers(1, out vbo.NormalBufferID); // Bind current context to Array Buffer ID GL.BindBuffer(BufferTarget.ARRAY_BUFFER, vbo.NormalBufferID); // Send data to buffer GL.BufferData(BufferTarget.ARRAY_BUFFER, (IntPtr) (shape.Normals.Length * Vector3.SizeInBytes), shape.Normals, BufferUsageHint.STATIC_DRAW); // Validate that the buffer is the correct size GL.GetBufferParameter(BufferTarget.ARRAY_BUFFER, BufferParameterName.BUFFER_SIZE, out bufferSize); if (shape.Normals.Length * Vector3.SizeInBytes != bufferSize) throw new ApplicationException("Normal array not uploaded correctly"); // Clear the buffer Binding GL.BindBuffer(BufferTarget.ARRAY_BUFFER, 0); } // TexCoord Array Buffer if (shape.Texcoords != null) { // Generate Array Buffer Id GL.GenBuffers(1, out vbo.TexCoordBufferID); // Bind current context to Array Buffer ID GL.BindBuffer(BufferTarget.ARRAY_BUFFER, vbo.TexCoordBufferID); // Send data to buffer GL.BufferData(BufferTarget.ARRAY_BUFFER, (IntPtr) (shape.Texcoords.Length * Vector2.SizeInBytes), shape.Texcoords, BufferUsageHint.STATIC_DRAW); // Validate that the buffer is the correct size GL.GetBufferParameter(BufferTarget.ARRAY_BUFFER, BufferParameterName.BUFFER_SIZE, out bufferSize); if (shape.Texcoords.Length * Vector2.SizeInBytes != bufferSize) throw new ApplicationException("TexCoord array not uploaded correctly"); // Clear the buffer Binding GL.BindBuffer(BufferTarget.ARRAY_BUFFER, 0); } // Vertex Array Buffer { // Generate Array Buffer Id GL.GenBuffers(1, out vbo.VertexBufferID); // Bind current context to Array Buffer ID GL.BindBuffer(BufferTarget.ARRAY_BUFFER, vbo.VertexBufferID); // Send data to buffer GL.BufferData(BufferTarget.ARRAY_BUFFER, (IntPtr) (shape.Vertices.Length * Vector3.SizeInBytes), shape.Vertices, BufferUsageHint.STATIC_DRAW); // Validate that the buffer is the correct size GL.GetBufferParameter(BufferTarget.ARRAY_BUFFER, BufferParameterName.BUFFER_SIZE, out bufferSize); if (shape.Vertices.Length * Vector3.SizeInBytes != bufferSize) throw new ApplicationException("Vertex array not uploaded correctly"); // Clear the buffer Binding GL.BindBuffer(BufferTarget.ARRAY_BUFFER, 0); } // Element Array Buffer { // Generate Array Buffer Id GL.GenBuffers(1, out vbo.ElementBufferID); // Bind current context to Array Buffer ID GL.BindBuffer(BufferTarget.ELEMENT_ARRAY_BUFFER, vbo.ElementBufferID); // Send data to buffer GL.BufferData(BufferTarget.ELEMENT_ARRAY_BUFFER, (IntPtr) (shape.Indices.Length * sizeof(int)), shape.Indices, BufferUsageHint.STATIC_DRAW); // Validate that the buffer is the correct size GL.GetBufferParameter(BufferTarget.ELEMENT_ARRAY_BUFFER, BufferParameterName.BUFFER_SIZE, out bufferSize); if (shape.Indices.Length * sizeof(int) != bufferSize) throw new ApplicationException("Element array not uploaded correctly"); // Clear the buffer Binding GL.BindBuffer(BufferTarget.ELEMENT_ARRAY_BUFFER, 0); } // Store the number of elements for the DrawElements call vbo.NumElements = shape.Indices.Length; }